summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout')
-rw-r--r--gfx/angle/checkout/LICENSE32
-rw-r--r--gfx/angle/checkout/include/EGL/egl.h342
-rw-r--r--gfx/angle/checkout/include/EGL/eglext.h1486
-rw-r--r--gfx/angle/checkout/include/EGL/eglext_angle.h412
-rw-r--r--gfx/angle/checkout/include/EGL/eglplatform.h175
-rw-r--r--gfx/angle/checkout/include/GLES/gl.h743
-rw-r--r--gfx/angle/checkout/include/GLES/glext.h962
-rw-r--r--gfx/angle/checkout/include/GLES/glplatform.h38
-rw-r--r--gfx/angle/checkout/include/GLES2/gl2.h656
-rw-r--r--gfx/angle/checkout/include/GLES2/gl2ext.h3949
-rw-r--r--gfx/angle/checkout/include/GLES2/gl2ext_angle.h667
-rw-r--r--gfx/angle/checkout/include/GLES2/gl2platform.h27
-rw-r--r--gfx/angle/checkout/include/GLES3/gl3.h1192
-rw-r--r--gfx/angle/checkout/include/GLES3/gl31.h1507
-rw-r--r--gfx/angle/checkout/include/GLES3/gl32.h1808
-rw-r--r--gfx/angle/checkout/include/GLES3/gl3platform.h27
-rw-r--r--gfx/angle/checkout/include/GLSLANG/ShaderLang.h1001
-rw-r--r--gfx/angle/checkout/include/GLSLANG/ShaderVars.h331
-rw-r--r--gfx/angle/checkout/include/GLX/glxext.h954
-rw-r--r--gfx/angle/checkout/include/KHR/khrplatform.h290
-rw-r--r--gfx/angle/checkout/include/WGL/wgl.h946
-rw-r--r--gfx/angle/checkout/include/angle_gl.h27
-rw-r--r--gfx/angle/checkout/include/export.h40
-rw-r--r--gfx/angle/checkout/include/platform/Feature.h196
-rw-r--r--gfx/angle/checkout/include/platform/FeaturesD3D_autogen.h198
-rw-r--r--gfx/angle/checkout/include/platform/FeaturesGL_autogen.h501
-rw-r--r--gfx/angle/checkout/include/platform/FeaturesMtl_autogen.h242
-rw-r--r--gfx/angle/checkout/include/platform/FeaturesVk_autogen.h786
-rw-r--r--gfx/angle/checkout/include/platform/FrontendFeatures_autogen.h115
-rw-r--r--gfx/angle/checkout/include/platform/PlatformMethods.h334
-rw-r--r--gfx/angle/checkout/include/vulkan/vulkan_fuchsia_ext.h31
-rw-r--r--gfx/angle/checkout/out/gen/angle/angle_commit.h5
-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
-rw-r--r--gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_icd.h245
-rw-r--r--gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_layer.h210
-rw-r--r--gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_platform.h84
-rw-r--r--gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_sdk_platform.h69
-rw-r--r--gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan.h91
-rw-r--r--gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan.hpp15303
-rw-r--r--gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan_core.h16027
-rw-r--r--gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan_screen.h54
-rw-r--r--gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.cc205
-rw-r--r--gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.h63
1139 files changed, 555321 insertions, 0 deletions
diff --git a/gfx/angle/checkout/LICENSE b/gfx/angle/checkout/LICENSE
new file mode 100644
index 0000000000..0f65fd60fd
--- /dev/null
+++ b/gfx/angle/checkout/LICENSE
@@ -0,0 +1,32 @@
+// Copyright 2018 The ANGLE Project Authors.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of TransGaming Inc., Google Inc., 3DLabs Inc.
+// Ltd., nor the names of their contributors may be used to endorse
+// or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT 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.
diff --git a/gfx/angle/checkout/include/EGL/egl.h b/gfx/angle/checkout/include/EGL/egl.h
new file mode 100644
index 0000000000..97d0878cc7
--- /dev/null
+++ b/gfx/angle/checkout/include/EGL/egl.h
@@ -0,0 +1,342 @@
+#ifndef __egl_h_
+#define __egl_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright 2013-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: Apache-2.0
+**
+** This header is generated from the Khronos EGL XML API Registry.
+** The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** http://www.khronos.org/registry/egl
+**
+** Khronos $Git commit SHA1: 6fb1daea15 $ on $Git commit date: 2022-05-25 09:41:13 -0600 $
+*/
+
+#include <EGL/eglplatform.h>
+
+#ifndef EGL_EGL_PROTOTYPES
+#define EGL_EGL_PROTOTYPES 1
+#endif
+
+/* Generated on date 20220525 */
+
+/* Generated C header for:
+ * API: egl
+ * Versions considered: .*
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef EGL_VERSION_1_0
+#define EGL_VERSION_1_0 1
+typedef unsigned int EGLBoolean;
+typedef void *EGLDisplay;
+#include <KHR/khrplatform.h>
+#include <EGL/eglplatform.h>
+typedef void *EGLConfig;
+typedef void *EGLSurface;
+typedef void *EGLContext;
+typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+#define EGL_ALPHA_SIZE 0x3021
+#define EGL_BAD_ACCESS 0x3002
+#define EGL_BAD_ALLOC 0x3003
+#define EGL_BAD_ATTRIBUTE 0x3004
+#define EGL_BAD_CONFIG 0x3005
+#define EGL_BAD_CONTEXT 0x3006
+#define EGL_BAD_CURRENT_SURFACE 0x3007
+#define EGL_BAD_DISPLAY 0x3008
+#define EGL_BAD_MATCH 0x3009
+#define EGL_BAD_NATIVE_PIXMAP 0x300A
+#define EGL_BAD_NATIVE_WINDOW 0x300B
+#define EGL_BAD_PARAMETER 0x300C
+#define EGL_BAD_SURFACE 0x300D
+#define EGL_BLUE_SIZE 0x3022
+#define EGL_BUFFER_SIZE 0x3020
+#define EGL_CONFIG_CAVEAT 0x3027
+#define EGL_CONFIG_ID 0x3028
+#define EGL_CORE_NATIVE_ENGINE 0x305B
+#define EGL_DEPTH_SIZE 0x3025
+#define EGL_DONT_CARE EGL_CAST(EGLint,-1)
+#define EGL_DRAW 0x3059
+#define EGL_EXTENSIONS 0x3055
+#define EGL_FALSE 0
+#define EGL_GREEN_SIZE 0x3023
+#define EGL_HEIGHT 0x3056
+#define EGL_LARGEST_PBUFFER 0x3058
+#define EGL_LEVEL 0x3029
+#define EGL_MAX_PBUFFER_HEIGHT 0x302A
+#define EGL_MAX_PBUFFER_PIXELS 0x302B
+#define EGL_MAX_PBUFFER_WIDTH 0x302C
+#define EGL_NATIVE_RENDERABLE 0x302D
+#define EGL_NATIVE_VISUAL_ID 0x302E
+#define EGL_NATIVE_VISUAL_TYPE 0x302F
+#define EGL_NONE 0x3038
+#define EGL_NON_CONFORMANT_CONFIG 0x3051
+#define EGL_NOT_INITIALIZED 0x3001
+#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0)
+#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0)
+#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0)
+#define EGL_PBUFFER_BIT 0x0001
+#define EGL_PIXMAP_BIT 0x0002
+#define EGL_READ 0x305A
+#define EGL_RED_SIZE 0x3024
+#define EGL_SAMPLES 0x3031
+#define EGL_SAMPLE_BUFFERS 0x3032
+#define EGL_SLOW_CONFIG 0x3050
+#define EGL_STENCIL_SIZE 0x3026
+#define EGL_SUCCESS 0x3000
+#define EGL_SURFACE_TYPE 0x3033
+#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
+#define EGL_TRANSPARENT_RED_VALUE 0x3037
+#define EGL_TRANSPARENT_RGB 0x3052
+#define EGL_TRANSPARENT_TYPE 0x3034
+#define EGL_TRUE 1
+#define EGL_VENDOR 0x3053
+#define EGL_VERSION 0x3054
+#define EGL_WIDTH 0x3057
+#define EGL_WINDOW_BIT 0x0004
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+typedef EGLContext (EGLAPIENTRYP PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETCURRENTDISPLAYPROC) (void);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw);
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id);
+typedef EGLint (EGLAPIENTRYP PFNEGLGETERRORPROC) (void);
+typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP PFNEGLGETPROCADDRESSPROC) (const char *procname);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint *major, EGLint *minor);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLTERMINATEPROC) (EGLDisplay dpy);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITGLPROC) (void);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITNATIVEPROC) (EGLint engine);
+#if EGL_EGL_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void);
+EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id);
+EGLAPI EGLint EGLAPIENTRY eglGetError (void);
+EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname);
+EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);
+EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine);
+#endif
+#endif /* EGL_VERSION_1_0 */
+
+#ifndef EGL_VERSION_1_1
+#define EGL_VERSION_1_1 1
+#define EGL_BACK_BUFFER 0x3084
+#define EGL_BIND_TO_TEXTURE_RGB 0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
+#define EGL_CONTEXT_LOST 0x300E
+#define EGL_MIN_SWAP_INTERVAL 0x303B
+#define EGL_MAX_SWAP_INTERVAL 0x303C
+#define EGL_MIPMAP_TEXTURE 0x3082
+#define EGL_MIPMAP_LEVEL 0x3083
+#define EGL_NO_TEXTURE 0x305C
+#define EGL_TEXTURE_2D 0x305F
+#define EGL_TEXTURE_FORMAT 0x3080
+#define EGL_TEXTURE_RGB 0x305D
+#define EGL_TEXTURE_RGBA 0x305E
+#define EGL_TEXTURE_TARGET 0x3081
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval);
+#if EGL_EGL_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval);
+#endif
+#endif /* EGL_VERSION_1_1 */
+
+#ifndef EGL_VERSION_1_2
+#define EGL_VERSION_1_2 1
+typedef unsigned int EGLenum;
+typedef void *EGLClientBuffer;
+#define EGL_ALPHA_FORMAT 0x3088
+#define EGL_ALPHA_FORMAT_NONPRE 0x308B
+#define EGL_ALPHA_FORMAT_PRE 0x308C
+#define EGL_ALPHA_MASK_SIZE 0x303E
+#define EGL_BUFFER_PRESERVED 0x3094
+#define EGL_BUFFER_DESTROYED 0x3095
+#define EGL_CLIENT_APIS 0x308D
+#define EGL_COLORSPACE 0x3087
+#define EGL_COLORSPACE_sRGB 0x3089
+#define EGL_COLORSPACE_LINEAR 0x308A
+#define EGL_COLOR_BUFFER_TYPE 0x303F
+#define EGL_CONTEXT_CLIENT_TYPE 0x3097
+#define EGL_DISPLAY_SCALING 10000
+#define EGL_HORIZONTAL_RESOLUTION 0x3090
+#define EGL_LUMINANCE_BUFFER 0x308F
+#define EGL_LUMINANCE_SIZE 0x303D
+#define EGL_OPENGL_ES_BIT 0x0001
+#define EGL_OPENVG_BIT 0x0002
+#define EGL_OPENGL_ES_API 0x30A0
+#define EGL_OPENVG_API 0x30A1
+#define EGL_OPENVG_IMAGE 0x3096
+#define EGL_PIXEL_ASPECT_RATIO 0x3092
+#define EGL_RENDERABLE_TYPE 0x3040
+#define EGL_RENDER_BUFFER 0x3086
+#define EGL_RGB_BUFFER 0x308E
+#define EGL_SINGLE_BUFFER 0x3085
+#define EGL_SWAP_BEHAVIOR 0x3093
+#define EGL_UNKNOWN EGL_CAST(EGLint,-1)
+#define EGL_VERTICAL_RESOLUTION 0x3091
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDAPIPROC) (EGLenum api);
+typedef EGLenum (EGLAPIENTRYP PFNEGLQUERYAPIPROC) (void);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETHREADPROC) (void);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITCLIENTPROC) (void);
+#if EGL_EGL_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api);
+EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void);
+#endif
+#endif /* EGL_VERSION_1_2 */
+
+#ifndef EGL_VERSION_1_3
+#define EGL_VERSION_1_3 1
+#define EGL_CONFORMANT 0x3042
+#define EGL_CONTEXT_CLIENT_VERSION 0x3098
+#define EGL_MATCH_NATIVE_PIXMAP 0x3041
+#define EGL_OPENGL_ES2_BIT 0x0004
+#define EGL_VG_ALPHA_FORMAT 0x3088
+#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B
+#define EGL_VG_ALPHA_FORMAT_PRE 0x308C
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040
+#define EGL_VG_COLORSPACE 0x3087
+#define EGL_VG_COLORSPACE_sRGB 0x3089
+#define EGL_VG_COLORSPACE_LINEAR 0x308A
+#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020
+#endif /* EGL_VERSION_1_3 */
+
+#ifndef EGL_VERSION_1_4
+#define EGL_VERSION_1_4 1
+#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0)
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
+#define EGL_MULTISAMPLE_RESOLVE 0x3099
+#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A
+#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B
+#define EGL_OPENGL_API 0x30A2
+#define EGL_OPENGL_BIT 0x0008
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
+typedef EGLContext (EGLAPIENTRYP PFNEGLGETCURRENTCONTEXTPROC) (void);
+#if EGL_EGL_PROTOTYPES
+EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
+#endif
+#endif /* EGL_VERSION_1_4 */
+
+#ifndef EGL_VERSION_1_5
+#define EGL_VERSION_1_5 1
+typedef void *EGLSync;
+typedef intptr_t EGLAttrib;
+typedef khronos_utime_nanoseconds_t EGLTime;
+typedef void *EGLImage;
+#define EGL_CONTEXT_MAJOR_VERSION 0x3098
+#define EGL_CONTEXT_MINOR_VERSION 0x30FB
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
+#define EGL_NO_RESET_NOTIFICATION 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2
+#define EGL_OPENGL_ES3_BIT 0x00000040
+#define EGL_CL_EVENT_HANDLE 0x309C
+#define EGL_SYNC_CL_EVENT 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
+#define EGL_SYNC_TYPE 0x30F7
+#define EGL_SYNC_STATUS 0x30F1
+#define EGL_SYNC_CONDITION 0x30F8
+#define EGL_SIGNALED 0x30F2
+#define EGL_UNSIGNALED 0x30F3
+#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
+#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull
+#define EGL_TIMEOUT_EXPIRED 0x30F5
+#define EGL_CONDITION_SATISFIED 0x30F6
+#define EGL_NO_SYNC EGL_CAST(EGLSync,0)
+#define EGL_SYNC_FENCE 0x30F9
+#define EGL_GL_COLORSPACE 0x309D
+#define EGL_GL_COLORSPACE_SRGB 0x3089
+#define EGL_GL_COLORSPACE_LINEAR 0x308A
+#define EGL_GL_RENDERBUFFER 0x30B9
+#define EGL_GL_TEXTURE_2D 0x30B1
+#define EGL_GL_TEXTURE_LEVEL 0x30BC
+#define EGL_GL_TEXTURE_3D 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET 0x30BD
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
+#define EGL_IMAGE_PRESERVED 0x30D2
+#define EGL_NO_IMAGE EGL_CAST(EGLImage,0)
+typedef EGLSync (EGLAPIENTRYP PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
+typedef EGLImage (EGLAPIENTRYP PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image);
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags);
+#if EGL_EGL_PROTOTYPES
+EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
+EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags);
+#endif
+#endif /* EGL_VERSION_1_5 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/include/EGL/eglext.h b/gfx/angle/checkout/include/EGL/eglext.h
new file mode 100644
index 0000000000..d226b7f6da
--- /dev/null
+++ b/gfx/angle/checkout/include/EGL/eglext.h
@@ -0,0 +1,1486 @@
+#ifndef __eglext_h_
+#define __eglext_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright 2013-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: Apache-2.0
+**
+** This header is generated from the Khronos EGL XML API Registry.
+** The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** http://www.khronos.org/registry/egl
+**
+** Khronos $Git commit SHA1: 6fb1daea15 $ on $Git commit date: 2022-05-25 09:41:13 -0600 $
+*/
+
+#include <EGL/eglplatform.h>
+
+#define EGL_EGLEXT_VERSION 20220525
+
+/* Generated C header for:
+ * API: egl
+ * Versions considered: .*
+ * Versions emitted: _nomatch_^
+ * Default extensions included: egl
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef EGL_KHR_cl_event
+#define EGL_KHR_cl_event 1
+#define EGL_CL_EVENT_HANDLE_KHR 0x309C
+#define EGL_SYNC_CL_EVENT_KHR 0x30FE
+#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF
+#endif /* EGL_KHR_cl_event */
+
+#ifndef EGL_KHR_cl_event2
+#define EGL_KHR_cl_event2 1
+typedef void *EGLSyncKHR;
+typedef intptr_t EGLAttribKHR;
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
+#endif
+#endif /* EGL_KHR_cl_event2 */
+
+#ifndef EGL_KHR_client_get_all_proc_addresses
+#define EGL_KHR_client_get_all_proc_addresses 1
+#endif /* EGL_KHR_client_get_all_proc_addresses */
+
+#ifndef EGL_KHR_config_attribs
+#define EGL_KHR_config_attribs 1
+#define EGL_CONFORMANT_KHR 0x3042
+#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040
+#endif /* EGL_KHR_config_attribs */
+
+#ifndef EGL_KHR_context_flush_control
+#define EGL_KHR_context_flush_control 1
+#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
+#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
+#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
+#endif /* EGL_KHR_context_flush_control */
+
+#ifndef EGL_KHR_create_context
+#define EGL_KHR_create_context 1
+#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
+#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
+#define EGL_CONTEXT_FLAGS_KHR 0x30FC
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
+#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
+#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
+#endif /* EGL_KHR_create_context */
+
+#ifndef EGL_KHR_create_context_no_error
+#define EGL_KHR_create_context_no_error 1
+#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3
+#endif /* EGL_KHR_create_context_no_error */
+
+#ifndef EGL_KHR_debug
+#define EGL_KHR_debug 1
+typedef void *EGLLabelKHR;
+typedef void *EGLObjectKHR;
+typedef void (EGLAPIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message);
+#define EGL_OBJECT_THREAD_KHR 0x33B0
+#define EGL_OBJECT_DISPLAY_KHR 0x33B1
+#define EGL_OBJECT_CONTEXT_KHR 0x33B2
+#define EGL_OBJECT_SURFACE_KHR 0x33B3
+#define EGL_OBJECT_IMAGE_KHR 0x33B4
+#define EGL_OBJECT_SYNC_KHR 0x33B5
+#define EGL_OBJECT_STREAM_KHR 0x33B6
+#define EGL_DEBUG_MSG_CRITICAL_KHR 0x33B9
+#define EGL_DEBUG_MSG_ERROR_KHR 0x33BA
+#define EGL_DEBUG_MSG_WARN_KHR 0x33BB
+#define EGL_DEBUG_MSG_INFO_KHR 0x33BC
+#define EGL_DEBUG_CALLBACK_KHR 0x33B8
+typedef EGLint (EGLAPIENTRYP PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib *value);
+typedef EGLint (EGLAPIENTRYP PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglDebugMessageControlKHR (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDebugKHR (EGLint attribute, EGLAttrib *value);
+EGLAPI EGLint EGLAPIENTRY eglLabelObjectKHR (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label);
+#endif
+#endif /* EGL_KHR_debug */
+
+#ifndef EGL_KHR_display_reference
+#define EGL_KHR_display_reference 1
+#define EGL_TRACK_REFERENCES_KHR 0x3352
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBKHRPROC) (EGLDisplay dpy, EGLint name, EGLAttrib *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribKHR (EGLDisplay dpy, EGLint name, EGLAttrib *value);
+#endif
+#endif /* EGL_KHR_display_reference */
+
+#ifndef EGL_KHR_fence_sync
+#define EGL_KHR_fence_sync 1
+typedef khronos_utime_nanoseconds_t EGLTimeKHR;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
+#define EGL_SYNC_CONDITION_KHR 0x30F8
+#define EGL_SYNC_FENCE_KHR 0x30F9
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_fence_sync */
+
+#ifndef EGL_KHR_get_all_proc_addresses
+#define EGL_KHR_get_all_proc_addresses 1
+#endif /* EGL_KHR_get_all_proc_addresses */
+
+#ifndef EGL_KHR_gl_colorspace
+#define EGL_KHR_gl_colorspace 1
+#define EGL_GL_COLORSPACE_KHR 0x309D
+#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
+#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A
+#endif /* EGL_KHR_gl_colorspace */
+
+#ifndef EGL_KHR_gl_renderbuffer_image
+#define EGL_KHR_gl_renderbuffer_image 1
+#define EGL_GL_RENDERBUFFER_KHR 0x30B9
+#endif /* EGL_KHR_gl_renderbuffer_image */
+
+#ifndef EGL_KHR_gl_texture_2D_image
+#define EGL_KHR_gl_texture_2D_image 1
+#define EGL_GL_TEXTURE_2D_KHR 0x30B1
+#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC
+#endif /* EGL_KHR_gl_texture_2D_image */
+
+#ifndef EGL_KHR_gl_texture_3D_image
+#define EGL_KHR_gl_texture_3D_image 1
+#define EGL_GL_TEXTURE_3D_KHR 0x30B2
+#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD
+#endif /* EGL_KHR_gl_texture_3D_image */
+
+#ifndef EGL_KHR_gl_texture_cubemap_image
+#define EGL_KHR_gl_texture_cubemap_image 1
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8
+#endif /* EGL_KHR_gl_texture_cubemap_image */
+
+#ifndef EGL_KHR_image
+#define EGL_KHR_image 1
+typedef void *EGLImageKHR;
+#define EGL_NATIVE_PIXMAP_KHR 0x30B0
+#define EGL_NO_IMAGE_KHR EGL_CAST(EGLImageKHR,0)
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
+#endif
+#endif /* EGL_KHR_image */
+
+#ifndef EGL_KHR_image_base
+#define EGL_KHR_image_base 1
+#define EGL_IMAGE_PRESERVED_KHR 0x30D2
+#endif /* EGL_KHR_image_base */
+
+#ifndef EGL_KHR_image_pixmap
+#define EGL_KHR_image_pixmap 1
+#endif /* EGL_KHR_image_pixmap */
+
+#ifndef EGL_KHR_lock_surface
+#define EGL_KHR_lock_surface 1
+#define EGL_READ_SURFACE_BIT_KHR 0x0001
+#define EGL_WRITE_SURFACE_BIT_KHR 0x0002
+#define EGL_LOCK_SURFACE_BIT_KHR 0x0080
+#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100
+#define EGL_MATCH_FORMAT_KHR 0x3043
+#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0
+#define EGL_FORMAT_RGB_565_KHR 0x30C1
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2
+#define EGL_FORMAT_RGBA_8888_KHR 0x30C3
+#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
+#define EGL_LOCK_USAGE_HINT_KHR 0x30C5
+#define EGL_BITMAP_POINTER_KHR 0x30C6
+#define EGL_BITMAP_PITCH_KHR 0x30C7
+#define EGL_BITMAP_ORIGIN_KHR 0x30C8
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
+#define EGL_LOWER_LEFT_KHR 0x30CE
+#define EGL_UPPER_LEFT_KHR 0x30CF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface);
+#endif
+#endif /* EGL_KHR_lock_surface */
+
+#ifndef EGL_KHR_lock_surface2
+#define EGL_KHR_lock_surface2 1
+#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
+#endif /* EGL_KHR_lock_surface2 */
+
+#ifndef EGL_KHR_lock_surface3
+#define EGL_KHR_lock_surface3 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
+#endif
+#endif /* EGL_KHR_lock_surface3 */
+
+#ifndef EGL_KHR_mutable_render_buffer
+#define EGL_KHR_mutable_render_buffer 1
+#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000
+#endif /* EGL_KHR_mutable_render_buffer */
+
+#ifndef EGL_KHR_no_config_context
+#define EGL_KHR_no_config_context 1
+#define EGL_NO_CONFIG_KHR EGL_CAST(EGLConfig,0)
+#endif /* EGL_KHR_no_config_context */
+
+#ifndef EGL_KHR_partial_update
+#define EGL_KHR_partial_update 1
+#define EGL_BUFFER_AGE_KHR 0x313D
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_KHR_partial_update */
+
+#ifndef EGL_KHR_platform_android
+#define EGL_KHR_platform_android 1
+#define EGL_PLATFORM_ANDROID_KHR 0x3141
+#endif /* EGL_KHR_platform_android */
+
+#ifndef EGL_KHR_platform_gbm
+#define EGL_KHR_platform_gbm 1
+#define EGL_PLATFORM_GBM_KHR 0x31D7
+#endif /* EGL_KHR_platform_gbm */
+
+#ifndef EGL_KHR_platform_wayland
+#define EGL_KHR_platform_wayland 1
+#define EGL_PLATFORM_WAYLAND_KHR 0x31D8
+#endif /* EGL_KHR_platform_wayland */
+
+#ifndef EGL_KHR_platform_x11
+#define EGL_KHR_platform_x11 1
+#define EGL_PLATFORM_X11_KHR 0x31D5
+#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6
+#endif /* EGL_KHR_platform_x11 */
+
+#ifndef EGL_KHR_reusable_sync
+#define EGL_KHR_reusable_sync 1
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_STATUS_KHR 0x30F1
+#define EGL_SIGNALED_KHR 0x30F2
+#define EGL_UNSIGNALED_KHR 0x30F3
+#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
+#define EGL_CONDITION_SATISFIED_KHR 0x30F6
+#define EGL_SYNC_TYPE_KHR 0x30F7
+#define EGL_SYNC_REUSABLE_KHR 0x30FA
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001
+#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
+#define EGL_NO_SYNC_KHR EGL_CAST(EGLSyncKHR,0)
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_reusable_sync */
+
+#ifndef EGL_KHR_stream
+#define EGL_KHR_stream 1
+typedef void *EGLStreamKHR;
+typedef khronos_uint64_t EGLuint64KHR;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_NO_STREAM_KHR EGL_CAST(EGLStreamKHR,0)
+#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210
+#define EGL_PRODUCER_FRAME_KHR 0x3212
+#define EGL_CONSUMER_FRAME_KHR 0x3213
+#define EGL_STREAM_STATE_KHR 0x3214
+#define EGL_STREAM_STATE_CREATED_KHR 0x3215
+#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
+#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
+#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
+#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
+#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
+#define EGL_BAD_STREAM_KHR 0x321B
+#define EGL_BAD_STATE_KHR 0x321C
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR (EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_stream */
+
+#ifndef EGL_KHR_stream_attrib
+#define EGL_KHR_stream_attrib 1
+#ifdef KHRONOS_SUPPORT_INT64
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMATTRIBKHRPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamAttribKHR (EGLDisplay dpy, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_stream_attrib */
+
+#ifndef EGL_KHR_stream_consumer_gltexture
+#define EGL_KHR_stream_consumer_gltexture 1
+#ifdef EGL_KHR_stream
+#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_consumer_gltexture */
+
+#ifndef EGL_KHR_stream_cross_process_fd
+#define EGL_KHR_stream_cross_process_fd 1
+typedef int EGLNativeFileDescriptorKHR;
+#ifdef EGL_KHR_stream
+#define EGL_NO_FILE_DESCRIPTOR_KHR EGL_CAST(EGLNativeFileDescriptorKHR,-1)
+typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_cross_process_fd */
+
+#ifndef EGL_KHR_stream_fifo
+#define EGL_KHR_stream_fifo 1
+#ifdef EGL_KHR_stream
+#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC
+#define EGL_STREAM_TIME_NOW_KHR 0x31FD
+#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE
+#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_fifo */
+
+#ifndef EGL_KHR_stream_producer_aldatalocator
+#define EGL_KHR_stream_producer_aldatalocator 1
+#ifdef EGL_KHR_stream
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_producer_aldatalocator */
+
+#ifndef EGL_KHR_stream_producer_eglsurface
+#define EGL_KHR_stream_producer_eglsurface 1
+#ifdef EGL_KHR_stream
+#define EGL_STREAM_BIT_KHR 0x0800
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#endif
+#endif /* EGL_KHR_stream */
+#endif /* EGL_KHR_stream_producer_eglsurface */
+
+#ifndef EGL_KHR_surfaceless_context
+#define EGL_KHR_surfaceless_context 1
+#endif /* EGL_KHR_surfaceless_context */
+
+#ifndef EGL_KHR_swap_buffers_with_damage
+#define EGL_KHR_swap_buffers_with_damage 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_KHR_swap_buffers_with_damage */
+
+#ifndef EGL_KHR_vg_parent_image
+#define EGL_KHR_vg_parent_image 1
+#define EGL_VG_PARENT_IMAGE_KHR 0x30BA
+#endif /* EGL_KHR_vg_parent_image */
+
+#ifndef EGL_KHR_wait_sync
+#define EGL_KHR_wait_sync 1
+typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#endif
+#endif /* EGL_KHR_wait_sync */
+
+#ifndef EGL_ANDROID_GLES_layers
+#define EGL_ANDROID_GLES_layers 1
+#endif /* EGL_ANDROID_GLES_layers */
+
+#ifndef EGL_ANDROID_blob_cache
+#define EGL_ANDROID_blob_cache 1
+typedef khronos_ssize_t EGLsizeiANDROID;
+typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
+typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
+typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#endif
+#endif /* EGL_ANDROID_blob_cache */
+
+#ifndef EGL_ANDROID_create_native_client_buffer
+#define EGL_ANDROID_create_native_client_buffer 1
+#define EGL_NATIVE_BUFFER_USAGE_ANDROID 0x3143
+#define EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID 0x00000001
+#define EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID 0x00000002
+#define EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID 0x00000004
+typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC) (const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLClientBuffer EGLAPIENTRY eglCreateNativeClientBufferANDROID (const EGLint *attrib_list);
+#endif
+#endif /* EGL_ANDROID_create_native_client_buffer */
+
+#ifndef EGL_ANDROID_framebuffer_target
+#define EGL_ANDROID_framebuffer_target 1
+#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147
+#endif /* EGL_ANDROID_framebuffer_target */
+
+#ifndef EGL_ANDROID_front_buffer_auto_refresh
+#define EGL_ANDROID_front_buffer_auto_refresh 1
+#define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C
+#endif /* EGL_ANDROID_front_buffer_auto_refresh */
+
+#ifndef EGL_ANDROID_get_frame_timestamps
+#define EGL_ANDROID_get_frame_timestamps 1
+typedef khronos_stime_nanoseconds_t EGLnsecsANDROID;
+#define EGL_TIMESTAMP_PENDING_ANDROID EGL_CAST(EGLnsecsANDROID,-2)
+#define EGL_TIMESTAMP_INVALID_ANDROID EGL_CAST(EGLnsecsANDROID,-1)
+#define EGL_TIMESTAMPS_ANDROID 0x3430
+#define EGL_COMPOSITE_DEADLINE_ANDROID 0x3431
+#define EGL_COMPOSITE_INTERVAL_ANDROID 0x3432
+#define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3433
+#define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3434
+#define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3435
+#define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3436
+#define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3437
+#define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3438
+#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3439
+#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x343A
+#define EGL_DEQUEUE_READY_TIME_ANDROID 0x343B
+#define EGL_READS_DONE_TIME_ANDROID 0x343C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETNEXTFRAMEIDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingANDROID (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetNextFrameIdANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampsANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
+#endif
+#endif /* EGL_ANDROID_get_frame_timestamps */
+
+#ifndef EGL_ANDROID_get_native_client_buffer
+#define EGL_ANDROID_get_native_client_buffer 1
+struct AHardwareBuffer;
+typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC) (const struct AHardwareBuffer *buffer);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLClientBuffer EGLAPIENTRY eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer);
+#endif
+#endif /* EGL_ANDROID_get_native_client_buffer */
+
+#ifndef EGL_ANDROID_image_native_buffer
+#define EGL_ANDROID_image_native_buffer 1
+#define EGL_NATIVE_BUFFER_ANDROID 0x3140
+#endif /* EGL_ANDROID_image_native_buffer */
+
+#ifndef EGL_ANDROID_native_fence_sync
+#define EGL_ANDROID_native_fence_sync 1
+#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144
+#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145
+#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146
+#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1
+typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync);
+#endif
+#endif /* EGL_ANDROID_native_fence_sync */
+
+#ifndef EGL_ANDROID_presentation_time
+#define EGL_ANDROID_presentation_time 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time);
+#endif
+#endif /* EGL_ANDROID_presentation_time */
+
+#ifndef EGL_ANDROID_recordable
+#define EGL_ANDROID_recordable 1
+#define EGL_RECORDABLE_ANDROID 0x3142
+#endif /* EGL_ANDROID_recordable */
+
+#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
+#define EGL_ANGLE_d3d_share_handle_client_buffer 1
+#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
+#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
+
+#ifndef EGL_ANGLE_device_d3d
+#define EGL_ANGLE_device_d3d 1
+#define EGL_D3D9_DEVICE_ANGLE 0x33A0
+#define EGL_D3D11_DEVICE_ANGLE 0x33A1
+#endif /* EGL_ANGLE_device_d3d */
+
+#ifndef EGL_ANGLE_query_surface_pointer
+#define EGL_ANGLE_query_surface_pointer 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+#endif
+#endif /* EGL_ANGLE_query_surface_pointer */
+
+#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
+#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
+#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
+
+#ifndef EGL_ANGLE_sync_control_rate
+#define EGL_ANGLE_sync_control_rate 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMSCRATEANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglGetMscRateANGLE (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator);
+#endif
+#endif /* EGL_ANGLE_sync_control_rate */
+
+#ifndef EGL_ANGLE_window_fixed_size
+#define EGL_ANGLE_window_fixed_size 1
+#define EGL_FIXED_SIZE_ANGLE 0x3201
+#endif /* EGL_ANGLE_window_fixed_size */
+
+#ifndef EGL_ARM_image_format
+#define EGL_ARM_image_format 1
+#define EGL_COLOR_COMPONENT_TYPE_UNSIGNED_INTEGER_ARM 0x3287
+#define EGL_COLOR_COMPONENT_TYPE_INTEGER_ARM 0x3288
+#endif /* EGL_ARM_image_format */
+
+#ifndef EGL_ARM_implicit_external_sync
+#define EGL_ARM_implicit_external_sync 1
+#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A
+#endif /* EGL_ARM_implicit_external_sync */
+
+#ifndef EGL_ARM_pixmap_multisample_discard
+#define EGL_ARM_pixmap_multisample_discard 1
+#define EGL_DISCARD_SAMPLES_ARM 0x3286
+#endif /* EGL_ARM_pixmap_multisample_discard */
+
+#ifndef EGL_EXT_bind_to_front
+#define EGL_EXT_bind_to_front 1
+#define EGL_FRONT_BUFFER_EXT 0x3464
+#endif /* EGL_EXT_bind_to_front */
+
+#ifndef EGL_EXT_buffer_age
+#define EGL_EXT_buffer_age 1
+#define EGL_BUFFER_AGE_EXT 0x313D
+#endif /* EGL_EXT_buffer_age */
+
+#ifndef EGL_EXT_client_extensions
+#define EGL_EXT_client_extensions 1
+#endif /* EGL_EXT_client_extensions */
+
+#ifndef EGL_EXT_client_sync
+#define EGL_EXT_client_sync 1
+#define EGL_SYNC_CLIENT_EXT 0x3364
+#define EGL_SYNC_CLIENT_SIGNAL_EXT 0x3365
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCLIENTSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglClientSignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
+#endif
+#endif /* EGL_EXT_client_sync */
+
+#ifndef EGL_EXT_compositor
+#define EGL_EXT_compositor 1
+#define EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT 0x3460
+#define EGL_EXTERNAL_REF_ID_EXT 0x3461
+#define EGL_COMPOSITOR_DROP_NEWEST_FRAME_EXT 0x3462
+#define EGL_COMPOSITOR_KEEP_NEWEST_FRAME_EXT 0x3463
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTLISTEXTPROC) (const EGLint *external_ref_ids, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTATTRIBUTESEXTPROC) (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWLISTEXTPROC) (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWATTRIBUTESEXTPROC) (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORBINDTEXWINDOWEXTPROC) (EGLint external_win_id);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETSIZEEXTPROC) (EGLint external_win_id, EGLint width, EGLint height);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSWAPPOLICYEXTPROC) (EGLint external_win_id, EGLint policy);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextListEXT (const EGLint *external_ref_ids, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextAttributesEXT (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowListEXT (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowAttributesEXT (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorBindTexWindowEXT (EGLint external_win_id);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetSizeEXT (EGLint external_win_id, EGLint width, EGLint height);
+EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSwapPolicyEXT (EGLint external_win_id, EGLint policy);
+#endif
+#endif /* EGL_EXT_compositor */
+
+#ifndef EGL_EXT_config_select_group
+#define EGL_EXT_config_select_group 1
+#define EGL_CONFIG_SELECT_GROUP_EXT 0x34C0
+#endif /* EGL_EXT_config_select_group */
+
+#ifndef EGL_EXT_create_context_robustness
+#define EGL_EXT_create_context_robustness 1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
+#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
+#endif /* EGL_EXT_create_context_robustness */
+
+#ifndef EGL_EXT_device_base
+#define EGL_EXT_device_base 1
+typedef void *EGLDeviceEXT;
+#define EGL_NO_DEVICE_EXT EGL_CAST(EGLDeviceEXT,0)
+#define EGL_BAD_DEVICE_EXT 0x322B
+#define EGL_DEVICE_EXT 0x322C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#endif
+#endif /* EGL_EXT_device_base */
+
+#ifndef EGL_EXT_device_drm
+#define EGL_EXT_device_drm 1
+#define EGL_DRM_DEVICE_FILE_EXT 0x3233
+#define EGL_DRM_MASTER_FD_EXT 0x333C
+#endif /* EGL_EXT_device_drm */
+
+#ifndef EGL_EXT_device_drm_render_node
+#define EGL_EXT_device_drm_render_node 1
+#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377
+#endif /* EGL_EXT_device_drm_render_node */
+
+#ifndef EGL_EXT_device_enumeration
+#define EGL_EXT_device_enumeration 1
+#endif /* EGL_EXT_device_enumeration */
+
+#ifndef EGL_EXT_device_openwf
+#define EGL_EXT_device_openwf 1
+#define EGL_OPENWF_DEVICE_ID_EXT 0x3237
+#define EGL_OPENWF_DEVICE_EXT 0x333D
+#endif /* EGL_EXT_device_openwf */
+
+#ifndef EGL_EXT_device_persistent_id
+#define EGL_EXT_device_persistent_id 1
+#define EGL_DEVICE_UUID_EXT 0x335C
+#define EGL_DRIVER_UUID_EXT 0x335D
+#define EGL_DRIVER_NAME_EXT 0x335E
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEBINARYEXTPROC) (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceBinaryEXT (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size);
+#endif
+#endif /* EGL_EXT_device_persistent_id */
+
+#ifndef EGL_EXT_device_query
+#define EGL_EXT_device_query 1
+#endif /* EGL_EXT_device_query */
+
+#ifndef EGL_EXT_device_query_name
+#define EGL_EXT_device_query_name 1
+#define EGL_RENDERER_EXT 0x335F
+#endif /* EGL_EXT_device_query_name */
+
+#ifndef EGL_EXT_explicit_device
+#define EGL_EXT_explicit_device 1
+#endif /* EGL_EXT_explicit_device */
+
+#ifndef EGL_EXT_gl_colorspace_bt2020_linear
+#define EGL_EXT_gl_colorspace_bt2020_linear 1
+#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F
+#endif /* EGL_EXT_gl_colorspace_bt2020_linear */
+
+#ifndef EGL_EXT_gl_colorspace_bt2020_pq
+#define EGL_EXT_gl_colorspace_bt2020_pq 1
+#define EGL_GL_COLORSPACE_BT2020_PQ_EXT 0x3340
+#endif /* EGL_EXT_gl_colorspace_bt2020_pq */
+
+#ifndef EGL_EXT_gl_colorspace_display_p3
+#define EGL_EXT_gl_colorspace_display_p3 1
+#define EGL_GL_COLORSPACE_DISPLAY_P3_EXT 0x3363
+#endif /* EGL_EXT_gl_colorspace_display_p3 */
+
+#ifndef EGL_EXT_gl_colorspace_display_p3_linear
+#define EGL_EXT_gl_colorspace_display_p3_linear 1
+#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362
+#endif /* EGL_EXT_gl_colorspace_display_p3_linear */
+
+#ifndef EGL_EXT_gl_colorspace_display_p3_passthrough
+#define EGL_EXT_gl_colorspace_display_p3_passthrough 1
+#define EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT 0x3490
+#endif /* EGL_EXT_gl_colorspace_display_p3_passthrough */
+
+#ifndef EGL_EXT_gl_colorspace_scrgb
+#define EGL_EXT_gl_colorspace_scrgb 1
+#define EGL_GL_COLORSPACE_SCRGB_EXT 0x3351
+#endif /* EGL_EXT_gl_colorspace_scrgb */
+
+#ifndef EGL_EXT_gl_colorspace_scrgb_linear
+#define EGL_EXT_gl_colorspace_scrgb_linear 1
+#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT 0x3350
+#endif /* EGL_EXT_gl_colorspace_scrgb_linear */
+
+#ifndef EGL_EXT_image_dma_buf_import
+#define EGL_EXT_image_dma_buf_import 1
+#define EGL_LINUX_DMA_BUF_EXT 0x3270
+#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
+#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
+#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
+#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
+#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275
+#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276
+#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277
+#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278
+#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279
+#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A
+#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B
+#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C
+#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D
+#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E
+#define EGL_ITU_REC601_EXT 0x327F
+#define EGL_ITU_REC709_EXT 0x3280
+#define EGL_ITU_REC2020_EXT 0x3281
+#define EGL_YUV_FULL_RANGE_EXT 0x3282
+#define EGL_YUV_NARROW_RANGE_EXT 0x3283
+#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284
+#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285
+#endif /* EGL_EXT_image_dma_buf_import */
+
+#ifndef EGL_EXT_image_dma_buf_import_modifiers
+#define EGL_EXT_image_dma_buf_import_modifiers 1
+#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440
+#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441
+#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442
+#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443
+#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444
+#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445
+#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446
+#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447
+#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448
+#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449
+#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufFormatsEXT (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufModifiersEXT (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers);
+#endif
+#endif /* EGL_EXT_image_dma_buf_import_modifiers */
+
+#ifndef EGL_EXT_image_gl_colorspace
+#define EGL_EXT_image_gl_colorspace 1
+#define EGL_GL_COLORSPACE_DEFAULT_EXT 0x314D
+#endif /* EGL_EXT_image_gl_colorspace */
+
+#ifndef EGL_EXT_image_implicit_sync_control
+#define EGL_EXT_image_implicit_sync_control 1
+#define EGL_IMPORT_SYNC_TYPE_EXT 0x3470
+#define EGL_IMPORT_IMPLICIT_SYNC_EXT 0x3471
+#define EGL_IMPORT_EXPLICIT_SYNC_EXT 0x3472
+#endif /* EGL_EXT_image_implicit_sync_control */
+
+#ifndef EGL_EXT_multiview_window
+#define EGL_EXT_multiview_window 1
+#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134
+#endif /* EGL_EXT_multiview_window */
+
+#ifndef EGL_EXT_output_base
+#define EGL_EXT_output_base 1
+typedef void *EGLOutputLayerEXT;
+typedef void *EGLOutputPortEXT;
+#define EGL_NO_OUTPUT_LAYER_EXT EGL_CAST(EGLOutputLayerEXT,0)
+#define EGL_NO_OUTPUT_PORT_EXT EGL_CAST(EGLOutputPortEXT,0)
+#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D
+#define EGL_BAD_OUTPUT_PORT_EXT 0x322E
+#define EGL_SWAP_INTERVAL_EXT 0x322F
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputLayersEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputPortsEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
+EGLAPI EGLBoolean EGLAPIENTRY eglOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryOutputLayerStringEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
+EGLAPI EGLBoolean EGLAPIENTRY eglOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
+EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
+#endif
+#endif /* EGL_EXT_output_base */
+
+#ifndef EGL_EXT_output_drm
+#define EGL_EXT_output_drm 1
+#define EGL_DRM_CRTC_EXT 0x3234
+#define EGL_DRM_PLANE_EXT 0x3235
+#define EGL_DRM_CONNECTOR_EXT 0x3236
+#endif /* EGL_EXT_output_drm */
+
+#ifndef EGL_EXT_output_openwf
+#define EGL_EXT_output_openwf 1
+#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238
+#define EGL_OPENWF_PORT_ID_EXT 0x3239
+#endif /* EGL_EXT_output_openwf */
+
+#ifndef EGL_EXT_pixel_format_float
+#define EGL_EXT_pixel_format_float 1
+#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339
+#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A
+#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT 0x333B
+#endif /* EGL_EXT_pixel_format_float */
+
+#ifndef EGL_EXT_platform_base
+#define EGL_EXT_platform_base 1
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
+#endif
+#endif /* EGL_EXT_platform_base */
+
+#ifndef EGL_EXT_platform_device
+#define EGL_EXT_platform_device 1
+#define EGL_PLATFORM_DEVICE_EXT 0x313F
+#endif /* EGL_EXT_platform_device */
+
+#ifndef EGL_EXT_platform_wayland
+#define EGL_EXT_platform_wayland 1
+#define EGL_PLATFORM_WAYLAND_EXT 0x31D8
+#endif /* EGL_EXT_platform_wayland */
+
+#ifndef EGL_EXT_platform_x11
+#define EGL_EXT_platform_x11 1
+#define EGL_PLATFORM_X11_EXT 0x31D5
+#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6
+#endif /* EGL_EXT_platform_x11 */
+
+#ifndef EGL_EXT_platform_xcb
+#define EGL_EXT_platform_xcb 1
+#define EGL_PLATFORM_XCB_EXT 0x31DC
+#define EGL_PLATFORM_XCB_SCREEN_EXT 0x31DE
+#endif /* EGL_EXT_platform_xcb */
+
+#ifndef EGL_EXT_present_opaque
+#define EGL_EXT_present_opaque 1
+#define EGL_PRESENT_OPAQUE_EXT 0x31DF
+#endif /* EGL_EXT_present_opaque */
+
+#ifndef EGL_EXT_protected_content
+#define EGL_EXT_protected_content 1
+#define EGL_PROTECTED_CONTENT_EXT 0x32C0
+#endif /* EGL_EXT_protected_content */
+
+#ifndef EGL_EXT_protected_surface
+#define EGL_EXT_protected_surface 1
+#endif /* EGL_EXT_protected_surface */
+
+#ifndef EGL_EXT_stream_consumer_egloutput
+#define EGL_EXT_stream_consumer_egloutput 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
+#endif
+#endif /* EGL_EXT_stream_consumer_egloutput */
+
+#ifndef EGL_EXT_surface_CTA861_3_metadata
+#define EGL_EXT_surface_CTA861_3_metadata 1
+#define EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT 0x3360
+#define EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT 0x3361
+#endif /* EGL_EXT_surface_CTA861_3_metadata */
+
+#ifndef EGL_EXT_surface_SMPTE2086_metadata
+#define EGL_EXT_surface_SMPTE2086_metadata 1
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT 0x3341
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT 0x3342
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT 0x3343
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT 0x3344
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT 0x3345
+#define EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT 0x3346
+#define EGL_SMPTE2086_WHITE_POINT_X_EXT 0x3347
+#define EGL_SMPTE2086_WHITE_POINT_Y_EXT 0x3348
+#define EGL_SMPTE2086_MAX_LUMINANCE_EXT 0x3349
+#define EGL_SMPTE2086_MIN_LUMINANCE_EXT 0x334A
+#define EGL_METADATA_SCALING_EXT 50000
+#endif /* EGL_EXT_surface_SMPTE2086_metadata */
+
+#ifndef EGL_EXT_surface_compression
+#define EGL_EXT_surface_compression 1
+#define EGL_SURFACE_COMPRESSION_EXT 0x34B0
+#define EGL_SURFACE_COMPRESSION_PLANE1_EXT 0x328E
+#define EGL_SURFACE_COMPRESSION_PLANE2_EXT 0x328F
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT 0x34B1
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT 0x34B2
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT 0x34B4
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_2BPC_EXT 0x34B5
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_3BPC_EXT 0x34B6
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_4BPC_EXT 0x34B7
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_5BPC_EXT 0x34B8
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_6BPC_EXT 0x34B9
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_7BPC_EXT 0x34BA
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_8BPC_EXT 0x34BB
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_9BPC_EXT 0x34BC
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_10BPC_EXT 0x34BD
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_11BPC_EXT 0x34BE
+#define EGL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT 0x34BF
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSUPPORTEDCOMPRESSIONRATESEXTPROC) (EGLDisplay dpy, EGLConfig config, const EGLAttrib *attrib_list, EGLint *rates, EGLint rate_size, EGLint *num_rates);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySupportedCompressionRatesEXT (EGLDisplay dpy, EGLConfig config, const EGLAttrib *attrib_list, EGLint *rates, EGLint rate_size, EGLint *num_rates);
+#endif
+#endif /* EGL_EXT_surface_compression */
+
+#ifndef EGL_EXT_swap_buffers_with_damage
+#define EGL_EXT_swap_buffers_with_damage 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
+#endif
+#endif /* EGL_EXT_swap_buffers_with_damage */
+
+#ifndef EGL_EXT_sync_reuse
+#define EGL_EXT_sync_reuse 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglUnsignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
+#endif
+#endif /* EGL_EXT_sync_reuse */
+
+#ifndef EGL_EXT_yuv_surface
+#define EGL_EXT_yuv_surface 1
+#define EGL_YUV_ORDER_EXT 0x3301
+#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311
+#define EGL_YUV_SUBSAMPLE_EXT 0x3312
+#define EGL_YUV_DEPTH_RANGE_EXT 0x3317
+#define EGL_YUV_CSC_STANDARD_EXT 0x330A
+#define EGL_YUV_PLANE_BPP_EXT 0x331A
+#define EGL_YUV_BUFFER_EXT 0x3300
+#define EGL_YUV_ORDER_YUV_EXT 0x3302
+#define EGL_YUV_ORDER_YVU_EXT 0x3303
+#define EGL_YUV_ORDER_YUYV_EXT 0x3304
+#define EGL_YUV_ORDER_UYVY_EXT 0x3305
+#define EGL_YUV_ORDER_YVYU_EXT 0x3306
+#define EGL_YUV_ORDER_VYUY_EXT 0x3307
+#define EGL_YUV_ORDER_AYUV_EXT 0x3308
+#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313
+#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314
+#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315
+#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318
+#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319
+#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B
+#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C
+#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D
+#define EGL_YUV_PLANE_BPP_0_EXT 0x331B
+#define EGL_YUV_PLANE_BPP_8_EXT 0x331C
+#define EGL_YUV_PLANE_BPP_10_EXT 0x331D
+#endif /* EGL_EXT_yuv_surface */
+
+#ifndef EGL_HI_clientpixmap
+#define EGL_HI_clientpixmap 1
+struct EGLClientPixmapHI {
+ void *pData;
+ EGLint iWidth;
+ EGLint iHeight;
+ EGLint iStride;
+};
+#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
+#endif
+#endif /* EGL_HI_clientpixmap */
+
+#ifndef EGL_HI_colorformats
+#define EGL_HI_colorformats 1
+#define EGL_COLOR_FORMAT_HI 0x8F70
+#define EGL_COLOR_RGB_HI 0x8F71
+#define EGL_COLOR_RGBA_HI 0x8F72
+#define EGL_COLOR_ARGB_HI 0x8F73
+#endif /* EGL_HI_colorformats */
+
+#ifndef EGL_IMG_context_priority
+#define EGL_IMG_context_priority 1
+#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
+#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
+#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
+#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
+#endif /* EGL_IMG_context_priority */
+
+#ifndef EGL_IMG_image_plane_attribs
+#define EGL_IMG_image_plane_attribs 1
+#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105
+#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106
+#endif /* EGL_IMG_image_plane_attribs */
+
+#ifndef EGL_MESA_drm_image
+#define EGL_MESA_drm_image 1
+#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0
+#define EGL_DRM_BUFFER_USE_MESA 0x31D1
+#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
+#define EGL_DRM_BUFFER_MESA 0x31D3
+#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
+#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001
+#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002
+#define EGL_DRM_BUFFER_USE_CURSOR_MESA 0x00000004
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
+#endif
+#endif /* EGL_MESA_drm_image */
+
+#ifndef EGL_MESA_image_dma_buf_export
+#define EGL_MESA_image_dma_buf_export 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers);
+EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets);
+#endif
+#endif /* EGL_MESA_image_dma_buf_export */
+
+#ifndef EGL_MESA_platform_gbm
+#define EGL_MESA_platform_gbm 1
+#define EGL_PLATFORM_GBM_MESA 0x31D7
+#endif /* EGL_MESA_platform_gbm */
+
+#ifndef EGL_MESA_platform_surfaceless
+#define EGL_MESA_platform_surfaceless 1
+#define EGL_PLATFORM_SURFACELESS_MESA 0x31DD
+#endif /* EGL_MESA_platform_surfaceless */
+
+#ifndef EGL_MESA_query_driver
+#define EGL_MESA_query_driver 1
+typedef char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERCONFIGPROC) (EGLDisplay dpy);
+typedef const char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERNAMEPROC) (EGLDisplay dpy);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI char *EGLAPIENTRY eglGetDisplayDriverConfig (EGLDisplay dpy);
+EGLAPI const char *EGLAPIENTRY eglGetDisplayDriverName (EGLDisplay dpy);
+#endif
+#endif /* EGL_MESA_query_driver */
+
+#ifndef EGL_NOK_swap_region
+#define EGL_NOK_swap_region 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region */
+
+#ifndef EGL_NOK_swap_region2
+#define EGL_NOK_swap_region2 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
+#endif
+#endif /* EGL_NOK_swap_region2 */
+
+#ifndef EGL_NOK_texture_from_pixmap
+#define EGL_NOK_texture_from_pixmap 1
+#define EGL_Y_INVERTED_NOK 0x307F
+#endif /* EGL_NOK_texture_from_pixmap */
+
+#ifndef EGL_NV_3dvision_surface
+#define EGL_NV_3dvision_surface 1
+#define EGL_AUTO_STEREO_NV 0x3136
+#endif /* EGL_NV_3dvision_surface */
+
+#ifndef EGL_NV_context_priority_realtime
+#define EGL_NV_context_priority_realtime 1
+#define EGL_CONTEXT_PRIORITY_REALTIME_NV 0x3357
+#endif /* EGL_NV_context_priority_realtime */
+
+#ifndef EGL_NV_coverage_sample
+#define EGL_NV_coverage_sample 1
+#define EGL_COVERAGE_BUFFERS_NV 0x30E0
+#define EGL_COVERAGE_SAMPLES_NV 0x30E1
+#endif /* EGL_NV_coverage_sample */
+
+#ifndef EGL_NV_coverage_sample_resolve
+#define EGL_NV_coverage_sample_resolve 1
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
+#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
+#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
+#endif /* EGL_NV_coverage_sample_resolve */
+
+#ifndef EGL_NV_cuda_event
+#define EGL_NV_cuda_event 1
+#define EGL_CUDA_EVENT_HANDLE_NV 0x323B
+#define EGL_SYNC_CUDA_EVENT_NV 0x323C
+#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D
+#endif /* EGL_NV_cuda_event */
+
+#ifndef EGL_NV_depth_nonlinear
+#define EGL_NV_depth_nonlinear 1
+#define EGL_DEPTH_ENCODING_NV 0x30E2
+#define EGL_DEPTH_ENCODING_NONE_NV 0
+#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
+#endif /* EGL_NV_depth_nonlinear */
+
+#ifndef EGL_NV_device_cuda
+#define EGL_NV_device_cuda 1
+#define EGL_CUDA_DEVICE_NV 0x323A
+#endif /* EGL_NV_device_cuda */
+
+#ifndef EGL_NV_native_query
+#define EGL_NV_native_query 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV (EGLDisplay dpy, EGLNativeDisplayType *display_id);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
+#endif
+#endif /* EGL_NV_native_query */
+
+#ifndef EGL_NV_post_convert_rounding
+#define EGL_NV_post_convert_rounding 1
+#endif /* EGL_NV_post_convert_rounding */
+
+#ifndef EGL_NV_post_sub_buffer
+#define EGL_NV_post_sub_buffer 1
+#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+#endif
+#endif /* EGL_NV_post_sub_buffer */
+
+#ifndef EGL_NV_quadruple_buffer
+#define EGL_NV_quadruple_buffer 1
+#define EGL_QUADRUPLE_BUFFER_NV 0x3231
+#endif /* EGL_NV_quadruple_buffer */
+
+#ifndef EGL_NV_robustness_video_memory_purge
+#define EGL_NV_robustness_video_memory_purge 1
+#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C
+#endif /* EGL_NV_robustness_video_memory_purge */
+
+#ifndef EGL_NV_stream_consumer_eglimage
+#define EGL_NV_stream_consumer_eglimage 1
+#define EGL_STREAM_CONSUMER_IMAGE_NV 0x3373
+#define EGL_STREAM_IMAGE_ADD_NV 0x3374
+#define EGL_STREAM_IMAGE_REMOVE_NV 0x3375
+#define EGL_STREAM_IMAGE_AVAILABLE_NV 0x3376
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMIMAGECONSUMERCONNECTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, const EGLuint64KHR *modifiers, const EGLAttrib *attrib_list);
+typedef EGLint (EGLAPIENTRYP PFNEGLQUERYSTREAMCONSUMEREVENTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMACQUIREIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMRELEASEIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamImageConsumerConnectNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, const EGLuint64KHR *modifiers, const EGLAttrib *attrib_list);
+EGLAPI EGLint EGLAPIENTRY eglQueryStreamConsumerEventNV (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamAcquireImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamReleaseImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync);
+#endif
+#endif /* EGL_NV_stream_consumer_eglimage */
+
+#ifndef EGL_NV_stream_consumer_gltexture_yuv
+#define EGL_NV_stream_consumer_gltexture_yuv 1
+#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C
+#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D
+#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+#endif
+#endif /* EGL_NV_stream_consumer_gltexture_yuv */
+
+#ifndef EGL_NV_stream_cross_display
+#define EGL_NV_stream_cross_display 1
+#define EGL_STREAM_CROSS_DISPLAY_NV 0x334E
+#endif /* EGL_NV_stream_cross_display */
+
+#ifndef EGL_NV_stream_cross_object
+#define EGL_NV_stream_cross_object 1
+#define EGL_STREAM_CROSS_OBJECT_NV 0x334D
+#endif /* EGL_NV_stream_cross_object */
+
+#ifndef EGL_NV_stream_cross_partition
+#define EGL_NV_stream_cross_partition 1
+#define EGL_STREAM_CROSS_PARTITION_NV 0x323F
+#endif /* EGL_NV_stream_cross_partition */
+
+#ifndef EGL_NV_stream_cross_process
+#define EGL_NV_stream_cross_process 1
+#define EGL_STREAM_CROSS_PROCESS_NV 0x3245
+#endif /* EGL_NV_stream_cross_process */
+
+#ifndef EGL_NV_stream_cross_system
+#define EGL_NV_stream_cross_system 1
+#define EGL_STREAM_CROSS_SYSTEM_NV 0x334F
+#endif /* EGL_NV_stream_cross_system */
+
+#ifndef EGL_NV_stream_dma
+#define EGL_NV_stream_dma 1
+#define EGL_STREAM_DMA_NV 0x3371
+#define EGL_STREAM_DMA_SERVER_NV 0x3372
+#endif /* EGL_NV_stream_dma */
+
+#ifndef EGL_NV_stream_fifo_next
+#define EGL_NV_stream_fifo_next 1
+#define EGL_PENDING_FRAME_NV 0x3329
+#define EGL_STREAM_TIME_PENDING_NV 0x332A
+#endif /* EGL_NV_stream_fifo_next */
+
+#ifndef EGL_NV_stream_fifo_synchronous
+#define EGL_NV_stream_fifo_synchronous 1
+#define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336
+#endif /* EGL_NV_stream_fifo_synchronous */
+
+#ifndef EGL_NV_stream_flush
+#define EGL_NV_stream_flush 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMFLUSHNVPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamFlushNV (EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+#endif /* EGL_NV_stream_flush */
+
+#ifndef EGL_NV_stream_frame_limits
+#define EGL_NV_stream_frame_limits 1
+#define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337
+#define EGL_CONSUMER_MAX_FRAME_HINT_NV 0x3338
+#endif /* EGL_NV_stream_frame_limits */
+
+#ifndef EGL_NV_stream_metadata
+#define EGL_NV_stream_metadata 1
+#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250
+#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251
+#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252
+#define EGL_PRODUCER_METADATA_NV 0x3253
+#define EGL_CONSUMER_METADATA_NV 0x3254
+#define EGL_PENDING_METADATA_NV 0x3328
+#define EGL_METADATA0_SIZE_NV 0x3255
+#define EGL_METADATA1_SIZE_NV 0x3256
+#define EGL_METADATA2_SIZE_NV 0x3257
+#define EGL_METADATA3_SIZE_NV 0x3258
+#define EGL_METADATA0_TYPE_NV 0x3259
+#define EGL_METADATA1_TYPE_NV 0x325A
+#define EGL_METADATA2_TYPE_NV 0x325B
+#define EGL_METADATA3_TYPE_NV 0x325C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribNV (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data);
+#endif
+#endif /* EGL_NV_stream_metadata */
+
+#ifndef EGL_NV_stream_origin
+#define EGL_NV_stream_origin 1
+#define EGL_STREAM_FRAME_ORIGIN_X_NV 0x3366
+#define EGL_STREAM_FRAME_ORIGIN_Y_NV 0x3367
+#define EGL_STREAM_FRAME_MAJOR_AXIS_NV 0x3368
+#define EGL_CONSUMER_AUTO_ORIENTATION_NV 0x3369
+#define EGL_PRODUCER_AUTO_ORIENTATION_NV 0x336A
+#define EGL_LEFT_NV 0x336B
+#define EGL_RIGHT_NV 0x336C
+#define EGL_TOP_NV 0x336D
+#define EGL_BOTTOM_NV 0x336E
+#define EGL_X_AXIS_NV 0x336F
+#define EGL_Y_AXIS_NV 0x3370
+#endif /* EGL_NV_stream_origin */
+
+#ifndef EGL_NV_stream_remote
+#define EGL_NV_stream_remote 1
+#define EGL_STREAM_STATE_INITIALIZING_NV 0x3240
+#define EGL_STREAM_TYPE_NV 0x3241
+#define EGL_STREAM_PROTOCOL_NV 0x3242
+#define EGL_STREAM_ENDPOINT_NV 0x3243
+#define EGL_STREAM_LOCAL_NV 0x3244
+#define EGL_STREAM_PRODUCER_NV 0x3247
+#define EGL_STREAM_CONSUMER_NV 0x3248
+#define EGL_STREAM_PROTOCOL_FD_NV 0x3246
+#endif /* EGL_NV_stream_remote */
+
+#ifndef EGL_NV_stream_reset
+#define EGL_NV_stream_reset 1
+#define EGL_SUPPORT_RESET_NV 0x3334
+#define EGL_SUPPORT_REUSE_NV 0x3335
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLRESETSTREAMNVPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglResetStreamNV (EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+#endif /* EGL_NV_stream_reset */
+
+#ifndef EGL_NV_stream_socket
+#define EGL_NV_stream_socket 1
+#define EGL_STREAM_PROTOCOL_SOCKET_NV 0x324B
+#define EGL_SOCKET_HANDLE_NV 0x324C
+#define EGL_SOCKET_TYPE_NV 0x324D
+#endif /* EGL_NV_stream_socket */
+
+#ifndef EGL_NV_stream_socket_inet
+#define EGL_NV_stream_socket_inet 1
+#define EGL_SOCKET_TYPE_INET_NV 0x324F
+#endif /* EGL_NV_stream_socket_inet */
+
+#ifndef EGL_NV_stream_socket_unix
+#define EGL_NV_stream_socket_unix 1
+#define EGL_SOCKET_TYPE_UNIX_NV 0x324E
+#endif /* EGL_NV_stream_socket_unix */
+
+#ifndef EGL_NV_stream_sync
+#define EGL_NV_stream_sync 1
+#define EGL_SYNC_NEW_FRAME_NV 0x321F
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
+#endif
+#endif /* EGL_NV_stream_sync */
+
+#ifndef EGL_NV_sync
+#define EGL_NV_sync 1
+typedef void *EGLSyncNV;
+typedef khronos_utime_nanoseconds_t EGLTimeNV;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
+#define EGL_SYNC_STATUS_NV 0x30E7
+#define EGL_SIGNALED_NV 0x30E8
+#define EGL_UNSIGNALED_NV 0x30E9
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
+#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull
+#define EGL_ALREADY_SIGNALED_NV 0x30EA
+#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
+#define EGL_CONDITION_SATISFIED_NV 0x30EC
+#define EGL_SYNC_TYPE_NV 0x30ED
+#define EGL_SYNC_CONDITION_NV 0x30EE
+#define EGL_SYNC_FENCE_NV 0x30EF
+#define EGL_NO_SYNC_NV EGL_CAST(EGLSyncNV,0)
+typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync);
+EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_NV_sync */
+
+#ifndef EGL_NV_system_time
+#define EGL_NV_system_time 1
+typedef khronos_utime_nanoseconds_t EGLuint64NV;
+#ifdef KHRONOS_SUPPORT_INT64
+typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void);
+typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void);
+EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void);
+#endif
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_NV_system_time */
+
+#ifndef EGL_NV_triple_buffer
+#define EGL_NV_triple_buffer 1
+#define EGL_TRIPLE_BUFFER_NV 0x3230
+#endif /* EGL_NV_triple_buffer */
+
+#ifndef EGL_TIZEN_image_native_buffer
+#define EGL_TIZEN_image_native_buffer 1
+#define EGL_NATIVE_BUFFER_TIZEN 0x32A0
+#endif /* EGL_TIZEN_image_native_buffer */
+
+#ifndef EGL_TIZEN_image_native_surface
+#define EGL_TIZEN_image_native_surface 1
+#define EGL_NATIVE_SURFACE_TIZEN 0x32A1
+#endif /* EGL_TIZEN_image_native_surface */
+
+#ifndef EGL_WL_bind_wayland_display
+#define EGL_WL_bind_wayland_display 1
+#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC
+#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC
+#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC
+struct wl_display;
+struct wl_resource;
+#define EGL_WAYLAND_BUFFER_WL 0x31D5
+#define EGL_WAYLAND_PLANE_WL 0x31D6
+#define EGL_TEXTURE_Y_U_V_WL 0x31D7
+#define EGL_TEXTURE_Y_UV_WL 0x31D8
+#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
+#define EGL_TEXTURE_EXTERNAL_WL 0x31DA
+#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWLPROC) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display);
+EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
+#endif
+#endif /* EGL_WL_bind_wayland_display */
+
+#ifndef EGL_WL_create_wayland_buffer_from_image
+#define EGL_WL_create_wayland_buffer_from_image 1
+#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC
+struct wl_buffer;
+typedef struct wl_buffer *(EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC) (EGLDisplay dpy, EGLImageKHR image);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI struct wl_buffer *EGLAPIENTRY eglCreateWaylandBufferFromImageWL (EGLDisplay dpy, EGLImageKHR image);
+#endif
+#endif /* EGL_WL_create_wayland_buffer_from_image */
+
+/* ANGLE EGL extensions */
+#include "eglext_angle.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/include/EGL/eglext_angle.h b/gfx/angle/checkout/include/EGL/eglext_angle.h
new file mode 100644
index 0000000000..caf3780172
--- /dev/null
+++ b/gfx/angle/checkout/include/EGL/eglext_angle.h
@@ -0,0 +1,412 @@
+//
+// 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.
+//
+// eglext_angle.h: ANGLE modifications to the eglext.h header file.
+// Currently we don't include this file directly, we patch eglext.h
+// to include it implicitly so it is visible throughout our code.
+
+#ifndef INCLUDE_EGL_EGLEXT_ANGLE_
+#define INCLUDE_EGL_EGLEXT_ANGLE_
+
+// clang-format off
+
+#ifndef EGL_ANGLE_robust_resource_initialization
+#define EGL_ANGLE_robust_resource_initialization 1
+#define EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x3453
+#endif /* EGL_ANGLE_robust_resource_initialization */
+
+#ifndef EGL_ANGLE_keyed_mutex
+#define EGL_ANGLE_keyed_mutex 1
+#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2
+#endif /* EGL_ANGLE_keyed_mutex */
+
+#ifndef EGL_ANGLE_d3d_texture_client_buffer
+#define EGL_ANGLE_d3d_texture_client_buffer 1
+#define EGL_D3D_TEXTURE_ANGLE 0x33A3
+#define EGL_TEXTURE_OFFSET_X_ANGLE 0x3490
+#define EGL_TEXTURE_OFFSET_Y_ANGLE 0x3491
+#define EGL_D3D11_TEXTURE_PLANE_ANGLE 0x3492
+#define EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE 0x3493
+#endif /* EGL_ANGLE_d3d_texture_client_buffer */
+
+#ifndef EGL_ANGLE_software_display
+#define EGL_ANGLE_software_display 1
+#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1)
+#endif /* EGL_ANGLE_software_display */
+
+#ifndef EGL_ANGLE_direct3d_display
+#define EGL_ANGLE_direct3d_display 1
+#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ((EGLNativeDisplayType)-2)
+#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-3)
+#endif /* EGL_ANGLE_direct3d_display */
+
+#ifndef EGL_ANGLE_direct_composition
+#define EGL_ANGLE_direct_composition 1
+#define EGL_DIRECT_COMPOSITION_ANGLE 0x33A5
+#endif /* EGL_ANGLE_direct_composition */
+
+#ifndef EGL_ANGLE_platform_angle
+#define EGL_ANGLE_platform_angle 1
+#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
+#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
+#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204
+#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205
+#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206
+#define EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE 0x3451
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x345E
+#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348F
+#endif /* EGL_ANGLE_platform_angle */
+
+#ifndef EGL_ANGLE_platform_angle_d3d
+#define EGL_ANGLE_platform_angle_d3d 1
+#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
+#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE 0x320B
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE 0x320C
+#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
+#endif /* EGL_ANGLE_platform_angle_d3d */
+
+#ifndef EGL_ANGLE_platform_angle_d3d_luid
+#define EGL_ANGLE_platform_angle_d3d_luid 1
+#define EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE 0x34A0
+#define EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE 0x34A1
+#endif /* EGL_ANGLE_platform_angle_d3d_luid */
+
+#ifndef EGL_ANGLE_platform_angle_d3d11on12
+#define EGL_ANGLE_platform_angle_d3d11on12 1
+#define EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE 0x3488
+#endif /* EGL_ANGLE_platform_angle_d3d11on12 */
+
+#ifndef EGL_ANGLE_platform_angle_opengl
+#define EGL_ANGLE_platform_angle_opengl 1
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
+#define EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE 0x3480
+#endif /* EGL_ANGLE_platform_angle_opengl */
+
+#ifndef EGL_ANGLE_platform_angle_null
+#define EGL_ANGLE_platform_angle_null 1
+#define EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE 0x33AE
+#endif /* EGL_ANGLE_platform_angle_null */
+
+#ifndef EGL_ANGLE_platform_angle_vulkan
+#define EGL_ANGLE_platform_angle_vulkan 1
+#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
+#define EGL_PLATFORM_VULKAN_DISPLAY_MODE_SIMPLE_ANGLE 0x34A4
+#define EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE 0x34A5
+#endif /* EGL_ANGLE_platform_angle_vulkan */
+
+#ifndef EGL_ANGLE_platform_angle_metal
+#define EGL_ANGLE_platform_angle_metal 1
+#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
+#endif /* EGL_ANGLE_platform_angle_metal */
+
+#ifndef EGL_ANGLE_platform_angle_device_type_swiftshader
+#define EGL_ANGLE_platform_angle_device_type_swiftshader
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE 0x3487
+#endif /* EGL_ANGLE_platform_angle_device_type_swiftshader */
+
+#ifndef EGL_ANGLE_platform_angle_device_type_egl_angle
+#define EGL_ANGLE_platform_angle_device_type_egl_angle
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE 0x348E
+#endif /* EGL_ANGLE_platform_angle_device_type_egl_angle */
+
+#ifndef EGL_ANGLE_context_virtualization
+#define EGL_ANGLE_context_virtualization 1
+#define EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE 0x3481
+#endif /* EGL_ANGLE_context_virtualization */
+
+#ifndef EGL_ANGLE_platform_angle_device_context_volatile_eagl
+#define EGL_ANGLE_platform_angle_device_context_volatile_eagl 1
+#define EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE 0x34A2
+#endif /* EGL_ANGLE_platform_angle_device_context_volatile_eagl */
+
+#ifndef EGL_ANGLE_platform_angle_device_context_volatile_cgl
+#define EGL_ANGLE_platform_angle_device_context_volatile_cgl 1
+#define EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE 0x34A3
+#endif /* EGL_ANGLE_platform_angle_device_context_volatile_cgl */
+
+#ifndef EGL_ANGLE_platform_angle_device_id
+#define EGL_ANGLE_platform_angle_device_id
+#define EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE 0x34D6
+#define EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE 0x34D7
+#endif /* EGL_ANGLE_platform_angle_device_id */
+
+#ifndef EGL_ANGLE_x11_visual
+#define EGL_ANGLE_x11_visual
+#define EGL_X11_VISUAL_ID_ANGLE 0x33A3
+#endif /* EGL_ANGLE_x11_visual */
+
+#ifndef EGL_ANGLE_surface_orientation
+#define EGL_ANGLE_surface_orientation
+#define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7
+#define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8
+#define EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE 0x0001
+#define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002
+#endif /* EGL_ANGLE_surface_orientation */
+
+#ifndef EGL_ANGLE_experimental_present_path
+#define EGL_ANGLE_experimental_present_path
+#define EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE 0x33A4
+#define EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE 0x33A9
+#define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA
+#endif /* EGL_ANGLE_experimental_present_path */
+
+#ifndef EGL_ANGLE_stream_producer_d3d_texture
+#define EGL_ANGLE_stream_producer_d3d_texture
+#define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x33AB
+typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTUREANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTUREANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureANGLE(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureANGLE(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
+#endif
+#endif /* EGL_ANGLE_stream_producer_d3d_texture */
+
+#ifndef EGL_ANGLE_create_context_webgl_compatibility
+#define EGL_ANGLE_create_context_webgl_compatibility 1
+#define EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE 0x33AC
+#endif /* EGL_ANGLE_create_context_webgl_compatibility */
+
+#ifndef EGL_ANGLE_display_texture_share_group
+#define EGL_ANGLE_display_texture_share_group 1
+#define EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE 0x33AF
+#endif /* EGL_ANGLE_display_texture_share_group */
+
+#ifndef EGL_CHROMIUM_create_context_bind_generates_resource
+#define EGL_CHROMIUM_create_context_bind_generates_resource 1
+#define EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM 0x33AD
+#endif /* EGL_CHROMIUM_create_context_bind_generates_resource */
+
+#ifndef EGL_ANGLE_metal_create_context_ownership_identity
+#define EGL_ANGLE_metal_create_context_ownership_identity 1
+#define EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE 0x34D2
+#endif /* EGL_ANGLE_metal_create_context_ownership_identity */
+
+#ifndef EGL_ANGLE_create_context_client_arrays
+#define EGL_ANGLE_create_context_client_arrays 1
+#define EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE 0x3452
+#endif /* EGL_ANGLE_create_context_client_arrays */
+
+#ifndef EGL_ANGLE_device_creation
+#define EGL_ANGLE_device_creation 1
+typedef EGLDeviceEXT(EGLAPIENTRYP PFNEGLCREATEDEVICEANGLEPROC) (EGLint device_type, void *native_device, const EGLAttrib *attrib_list);
+typedef EGLBoolean(EGLAPIENTRYP PFNEGLRELEASEDEVICEANGLEPROC) (EGLDeviceEXT device);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLDeviceEXT EGLAPIENTRY eglCreateDeviceANGLE(EGLint device_type, void *native_device, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseDeviceANGLE(EGLDeviceEXT device);
+#endif
+#endif /* EGL_ANGLE_device_creation */
+
+#ifndef EGL_ANGLE_program_cache_control
+#define EGL_ANGLE_program_cache_control 1
+#define EGL_PROGRAM_CACHE_SIZE_ANGLE 0x3455
+#define EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE 0x3456
+#define EGL_PROGRAM_CACHE_RESIZE_ANGLE 0x3457
+#define EGL_PROGRAM_CACHE_TRIM_ANGLE 0x3458
+#define EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE 0x3459
+typedef EGLint (EGLAPIENTRYP PFNEGLPROGRAMCACHEGETATTRIBANGLEPROC) (EGLDisplay dpy, EGLenum attrib);
+typedef void (EGLAPIENTRYP PFNEGLPROGRAMCACHEQUERYANGLEPROC) (EGLDisplay dpy, EGLint index, void *key, EGLint *keysize, void *binary, EGLint *binarysize);
+typedef void (EGLAPIENTRYP PFNEGLPROGRAMCACHEPOPULATEANGLEPROC) (EGLDisplay dpy, const void *key, EGLint keysize, const void *binary, EGLint binarysize);
+typedef EGLint (EGLAPIENTRYP PFNEGLPROGRAMCACHERESIZEANGLEPROC) (EGLDisplay dpy, EGLint limit, EGLint mode);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib);
+EGLAPI void EGLAPIENTRY eglProgramCacheQueryANGLE(EGLDisplay dpy, EGLint index, void *key, EGLint *keysize, void *binary, EGLint *binarysize);
+EGLAPI void EGLAPIENTRY eglProgramCachePopulateANGLE(EGLDisplay dpy, const void *key, EGLint keysize, const void *binary, EGLint binarysize);
+EGLAPI EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLint mode);
+#endif
+#endif /* EGL_ANGLE_program_cache_control */
+
+#ifndef EGL_ANGLE_iosurface_client_buffer
+#define EGL_ANGLE_iosurface_client_buffer 1
+#define EGL_IOSURFACE_ANGLE 0x3454
+#define EGL_IOSURFACE_PLANE_ANGLE 0x345A
+#define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
+#define EGL_TEXTURE_TYPE_ANGLE 0x345C
+#define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
+#define EGL_IOSURFACE_USAGE_HINT_ANGLE 0x348A
+#define EGL_IOSURFACE_READ_HINT_ANGLE 0x0001
+#define EGL_IOSURFACE_WRITE_HINT_ANGLE 0x0002
+#define EGL_BIND_TO_TEXTURE_TARGET_ANGLE 0x348D
+#endif /* EGL_ANGLE_iosurface_client_buffer */
+
+#ifndef ANGLE_metal_texture_client_buffer
+#define ANGLE_metal_texture_client_buffer 1
+#define EGL_METAL_TEXTURE_ANGLE 0x34A7
+#endif /* ANGLE_metal_texture_client_buffer */
+
+#ifndef EGL_ANGLE_create_context_extensions_enabled
+#define EGL_ANGLE_create_context_extensions_enabled 1
+#define EGL_EXTENSIONS_ENABLED_ANGLE 0x345F
+#endif /* EGL_ANGLE_create_context_extensions_enabled */
+
+#ifndef EGL_CHROMIUM_sync_control
+#define EGL_CHROMIUM_sync_control 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCVALUESCHROMIUMPROC) (EGLDisplay dpy,
+ EGLSurface surface,
+ EGLuint64KHR *ust,
+ EGLuint64KHR *msc,
+ EGLuint64KHR *sbc);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncValuesCHROMIUM(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLuint64KHR *ust,
+ EGLuint64KHR *msc,
+ EGLuint64KHR *sbc);
+#endif
+#endif /* EGL_CHROMIUM_sync_control */
+
+#ifndef EGL_ANGLE_sync_control_rate
+#define EGL_ANGLE_sync_control_rate 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMSCRATEANGLEPROC) (EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint *numerator,
+ EGLint *denominator);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglGetMscRateANGLE(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint *numerator,
+ EGLint *denominator);
+#endif
+#endif /* EGL_ANGLE_sync_control_rate */
+
+#ifndef EGL_ANGLE_power_preference
+#define EGL_ANGLE_power_preference 1
+#define EGL_POWER_PREFERENCE_ANGLE 0x3482
+#define EGL_LOW_POWER_ANGLE 0x0001
+#define EGL_HIGH_POWER_ANGLE 0x0002
+typedef void(EGLAPIENTRYP PFNEGLRELEASEHIGHPOWERGPUANGLEPROC) (EGLDisplay dpy, EGLContext ctx);
+typedef void(EGLAPIENTRYP PFNEGLREACQUIREHIGHPOWERGPUANGLEPROC) (EGLDisplay dpy, EGLContext ctx);
+typedef void(EGLAPIENTRYP PFNEGLHANDLEGPUSWITCHANGLEPROC) (EGLDisplay dpy);
+typedef void(EGLAPIENTRYP PFNEGLFORCEGPUSWITCHANGLEPROC) (EGLDisplay dpy, EGLint gpuIDHigh, EGLint gpuIDLow);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI void EGLAPIENTRY eglReleaseHighPowerGPUANGLE(EGLDisplay dpy, EGLContext ctx);
+EGLAPI void EGLAPIENTRY eglReacquireHighPowerGPUANGLE(EGLDisplay dpy, EGLContext ctx);
+EGLAPI void EGLAPIENTRY eglHandleGPUSwitchANGLE(EGLDisplay dpy);
+EGLAPI void EGLAPIENTRY eglForceGPUSwitchANGLE(EGLDisplay dpy, EGLint gpuIDHigh, EGLint gpuIDLow);
+#endif
+#endif /* EGL_ANGLE_power_preference */
+
+#ifndef EGL_ANGLE_feature_control
+#define EGL_ANGLE_feature_control 1
+#define EGL_FEATURE_NAME_ANGLE 0x3460
+#define EGL_FEATURE_CATEGORY_ANGLE 0x3461
+#define EGL_FEATURE_DESCRIPTION_ANGLE 0x3462
+#define EGL_FEATURE_BUG_ANGLE 0x3463
+#define EGL_FEATURE_STATUS_ANGLE 0x3464
+#define EGL_FEATURE_COUNT_ANGLE 0x3465
+#define EGL_FEATURE_OVERRIDES_ENABLED_ANGLE 0x3466
+#define EGL_FEATURE_OVERRIDES_DISABLED_ANGLE 0x3467
+#define EGL_FEATURE_CONDITION_ANGLE 0x3468
+#define EGL_FEATURE_ALL_DISABLED_ANGLE 0x3469
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYSTRINGIANGLEPROC) (EGLDisplay dpy, EGLint name, EGLint index);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBANGLEPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI const char *EGLAPIENTRY eglQueryStringiANGLE(EGLDisplay dpy, EGLint name, EGLint index);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribANGLE(EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+#endif
+#endif /* EGL_ANGLE_feature_control */
+
+#ifndef EGL_ANGLE_image_d3d11_texture
+#define EGL_D3D11_TEXTURE_ANGLE 0x3484
+#define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
+#endif /* EGL_ANGLE_image_d3d11_texture */
+
+#ifndef EGL_ANGLE_create_context_backwards_compatible
+#define EGL_ANGLE_create_context_backwards_compatible 1
+#define EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE 0x3483
+#endif /* EGL_ANGLE_create_context_backwards_compatible */
+
+#ifndef EGL_ANGLE_device_cgl
+#define EGL_ANGLE_device_cgl 1
+#define EGL_CGL_CONTEXT_ANGLE 0x3485
+#define EGL_CGL_PIXEL_FORMAT_ANGLE 0x3486
+#endif
+
+#ifndef EGL_ANGLE_ggp_stream_descriptor
+#define EGL_ANGLE_ggp_stream_descriptor 1
+#define EGL_GGP_STREAM_DESCRIPTOR_ANGLE 0x348B
+#endif /* EGL_ANGLE_ggp_stream_descriptor */
+
+#ifndef EGL_ANGLE_swap_with_frame_token
+#define EGL_ANGLE_swap_with_frame_token 1
+typedef khronos_uint64_t EGLFrameTokenANGLE;
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHFRAMETOKENANGLEPROC)(EGLDisplay dpy, EGLSurface surface, EGLFrameTokenANGLE frametoken);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithFrameTokenANGLE(EGLDisplay dpy, EGLSurface surface, EGLFrameTokenANGLE frametoken);
+#endif
+#endif /* EGL_ANGLE_swap_with_frame_token */
+
+#ifndef EGL_ANGLE_prepare_swap_buffers
+#define EGL_ANGLE_prepare_swap_buffers 1
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLPREPARESWAPBUFFERSANGLEPROC)(EGLDisplay dpy, EGLSurface surface);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglPrepareSwapBuffersANGLE(EGLDisplay dpy, EGLSurface surface);
+#endif
+#endif /* EGL_ANGLE_prepare_swap_buffers */
+
+#ifndef EGL_ANGLE_device_eagl
+#define EGL_ANGLE_device_eagl 1
+#define EGL_EAGL_CONTEXT_ANGLE 0x348C
+#endif
+
+#ifndef EGL_ANGLE_device_metal
+#define EGL_ANGLE_device_metal 1
+#define EGL_METAL_DEVICE_ANGLE 0x34A6
+#endif /* EGL_ANGLE_device_metal */
+
+#ifndef EGL_ANGLE_display_semaphore_share_group
+#define EGL_ANGLE_display_semaphore_share_group 1
+#define EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE 0x348D
+#endif /* EGL_ANGLE_display_semaphore_share_group */
+
+#ifndef EGL_ANGLE_external_context_and_surface
+#define EGL_ANGLE_external_context_and_surface 1
+#define EGL_EXTERNAL_CONTEXT_ANGLE 0x348E
+#define EGL_EXTERNAL_SURFACE_ANGLE 0x348F
+#define EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE 0x3490
+#endif /* EGL_ANGLE_external_context_and_surface */
+
+#ifndef EGL_ANGLE_create_surface_swap_interval
+#define EGL_ANGLE_create_surface_swap_interval 1
+#define EGL_SWAP_INTERVAL_ANGLE 0x322F
+#endif /* EGL_ANGLE_create_surface_swap_interval */
+
+#ifndef EGL_ANGLE_device_vulkan
+#define EGL_ANGLE_device_vulkan 1
+#define EGL_VULKAN_VERSION_ANGLE 0x34A8
+#define EGL_VULKAN_INSTANCE_ANGLE 0x34A9
+#define EGL_VULKAN_INSTANCE_EXTENSIONS_ANGLE 0x34AA
+#define EGL_VULKAN_PHYSICAL_DEVICE_ANGLE 0x34AB
+#define EGL_VULKAN_DEVICE_ANGLE 0x34AC
+#define EGL_VULKAN_DEVICE_EXTENSIONS_ANGLE 0x34AD
+#define EGL_VULKAN_FEATURES_ANGLE 0x34AE
+#define EGL_VULKAN_QUEUE_ANGLE 0x34AF
+#define EGL_VULKAN_QUEUE_FAMILIY_INDEX_ANGLE 0x34D0
+#define EGL_VULKAN_GET_INSTANCE_PROC_ADDR 0x34D1
+#endif /* EGL_ANGLE_device_vulkan */
+
+#ifndef EGL_ANGLE_vulkan_image
+#define EGL_ANGLE_vulkan_image
+#define EGL_VULKAN_IMAGE_ANGLE 0x34D3
+#define EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE 0x34D4
+#define EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE 0x34D5
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTVKIMAGEANGLEPROC)(EGLDisplay dpy, EGLImage image, void* vk_image, void* vk_image_create_info);
+#endif /* EGL_ANGLE_vulkan_image */
+
+#ifndef EGL_ANGLE_metal_shared_event_sync
+#define EGL_ANGLE_metal_hared_event_sync 1
+#define EGL_SYNC_METAL_SHARED_EVENT_ANGLE 0x34D8
+#define EGL_SYNC_METAL_SHARED_EVENT_OBJECT_ANGLE 0x34D9
+#define EGL_SYNC_METAL_SHARED_EVENT_SIGNAL_VALUE_LO_ANGLE 0x34DA
+#define EGL_SYNC_METAL_SHARED_EVENT_SIGNAL_VALUE_HI_ANGLE 0x34DB
+typedef void* (EGLAPIENTRYP PFNEGLCOPYMETALSHAREDEVENTANGLEPROC)(EGLDisplay dpy, EGLSyncKHR sync);
+#endif /* EGL_ANGLE_metal_shared_event_sync */
+
+// clang-format on
+
+#endif // INCLUDE_EGL_EGLEXT_ANGLE_
diff --git a/gfx/angle/checkout/include/EGL/eglplatform.h b/gfx/angle/checkout/include/EGL/eglplatform.h
new file mode 100644
index 0000000000..777e985588
--- /dev/null
+++ b/gfx/angle/checkout/include/EGL/eglplatform.h
@@ -0,0 +1,175 @@
+#ifndef __eglplatform_h_
+#define __eglplatform_h_
+
+/*
+** Copyright 2007-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: Apache-2.0
+*/
+
+/* Platform-specific types and definitions for egl.h
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * You are encouraged to submit all modifications to the Khronos group so that
+ * they can be included in future versions of this file. Please submit changes
+ * by filing an issue or pull request on the public Khronos EGL Registry, at
+ * https://www.github.com/KhronosGroup/EGL-Registry/
+ */
+
+#include <KHR/khrplatform.h>
+
+/* Macros used in EGL function prototype declarations.
+ *
+ * EGL functions should be prototyped as:
+ *
+ * EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
+ * typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
+ *
+ * KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
+ */
+
+#ifndef EGLAPI
+#define EGLAPI KHRONOS_APICALL
+#endif
+
+#ifndef EGLAPIENTRY
+#define EGLAPIENTRY KHRONOS_APIENTRY
+#endif
+#define EGLAPIENTRYP EGLAPIENTRY*
+
+/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
+ * are aliases of window-system-dependent types, such as X Display * or
+ * Windows Device Context. They must be defined in platform-specific
+ * code below. The EGL-prefixed versions of Native*Type are the same
+ * types, renamed in EGL 1.3 so all types in the API start with "EGL".
+ *
+ * Khronos STRONGLY RECOMMENDS that you use the default definitions
+ * provided below, since these changes affect both binary and source
+ * portability of applications using EGL running on different EGL
+ * implementations.
+ */
+
+#if defined(EGL_NO_PLATFORM_SPECIFIC_TYPES)
+
+typedef void *EGLNativeDisplayType;
+typedef void *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
+#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+#include <windows.h>
+
+typedef HDC EGLNativeDisplayType;
+typedef HBITMAP EGLNativePixmapType;
+
+#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) /* Windows Desktop */
+typedef HWND EGLNativeWindowType;
+#else /* Windows Store */
+#include <inspectable.h>
+typedef IInspectable* EGLNativeWindowType;
+#endif
+
+#elif defined(__EMSCRIPTEN__)
+
+typedef int EGLNativeDisplayType;
+typedef int EGLNativePixmapType;
+typedef int EGLNativeWindowType;
+
+#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
+
+typedef int EGLNativeDisplayType;
+typedef void *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
+#elif defined(WL_EGL_PLATFORM)
+
+typedef struct wl_display *EGLNativeDisplayType;
+typedef struct wl_egl_pixmap *EGLNativePixmapType;
+typedef struct wl_egl_window *EGLNativeWindowType;
+
+#elif defined(__GBM__)
+
+typedef struct gbm_device *EGLNativeDisplayType;
+typedef struct gbm_bo *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
+#elif defined(__ANDROID__) || defined(ANDROID)
+
+struct ANativeWindow;
+struct egl_native_pixmap_t;
+
+typedef void* EGLNativeDisplayType;
+typedef struct egl_native_pixmap_t* EGLNativePixmapType;
+typedef struct ANativeWindow* EGLNativeWindowType;
+
+#elif defined(USE_OZONE)
+
+typedef intptr_t EGLNativeDisplayType;
+typedef intptr_t EGLNativePixmapType;
+typedef intptr_t EGLNativeWindowType;
+
+#elif defined(USE_X11)
+
+/* X11 (tentative) */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+typedef Display *EGLNativeDisplayType;
+typedef Pixmap EGLNativePixmapType;
+typedef Window EGLNativeWindowType;
+
+#elif defined(__unix__)
+
+typedef void *EGLNativeDisplayType;
+typedef khronos_uintptr_t EGLNativePixmapType;
+typedef khronos_uintptr_t EGLNativeWindowType;
+
+#elif defined(__APPLE__)
+
+typedef int EGLNativeDisplayType;
+typedef void *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
+#elif defined(__HAIKU__)
+
+#include <kernel/image.h>
+
+typedef void *EGLNativeDisplayType;
+typedef khronos_uintptr_t EGLNativePixmapType;
+typedef khronos_uintptr_t EGLNativeWindowType;
+
+#elif defined(__Fuchsia__)
+
+typedef void *EGLNativeDisplayType;
+typedef khronos_uintptr_t EGLNativePixmapType;
+typedef khronos_uintptr_t EGLNativeWindowType;
+
+#else
+#error "Platform not recognized"
+#endif
+
+/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
+typedef EGLNativeDisplayType NativeDisplayType;
+typedef EGLNativePixmapType NativePixmapType;
+typedef EGLNativeWindowType NativeWindowType;
+
+
+/* Define EGLint. This must be a signed integral type large enough to contain
+ * all legal attribute names and values passed into and out of EGL, whether
+ * their type is boolean, bitmask, enumerant (symbolic constant), integer,
+ * handle, or other. While in general a 32-bit integer will suffice, if
+ * handles are 64 bit types, then EGLint should be defined as a signed 64-bit
+ * integer type.
+ */
+typedef khronos_int32_t EGLint;
+
+
+/* C++ / C typecast macros for special EGL handle values */
+#if defined(__cplusplus)
+#define EGL_CAST(type, value) (static_cast<type>(value))
+#else
+#define EGL_CAST(type, value) ((type) (value))
+#endif
+
+#endif /* __eglplatform_h */
diff --git a/gfx/angle/checkout/include/GLES/gl.h b/gfx/angle/checkout/include/GLES/gl.h
new file mode 100644
index 0000000000..9f3ed3438a
--- /dev/null
+++ b/gfx/angle/checkout/include/GLES/gl.h
@@ -0,0 +1,743 @@
+#ifndef __gles1_gl_h_
+#define __gles1_gl_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2013-2018 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** https://github.com/KhronosGroup/OpenGL-Registry
+*/
+
+#include <GLES/glplatform.h>
+
+#ifndef GL_APIENTRYP
+#define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+/* Generated on date 20181204 */
+
+/* Generated C header for:
+ * API: gles1
+ * Profile: common
+ * Versions considered: .*
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: ^(GL_OES_read_format|GL_OES_compressed_paletted_texture|GL_OES_point_size_array|GL_OES_point_sprite)$
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef GL_VERSION_ES_CM_1_0
+#define GL_VERSION_ES_CM_1_0 1
+#include <KHR/khrplatform.h>
+typedef khronos_int8_t GLbyte;
+typedef khronos_float_t GLclampf;
+typedef khronos_int16_t GLshort;
+typedef khronos_uint16_t GLushort;
+typedef void GLvoid;
+typedef unsigned int GLenum;
+typedef khronos_float_t GLfloat;
+typedef khronos_int32_t GLfixed;
+typedef unsigned int GLuint;
+typedef khronos_ssize_t GLsizeiptr;
+typedef khronos_intptr_t GLintptr;
+typedef unsigned int GLbitfield;
+typedef int GLint;
+typedef khronos_uint8_t GLubyte;
+typedef unsigned char GLboolean;
+typedef int GLsizei;
+typedef khronos_int32_t GLclampx;
+#define GL_VERSION_ES_CL_1_0 1
+#define GL_VERSION_ES_CM_1_1 1
+#define GL_VERSION_ES_CL_1_1 1
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_FALSE 0
+#define GL_TRUE 1
+#define GL_POINTS 0x0000
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_STRIP 0x0003
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_NEVER 0x0200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+#define GL_ZERO 0
+#define GL_ONE 1
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_CLIP_PLANE0 0x3000
+#define GL_CLIP_PLANE1 0x3001
+#define GL_CLIP_PLANE2 0x3002
+#define GL_CLIP_PLANE3 0x3003
+#define GL_CLIP_PLANE4 0x3004
+#define GL_CLIP_PLANE5 0x3005
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_FOG 0x0B60
+#define GL_LIGHTING 0x0B50
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_CULL_FACE 0x0B44
+#define GL_ALPHA_TEST 0x0BC0
+#define GL_BLEND 0x0BE2
+#define GL_COLOR_LOGIC_OP 0x0BF2
+#define GL_DITHER 0x0BD0
+#define GL_STENCIL_TEST 0x0B90
+#define GL_DEPTH_TEST 0x0B71
+#define GL_POINT_SMOOTH 0x0B10
+#define GL_LINE_SMOOTH 0x0B20
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_COLOR_MATERIAL 0x0B57
+#define GL_NORMALIZE 0x0BA1
+#define GL_RESCALE_NORMAL 0x803A
+#define GL_VERTEX_ARRAY 0x8074
+#define GL_NORMAL_ARRAY 0x8075
+#define GL_COLOR_ARRAY 0x8076
+#define GL_TEXTURE_COORD_ARRAY 0x8078
+#define GL_MULTISAMPLE 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_NO_ERROR 0
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_EXP 0x0800
+#define GL_EXP2 0x0801
+#define GL_FOG_DENSITY 0x0B62
+#define GL_FOG_START 0x0B63
+#define GL_FOG_END 0x0B64
+#define GL_FOG_MODE 0x0B65
+#define GL_FOG_COLOR 0x0B66
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+#define GL_CURRENT_COLOR 0x0B00
+#define GL_CURRENT_NORMAL 0x0B02
+#define GL_CURRENT_TEXTURE_COORDS 0x0B03
+#define GL_POINT_SIZE 0x0B11
+#define GL_POINT_SIZE_MIN 0x8126
+#define GL_POINT_SIZE_MAX 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_POINT_DISTANCE_ATTENUATION 0x8129
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_LINE_WIDTH 0x0B21
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_SHADE_MODEL 0x0B54
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_MATRIX_MODE 0x0BA0
+#define GL_VIEWPORT 0x0BA2
+#define GL_MODELVIEW_STACK_DEPTH 0x0BA3
+#define GL_PROJECTION_STACK_DEPTH 0x0BA4
+#define GL_TEXTURE_STACK_DEPTH 0x0BA5
+#define GL_MODELVIEW_MATRIX 0x0BA6
+#define GL_PROJECTION_MATRIX 0x0BA7
+#define GL_TEXTURE_MATRIX 0x0BA8
+#define GL_ALPHA_TEST_FUNC 0x0BC1
+#define GL_ALPHA_TEST_REF 0x0BC2
+#define GL_BLEND_DST 0x0BE0
+#define GL_BLEND_SRC 0x0BE1
+#define GL_LOGIC_OP_MODE 0x0BF0
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_MAX_LIGHTS 0x0D31
+#define GL_MAX_CLIP_PLANES 0x0D32
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36
+#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38
+#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_MAX_TEXTURE_UNITS 0x84E2
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_ALPHA_BITS 0x0D55
+#define GL_DEPTH_BITS 0x0D56
+#define GL_STENCIL_BITS 0x0D57
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_VERTEX_ARRAY_SIZE 0x807A
+#define GL_VERTEX_ARRAY_TYPE 0x807B
+#define GL_VERTEX_ARRAY_STRIDE 0x807C
+#define GL_NORMAL_ARRAY_TYPE 0x807E
+#define GL_NORMAL_ARRAY_STRIDE 0x807F
+#define GL_COLOR_ARRAY_SIZE 0x8081
+#define GL_COLOR_ARRAY_TYPE 0x8082
+#define GL_COLOR_ARRAY_STRIDE 0x8083
+#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A
+#define GL_VERTEX_ARRAY_POINTER 0x808E
+#define GL_NORMAL_ARRAY_POINTER 0x808F
+#define GL_COLOR_ARRAY_POINTER 0x8090
+#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50
+#define GL_POINT_SMOOTH_HINT 0x0C51
+#define GL_LINE_SMOOTH_HINT 0x0C52
+#define GL_FOG_HINT 0x0C54
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_LIGHT_MODEL_AMBIENT 0x0B53
+#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52
+#define GL_AMBIENT 0x1200
+#define GL_DIFFUSE 0x1201
+#define GL_SPECULAR 0x1202
+#define GL_POSITION 0x1203
+#define GL_SPOT_DIRECTION 0x1204
+#define GL_SPOT_EXPONENT 0x1205
+#define GL_SPOT_CUTOFF 0x1206
+#define GL_CONSTANT_ATTENUATION 0x1207
+#define GL_LINEAR_ATTENUATION 0x1208
+#define GL_QUADRATIC_ATTENUATION 0x1209
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_FLOAT 0x1406
+#define GL_FIXED 0x140C
+#define GL_CLEAR 0x1500
+#define GL_AND 0x1501
+#define GL_AND_REVERSE 0x1502
+#define GL_COPY 0x1503
+#define GL_AND_INVERTED 0x1504
+#define GL_NOOP 0x1505
+#define GL_XOR 0x1506
+#define GL_OR 0x1507
+#define GL_NOR 0x1508
+#define GL_EQUIV 0x1509
+#define GL_INVERT 0x150A
+#define GL_OR_REVERSE 0x150B
+#define GL_COPY_INVERTED 0x150C
+#define GL_OR_INVERTED 0x150D
+#define GL_NAND 0x150E
+#define GL_SET 0x150F
+#define GL_EMISSION 0x1600
+#define GL_SHININESS 0x1601
+#define GL_AMBIENT_AND_DIFFUSE 0x1602
+#define GL_MODELVIEW 0x1700
+#define GL_PROJECTION 0x1701
+#define GL_TEXTURE 0x1702
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_FLAT 0x1D00
+#define GL_SMOOTH 0x1D01
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+#define GL_MODULATE 0x2100
+#define GL_DECAL 0x2101
+#define GL_ADD 0x0104
+#define GL_TEXTURE_ENV_MODE 0x2200
+#define GL_TEXTURE_ENV_COLOR 0x2201
+#define GL_TEXTURE_ENV 0x2300
+#define GL_NEAREST 0x2600
+#define GL_LINEAR 0x2601
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_GENERATE_MIPMAP 0x8191
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#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_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_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_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1
+#define GL_REPEAT 0x2901
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_LIGHT0 0x4000
+#define GL_LIGHT1 0x4001
+#define GL_LIGHT2 0x4002
+#define GL_LIGHT3 0x4003
+#define GL_LIGHT4 0x4004
+#define GL_LIGHT5 0x4005
+#define GL_LIGHT6 0x4006
+#define GL_LIGHT7 0x4007
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+#define GL_STATIC_DRAW 0x88E4
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_SUBTRACT 0x84E7
+#define GL_COMBINE 0x8570
+#define GL_COMBINE_RGB 0x8571
+#define GL_COMBINE_ALPHA 0x8572
+#define GL_RGB_SCALE 0x8573
+#define GL_ADD_SIGNED 0x8574
+#define GL_INTERPOLATE 0x8575
+#define GL_CONSTANT 0x8576
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PREVIOUS 0x8578
+#define GL_OPERAND0_RGB 0x8590
+#define GL_OPERAND1_RGB 0x8591
+#define GL_OPERAND2_RGB 0x8592
+#define GL_OPERAND0_ALPHA 0x8598
+#define GL_OPERAND1_ALPHA 0x8599
+#define GL_OPERAND2_ALPHA 0x859A
+#define GL_ALPHA_SCALE 0x0D1C
+#define GL_SRC0_RGB 0x8580
+#define GL_SRC1_RGB 0x8581
+#define GL_SRC2_RGB 0x8582
+#define GL_SRC0_ALPHA 0x8588
+#define GL_SRC1_ALPHA 0x8589
+#define GL_SRC2_ALPHA 0x858A
+#define GL_DOT3_RGB 0x86AE
+#define GL_DOT3_RGBA 0x86AF
+typedef void (GL_APIENTRYP PFNGLALPHAFUNCPROC) (GLenum func, GLfloat ref);
+typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);
+typedef void (GL_APIENTRYP PFNGLCLIPPLANEFPROC) (GLenum p, const GLfloat *eqn);
+typedef void (GL_APIENTRYP PFNGLCOLOR4FPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLFOGFPROC) (GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLFOGFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLFRUSTUMFPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLGETCLIPPLANEFPROC) (GLenum plane, GLfloat *equation);
+typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data);
+typedef void (GL_APIENTRYP PFNGLGETLIGHTFVPROC) (GLenum light, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETMATERIALFVPROC) (GLenum face, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXENVFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLLIGHTMODELFPROC) (GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLLIGHTMODELFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLLIGHTFPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLLIGHTFVPROC) (GLenum light, GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width);
+typedef void (GL_APIENTRYP PFNGLLOADMATRIXFPROC) (const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATERIALFPROC) (GLenum face, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLMATERIALFVPROC) (GLenum face, GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLMULTMATRIXFPROC) (const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (GL_APIENTRYP PFNGLNORMAL3FPROC) (GLfloat nx, GLfloat ny, GLfloat nz);
+typedef void (GL_APIENTRYP PFNGLORTHOFPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLPOINTSIZEPROC) (GLfloat size);
+typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);
+typedef void (GL_APIENTRYP PFNGLROTATEFPROC) (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLSCALEFPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLTEXENVFPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLTEXENVFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLTRANSLATEFPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GL_APIENTRYP PFNGLALPHAFUNCXPROC) (GLenum func, GLfixed ref);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
+typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
+typedef void (GL_APIENTRYP PFNGLCLEARCOLORXPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+typedef void (GL_APIENTRYP PFNGLCLEARDEPTHXPROC) (GLfixed depth);
+typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);
+typedef void (GL_APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GL_APIENTRYP PFNGLCLIPPLANEXPROC) (GLenum plane, const GLfixed *equation);
+typedef void (GL_APIENTRYP PFNGLCOLOR4UBPROC) (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+typedef void (GL_APIENTRYP PFNGLCOLOR4XPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+typedef void (GL_APIENTRYP PFNGLCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
+typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);
+typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEXPROC) (GLfixed n, GLfixed f);
+typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLDISABLECLIENTSTATEPROC) (GLenum array);
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
+typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLENABLECLIENTSTATEPROC) (GLenum array);
+typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFOGXPROC) (GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLFOGXVPROC) (GLenum pname, const GLfixed *param);
+typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLFRUSTUMXPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETCLIPPLANEXPROC) (GLenum plane, GLfixed *equation);
+typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
+typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void);
+typedef void (GL_APIENTRYP PFNGLGETFIXEDVPROC) (GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
+typedef void (GL_APIENTRYP PFNGLGETLIGHTXVPROC) (GLenum light, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETMATERIALXVPROC) (GLenum face, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETPOINTERVPROC) (GLenum pname, void **params);
+typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
+typedef void (GL_APIENTRYP PFNGLGETTEXENVIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXENVXVPROC) (GLenum target, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERXVPROC) (GLenum target, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode);
+typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
+typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture);
+typedef void (GL_APIENTRYP PFNGLLIGHTMODELXPROC) (GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLLIGHTMODELXVPROC) (GLenum pname, const GLfixed *param);
+typedef void (GL_APIENTRYP PFNGLLIGHTXPROC) (GLenum light, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLLIGHTXVPROC) (GLenum light, GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLLINEWIDTHXPROC) (GLfixed width);
+typedef void (GL_APIENTRYP PFNGLLOADIDENTITYPROC) (void);
+typedef void (GL_APIENTRYP PFNGLLOADMATRIXXPROC) (const GLfixed *m);
+typedef void (GL_APIENTRYP PFNGLLOGICOPPROC) (GLenum opcode);
+typedef void (GL_APIENTRYP PFNGLMATERIALXPROC) (GLenum face, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLMATERIALXVPROC) (GLenum face, GLenum pname, const GLfixed *param);
+typedef void (GL_APIENTRYP PFNGLMATRIXMODEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLMULTMATRIXXPROC) (const GLfixed *m);
+typedef void (GL_APIENTRYP PFNGLMULTITEXCOORD4XPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+typedef void (GL_APIENTRYP PFNGLNORMAL3XPROC) (GLfixed nx, GLfixed ny, GLfixed nz);
+typedef void (GL_APIENTRYP PFNGLNORMALPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLORTHOXPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
+typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLPOINTPARAMETERXPROC) (GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLPOINTPARAMETERXVPROC) (GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLPOINTSIZEXPROC) (GLfixed size);
+typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETXPROC) (GLfixed factor, GLfixed units);
+typedef void (GL_APIENTRYP PFNGLPOPMATRIXPROC) (void);
+typedef void (GL_APIENTRYP PFNGLPUSHMATRIXPROC) (void);
+typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+typedef void (GL_APIENTRYP PFNGLROTATEXPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert);
+typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEXPROC) (GLclampx value, GLboolean invert);
+typedef void (GL_APIENTRYP PFNGLSCALEXPROC) (GLfixed x, GLfixed y, GLfixed z);
+typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSHADEMODELPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
+typedef void (GL_APIENTRYP PFNGLTEXCOORDPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLTEXENVIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLTEXENVXPROC) (GLenum target, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLTEXENVIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXENVXVPROC) (GLenum target, GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERXPROC) (GLenum target, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERXVPROC) (GLenum target, GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTRANSLATEXPROC) (GLfixed x, GLfixed y, GLfixed z);
+typedef void (GL_APIENTRYP PFNGLVERTEXPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+#if GL_GLES_PROTOTYPES
+GL_API void GL_APIENTRY glAlphaFunc (GLenum func, GLfloat ref);
+GL_API void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_API void GL_APIENTRY glClearDepthf (GLfloat d);
+GL_API void GL_APIENTRY glClipPlanef (GLenum p, const GLfloat *eqn);
+GL_API void GL_APIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_API void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f);
+GL_API void GL_APIENTRY glFogf (GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glFogfv (GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glFrustumf (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+GL_API void GL_APIENTRY glGetClipPlanef (GLenum plane, GLfloat *equation);
+GL_API void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data);
+GL_API void GL_APIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params);
+GL_API void GL_APIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params);
+GL_API void GL_APIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params);
+GL_API void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GL_API void GL_APIENTRY glLightModelf (GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glLightModelfv (GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glLightf (GLenum light, GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glLineWidth (GLfloat width);
+GL_API void GL_APIENTRY glLoadMatrixf (const GLfloat *m);
+GL_API void GL_APIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glMultMatrixf (const GLfloat *m);
+GL_API void GL_APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GL_API void GL_APIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz);
+GL_API void GL_APIENTRY glOrthof (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+GL_API void GL_APIENTRY glPointParameterf (GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glPointSize (GLfloat size);
+GL_API void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GL_API void GL_APIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+GL_API void GL_APIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z);
+GL_API void GL_APIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z);
+GL_API void GL_APIENTRY glActiveTexture (GLenum texture);
+GL_API void GL_APIENTRY glAlphaFuncx (GLenum func, GLfixed ref);
+GL_API void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GL_API void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
+GL_API void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GL_API void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+GL_API void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+GL_API void GL_APIENTRY glClear (GLbitfield mask);
+GL_API void GL_APIENTRY glClearColorx (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+GL_API void GL_APIENTRY glClearDepthx (GLfixed depth);
+GL_API void GL_APIENTRY glClearStencil (GLint s);
+GL_API void GL_APIENTRY glClientActiveTexture (GLenum texture);
+GL_API void GL_APIENTRY glClipPlanex (GLenum plane, const GLfixed *equation);
+GL_API void GL_APIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+GL_API void GL_APIENTRY glColor4x (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+GL_API void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GL_API void GL_APIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer);
+GL_API void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+GL_API void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+GL_API void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GL_API void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glCullFace (GLenum mode);
+GL_API void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
+GL_API void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
+GL_API void GL_APIENTRY glDepthFunc (GLenum func);
+GL_API void GL_APIENTRY glDepthMask (GLboolean flag);
+GL_API void GL_APIENTRY glDepthRangex (GLfixed n, GLfixed f);
+GL_API void GL_APIENTRY glDisable (GLenum cap);
+GL_API void GL_APIENTRY glDisableClientState (GLenum array);
+GL_API void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GL_API void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
+GL_API void GL_APIENTRY glEnable (GLenum cap);
+GL_API void GL_APIENTRY glEnableClientState (GLenum array);
+GL_API void GL_APIENTRY glFinish (void);
+GL_API void GL_APIENTRY glFlush (void);
+GL_API void GL_APIENTRY glFogx (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glFogxv (GLenum pname, const GLfixed *param);
+GL_API void GL_APIENTRY glFrontFace (GLenum mode);
+GL_API void GL_APIENTRY glFrustumx (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
+GL_API void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);
+GL_API void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glGetClipPlanex (GLenum plane, GLfixed *equation);
+GL_API void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
+GL_API void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures);
+GL_API GLenum GL_APIENTRY glGetError (void);
+GL_API void GL_APIENTRY glGetFixedv (GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data);
+GL_API void GL_APIENTRY glGetLightxv (GLenum light, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetMaterialxv (GLenum face, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetPointerv (GLenum pname, void **params);
+GL_API const GLubyte *GL_APIENTRY glGetString (GLenum name);
+GL_API void GL_APIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glGetTexEnvxv (GLenum target, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glGetTexParameterxv (GLenum target, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glHint (GLenum target, GLenum mode);
+GL_API GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
+GL_API GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
+GL_API GLboolean GL_APIENTRY glIsTexture (GLuint texture);
+GL_API void GL_APIENTRY glLightModelx (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glLightModelxv (GLenum pname, const GLfixed *param);
+GL_API void GL_APIENTRY glLightx (GLenum light, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glLightxv (GLenum light, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glLineWidthx (GLfixed width);
+GL_API void GL_APIENTRY glLoadIdentity (void);
+GL_API void GL_APIENTRY glLoadMatrixx (const GLfixed *m);
+GL_API void GL_APIENTRY glLogicOp (GLenum opcode);
+GL_API void GL_APIENTRY glMaterialx (GLenum face, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glMaterialxv (GLenum face, GLenum pname, const GLfixed *param);
+GL_API void GL_APIENTRY glMatrixMode (GLenum mode);
+GL_API void GL_APIENTRY glMultMatrixx (const GLfixed *m);
+GL_API void GL_APIENTRY glMultiTexCoord4x (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+GL_API void GL_APIENTRY glNormal3x (GLfixed nx, GLfixed ny, GLfixed nz);
+GL_API void GL_APIENTRY glNormalPointer (GLenum type, GLsizei stride, const void *pointer);
+GL_API void GL_APIENTRY glOrthox (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
+GL_API void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
+GL_API void GL_APIENTRY glPointParameterx (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glPointParameterxv (GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glPointSizex (GLfixed size);
+GL_API void GL_APIENTRY glPolygonOffsetx (GLfixed factor, GLfixed units);
+GL_API void GL_APIENTRY glPopMatrix (void);
+GL_API void GL_APIENTRY glPushMatrix (void);
+GL_API void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+GL_API void GL_APIENTRY glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+GL_API void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);
+GL_API void GL_APIENTRY glSampleCoveragex (GLclampx value, GLboolean invert);
+GL_API void GL_APIENTRY glScalex (GLfixed x, GLfixed y, GLfixed z);
+GL_API void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glShadeModel (GLenum mode);
+GL_API void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GL_API void GL_APIENTRY glStencilMask (GLuint mask);
+GL_API void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GL_API void GL_APIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const void *pointer);
+GL_API void GL_APIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param);
+GL_API void GL_APIENTRY glTexEnvx (GLenum target, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params);
+GL_API void GL_APIENTRY glTexEnvxv (GLenum target, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+GL_API void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GL_API void GL_APIENTRY glTexParameterx (GLenum target, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
+GL_API void GL_APIENTRY glTexParameterxv (GLenum target, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+GL_API void GL_APIENTRY glTranslatex (GLfixed x, GLfixed y, GLfixed z);
+GL_API void GL_APIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const void *pointer);
+GL_API void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_VERSION_ES_CM_1_0 */
+
+#ifndef GL_OES_compressed_paletted_texture
+#define GL_OES_compressed_paletted_texture 1
+#define GL_PALETTE4_RGB8_OES 0x8B90
+#define GL_PALETTE4_RGBA8_OES 0x8B91
+#define GL_PALETTE4_R5_G6_B5_OES 0x8B92
+#define GL_PALETTE4_RGBA4_OES 0x8B93
+#define GL_PALETTE4_RGB5_A1_OES 0x8B94
+#define GL_PALETTE8_RGB8_OES 0x8B95
+#define GL_PALETTE8_RGBA8_OES 0x8B96
+#define GL_PALETTE8_R5_G6_B5_OES 0x8B97
+#define GL_PALETTE8_RGBA4_OES 0x8B98
+#define GL_PALETTE8_RGB5_A1_OES 0x8B99
+#endif /* GL_OES_compressed_paletted_texture */
+
+#ifndef GL_OES_point_size_array
+#define GL_OES_point_size_array 1
+#define GL_POINT_SIZE_ARRAY_OES 0x8B9C
+#define GL_POINT_SIZE_ARRAY_TYPE_OES 0x898A
+#define GL_POINT_SIZE_ARRAY_STRIDE_OES 0x898B
+#define GL_POINT_SIZE_ARRAY_POINTER_OES 0x898C
+#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES 0x8B9F
+typedef void (GL_APIENTRYP PFNGLPOINTSIZEPOINTEROESPROC) (GLenum type, GLsizei stride, const void *pointer);
+#if GL_GLES_PROTOTYPES
+GL_API void GL_APIENTRY glPointSizePointerOES (GLenum type, GLsizei stride, const void *pointer);
+#endif
+#endif /* GL_OES_point_size_array */
+
+#ifndef GL_OES_point_sprite
+#define GL_OES_point_sprite 1
+#define GL_POINT_SPRITE_OES 0x8861
+#define GL_COORD_REPLACE_OES 0x8862
+#endif /* GL_OES_point_sprite */
+
+#ifndef GL_OES_read_format
+#define GL_OES_read_format 1
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B
+#endif /* GL_OES_read_format */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/include/GLES/glext.h b/gfx/angle/checkout/include/GLES/glext.h
new file mode 100644
index 0000000000..d8933e37d5
--- /dev/null
+++ b/gfx/angle/checkout/include/GLES/glext.h
@@ -0,0 +1,962 @@
+#ifndef __glext_h_
+#define __glext_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2013-2017 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** https://github.com/KhronosGroup/OpenGL-Registry
+*/
+
+#ifndef GL_APIENTRYP
+#define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+/* Generated on date 20171212 */
+
+/* Generated C header for:
+ * API: gles1
+ * Profile: common
+ * Versions considered: .*
+ * Versions emitted: _nomatch_^
+ * Default extensions included: gles1
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: ^(GL_OES_read_format|GL_OES_compressed_paletted_texture|GL_OES_point_size_array|GL_OES_point_sprite)$
+ */
+
+#ifndef GL_OES_EGL_image
+#define GL_OES_EGL_image 1
+typedef void *GLeglImageOES;
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image);
+GL_API void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image);
+#endif
+#endif /* GL_OES_EGL_image */
+
+#ifndef GL_OES_blend_equation_separate
+#define GL_OES_blend_equation_separate 1
+#define GL_BLEND_EQUATION_RGB_OES 0x8009
+#define GL_BLEND_EQUATION_ALPHA_OES 0x883D
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEOESPROC) (GLenum modeRGB, GLenum modeAlpha);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glBlendEquationSeparateOES (GLenum modeRGB, GLenum modeAlpha);
+#endif
+#endif /* GL_OES_blend_equation_separate */
+
+#ifndef GL_OES_blend_func_separate
+#define GL_OES_blend_func_separate 1
+#define GL_BLEND_DST_RGB_OES 0x80C8
+#define GL_BLEND_SRC_RGB_OES 0x80C9
+#define GL_BLEND_DST_ALPHA_OES 0x80CA
+#define GL_BLEND_SRC_ALPHA_OES 0x80CB
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEOESPROC) (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glBlendFuncSeparateOES (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+#endif /* GL_OES_blend_func_separate */
+
+#ifndef GL_OES_blend_subtract
+#define GL_OES_blend_subtract 1
+#define GL_BLEND_EQUATION_OES 0x8009
+#define GL_FUNC_ADD_OES 0x8006
+#define GL_FUNC_SUBTRACT_OES 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT_OES 0x800B
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONOESPROC) (GLenum mode);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glBlendEquationOES (GLenum mode);
+#endif
+#endif /* GL_OES_blend_subtract */
+
+#ifndef GL_OES_byte_coordinates
+#define GL_OES_byte_coordinates 1
+#endif /* GL_OES_byte_coordinates */
+
+#ifndef GL_OES_compressed_ETC1_RGB8_sub_texture
+#define GL_OES_compressed_ETC1_RGB8_sub_texture 1
+#endif /* GL_OES_compressed_ETC1_RGB8_sub_texture */
+
+#ifndef GL_OES_compressed_ETC1_RGB8_texture
+#define GL_OES_compressed_ETC1_RGB8_texture 1
+#define GL_ETC1_RGB8_OES 0x8D64
+#endif /* GL_OES_compressed_ETC1_RGB8_texture */
+
+#ifndef GL_OES_depth24
+#define GL_OES_depth24 1
+#define GL_DEPTH_COMPONENT24_OES 0x81A6
+#endif /* GL_OES_depth24 */
+
+#ifndef GL_OES_depth32
+#define GL_OES_depth32 1
+#define GL_DEPTH_COMPONENT32_OES 0x81A7
+#endif /* GL_OES_depth32 */
+
+#ifndef GL_OES_draw_texture
+#define GL_OES_draw_texture 1
+#define GL_TEXTURE_CROP_RECT_OES 0x8B9D
+typedef void (GL_APIENTRYP PFNGLDRAWTEXSOESPROC) (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXIOESPROC) (GLint x, GLint y, GLint z, GLint width, GLint height);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXXOESPROC) (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXSVOESPROC) (const GLshort *coords);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXIVOESPROC) (const GLint *coords);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXXVOESPROC) (const GLfixed *coords);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXFOESPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXFVOESPROC) (const GLfloat *coords);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glDrawTexsOES (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
+GL_API void GL_APIENTRY glDrawTexiOES (GLint x, GLint y, GLint z, GLint width, GLint height);
+GL_API void GL_APIENTRY glDrawTexxOES (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
+GL_API void GL_APIENTRY glDrawTexsvOES (const GLshort *coords);
+GL_API void GL_APIENTRY glDrawTexivOES (const GLint *coords);
+GL_API void GL_APIENTRY glDrawTexxvOES (const GLfixed *coords);
+GL_API void GL_APIENTRY glDrawTexfOES (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+GL_API void GL_APIENTRY glDrawTexfvOES (const GLfloat *coords);
+#endif
+#endif /* GL_OES_draw_texture */
+
+#ifndef GL_OES_element_index_uint
+#define GL_OES_element_index_uint 1
+#define GL_UNSIGNED_INT 0x1405
+#endif /* GL_OES_element_index_uint */
+
+#ifndef GL_OES_extended_matrix_palette
+#define GL_OES_extended_matrix_palette 1
+#endif /* GL_OES_extended_matrix_palette */
+
+#ifndef GL_OES_fbo_render_mipmap
+#define GL_OES_fbo_render_mipmap 1
+#endif /* GL_OES_fbo_render_mipmap */
+
+#ifndef GL_OES_fixed_point
+#define GL_OES_fixed_point 1
+#define GL_FIXED_OES 0x140C
+typedef void (GL_APIENTRYP PFNGLALPHAFUNCXOESPROC) (GLenum func, GLfixed ref);
+typedef void (GL_APIENTRYP PFNGLCLEARCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+typedef void (GL_APIENTRYP PFNGLCLEARDEPTHXOESPROC) (GLfixed depth);
+typedef void (GL_APIENTRYP PFNGLCLIPPLANEXOESPROC) (GLenum plane, const GLfixed *equation);
+typedef void (GL_APIENTRYP PFNGLCOLOR4XOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEXOESPROC) (GLfixed n, GLfixed f);
+typedef void (GL_APIENTRYP PFNGLFOGXOESPROC) (GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLFOGXVOESPROC) (GLenum pname, const GLfixed *param);
+typedef void (GL_APIENTRYP PFNGLFRUSTUMXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
+typedef void (GL_APIENTRYP PFNGLGETCLIPPLANEXOESPROC) (GLenum plane, GLfixed *equation);
+typedef void (GL_APIENTRYP PFNGLGETFIXEDVOESPROC) (GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXENVXVOESPROC) (GLenum target, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLLIGHTMODELXOESPROC) (GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLLIGHTMODELXVOESPROC) (GLenum pname, const GLfixed *param);
+typedef void (GL_APIENTRYP PFNGLLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLLIGHTXVOESPROC) (GLenum light, GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLLINEWIDTHXOESPROC) (GLfixed width);
+typedef void (GL_APIENTRYP PFNGLLOADMATRIXXOESPROC) (const GLfixed *m);
+typedef void (GL_APIENTRYP PFNGLMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLMATERIALXVOESPROC) (GLenum face, GLenum pname, const GLfixed *param);
+typedef void (GL_APIENTRYP PFNGLMULTMATRIXXOESPROC) (const GLfixed *m);
+typedef void (GL_APIENTRYP PFNGLMULTITEXCOORD4XOESPROC) (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+typedef void (GL_APIENTRYP PFNGLNORMAL3XOESPROC) (GLfixed nx, GLfixed ny, GLfixed nz);
+typedef void (GL_APIENTRYP PFNGLORTHOXOESPROC) (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
+typedef void (GL_APIENTRYP PFNGLPOINTPARAMETERXVOESPROC) (GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLPOINTSIZEXOESPROC) (GLfixed size);
+typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETXOESPROC) (GLfixed factor, GLfixed units);
+typedef void (GL_APIENTRYP PFNGLROTATEXOESPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+typedef void (GL_APIENTRYP PFNGLSCALEXOESPROC) (GLfixed x, GLfixed y, GLfixed z);
+typedef void (GL_APIENTRYP PFNGLTEXENVXOESPROC) (GLenum target, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLTEXENVXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLTRANSLATEXOESPROC) (GLfixed x, GLfixed y, GLfixed z);
+typedef void (GL_APIENTRYP PFNGLGETLIGHTXVOESPROC) (GLenum light, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETMATERIALXVOESPROC) (GLenum face, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLPOINTPARAMETERXOESPROC) (GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEXOESPROC) (GLclampx value, GLboolean invert);
+typedef void (GL_APIENTRYP PFNGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLTEXGENXOESPROC) (GLenum coord, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLTEXGENXVOESPROC) (GLenum coord, GLenum pname, const GLfixed *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glAlphaFuncxOES (GLenum func, GLfixed ref);
+GL_API void GL_APIENTRY glClearColorxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+GL_API void GL_APIENTRY glClearDepthxOES (GLfixed depth);
+GL_API void GL_APIENTRY glClipPlanexOES (GLenum plane, const GLfixed *equation);
+GL_API void GL_APIENTRY glColor4xOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+GL_API void GL_APIENTRY glDepthRangexOES (GLfixed n, GLfixed f);
+GL_API void GL_APIENTRY glFogxOES (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glFogxvOES (GLenum pname, const GLfixed *param);
+GL_API void GL_APIENTRY glFrustumxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
+GL_API void GL_APIENTRY glGetClipPlanexOES (GLenum plane, GLfixed *equation);
+GL_API void GL_APIENTRY glGetFixedvOES (GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetTexEnvxvOES (GLenum target, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetTexParameterxvOES (GLenum target, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glLightModelxOES (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glLightModelxvOES (GLenum pname, const GLfixed *param);
+GL_API void GL_APIENTRY glLightxOES (GLenum light, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glLightxvOES (GLenum light, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glLineWidthxOES (GLfixed width);
+GL_API void GL_APIENTRY glLoadMatrixxOES (const GLfixed *m);
+GL_API void GL_APIENTRY glMaterialxOES (GLenum face, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glMaterialxvOES (GLenum face, GLenum pname, const GLfixed *param);
+GL_API void GL_APIENTRY glMultMatrixxOES (const GLfixed *m);
+GL_API void GL_APIENTRY glMultiTexCoord4xOES (GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+GL_API void GL_APIENTRY glNormal3xOES (GLfixed nx, GLfixed ny, GLfixed nz);
+GL_API void GL_APIENTRY glOrthoxOES (GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
+GL_API void GL_APIENTRY glPointParameterxvOES (GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glPointSizexOES (GLfixed size);
+GL_API void GL_APIENTRY glPolygonOffsetxOES (GLfixed factor, GLfixed units);
+GL_API void GL_APIENTRY glRotatexOES (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+GL_API void GL_APIENTRY glScalexOES (GLfixed x, GLfixed y, GLfixed z);
+GL_API void GL_APIENTRY glTexEnvxOES (GLenum target, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glTexEnvxvOES (GLenum target, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glTexParameterxOES (GLenum target, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glTexParameterxvOES (GLenum target, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glTranslatexOES (GLfixed x, GLfixed y, GLfixed z);
+GL_API void GL_APIENTRY glGetLightxvOES (GLenum light, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetMaterialxvOES (GLenum face, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glPointParameterxOES (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glSampleCoveragexOES (GLclampx value, GLboolean invert);
+GL_API void GL_APIENTRY glGetTexGenxvOES (GLenum coord, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glTexGenxOES (GLenum coord, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glTexGenxvOES (GLenum coord, GLenum pname, const GLfixed *params);
+#endif
+#endif /* GL_OES_fixed_point */
+
+#ifndef GL_OES_framebuffer_object
+#define GL_OES_framebuffer_object 1
+#define GL_NONE_OES 0
+#define GL_FRAMEBUFFER_OES 0x8D40
+#define GL_RENDERBUFFER_OES 0x8D41
+#define GL_RGBA4_OES 0x8056
+#define GL_RGB5_A1_OES 0x8057
+#define GL_RGB565_OES 0x8D62
+#define GL_DEPTH_COMPONENT16_OES 0x81A5
+#define GL_RENDERBUFFER_WIDTH_OES 0x8D42
+#define GL_RENDERBUFFER_HEIGHT_OES 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_OES 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE_OES 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE_OES 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE_OES 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE_OES 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE_OES 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE_OES 0x8D55
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES 0x8CD3
+#define GL_COLOR_ATTACHMENT0_OES 0x8CE0
+#define GL_DEPTH_ATTACHMENT_OES 0x8D00
+#define GL_STENCIL_ATTACHMENT_OES 0x8D20
+#define GL_FRAMEBUFFER_COMPLETE_OES 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES 0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES 0x8CDA
+#define GL_FRAMEBUFFER_UNSUPPORTED_OES 0x8CDD
+#define GL_FRAMEBUFFER_BINDING_OES 0x8CA6
+#define GL_RENDERBUFFER_BINDING_OES 0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE_OES 0x84E8
+#define GL_INVALID_FRAMEBUFFER_OPERATION_OES 0x0506
+typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFEROESPROC) (GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFEROESPROC) (GLenum target, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSOESPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSOESPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVOESPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFEROESPROC) (GLuint framebuffer);
+typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFEROESPROC) (GLenum target, GLuint framebuffer);
+typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSOESPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSOESPROC) (GLsizei n, GLuint *framebuffers);
+typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSOESPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEROESPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPOESPROC) (GLenum target);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API GLboolean GL_APIENTRY glIsRenderbufferOES (GLuint renderbuffer);
+GL_API void GL_APIENTRY glBindRenderbufferOES (GLenum target, GLuint renderbuffer);
+GL_API void GL_APIENTRY glDeleteRenderbuffersOES (GLsizei n, const GLuint *renderbuffers);
+GL_API void GL_APIENTRY glGenRenderbuffersOES (GLsizei n, GLuint *renderbuffers);
+GL_API void GL_APIENTRY glRenderbufferStorageOES (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glGetRenderbufferParameterivOES (GLenum target, GLenum pname, GLint *params);
+GL_API GLboolean GL_APIENTRY glIsFramebufferOES (GLuint framebuffer);
+GL_API void GL_APIENTRY glBindFramebufferOES (GLenum target, GLuint framebuffer);
+GL_API void GL_APIENTRY glDeleteFramebuffersOES (GLsizei n, const GLuint *framebuffers);
+GL_API void GL_APIENTRY glGenFramebuffersOES (GLsizei n, GLuint *framebuffers);
+GL_API GLenum GL_APIENTRY glCheckFramebufferStatusOES (GLenum target);
+GL_API void GL_APIENTRY glFramebufferRenderbufferOES (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_API void GL_APIENTRY glFramebufferTexture2DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_API void GL_APIENTRY glGetFramebufferAttachmentParameterivOES (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glGenerateMipmapOES (GLenum target);
+#endif
+#endif /* GL_OES_framebuffer_object */
+
+#ifndef GL_OES_mapbuffer
+#define GL_OES_mapbuffer 1
+#define GL_WRITE_ONLY_OES 0x88B9
+#define GL_BUFFER_ACCESS_OES 0x88BB
+#define GL_BUFFER_MAPPED_OES 0x88BC
+#define GL_BUFFER_MAP_POINTER_OES 0x88BD
+typedef void *(GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access);
+typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void **params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void *GL_APIENTRY glMapBufferOES (GLenum target, GLenum access);
+GL_API GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target);
+GL_API void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, void **params);
+#endif
+#endif /* GL_OES_mapbuffer */
+
+#ifndef GL_OES_matrix_get
+#define GL_OES_matrix_get 1
+#define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES 0x898D
+#define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES 0x898E
+#define GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES 0x898F
+#endif /* GL_OES_matrix_get */
+
+#ifndef GL_OES_matrix_palette
+#define GL_OES_matrix_palette 1
+#define GL_MAX_VERTEX_UNITS_OES 0x86A4
+#define GL_MAX_PALETTE_MATRICES_OES 0x8842
+#define GL_MATRIX_PALETTE_OES 0x8840
+#define GL_MATRIX_INDEX_ARRAY_OES 0x8844
+#define GL_WEIGHT_ARRAY_OES 0x86AD
+#define GL_CURRENT_PALETTE_MATRIX_OES 0x8843
+#define GL_MATRIX_INDEX_ARRAY_SIZE_OES 0x8846
+#define GL_MATRIX_INDEX_ARRAY_TYPE_OES 0x8847
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_OES 0x8848
+#define GL_MATRIX_INDEX_ARRAY_POINTER_OES 0x8849
+#define GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES 0x8B9E
+#define GL_WEIGHT_ARRAY_SIZE_OES 0x86AB
+#define GL_WEIGHT_ARRAY_TYPE_OES 0x86A9
+#define GL_WEIGHT_ARRAY_STRIDE_OES 0x86AA
+#define GL_WEIGHT_ARRAY_POINTER_OES 0x86AC
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_OES 0x889E
+typedef void (GL_APIENTRYP PFNGLCURRENTPALETTEMATRIXOESPROC) (GLuint matrixpaletteindex);
+typedef void (GL_APIENTRYP PFNGLLOADPALETTEFROMMODELVIEWMATRIXOESPROC) (void);
+typedef void (GL_APIENTRYP PFNGLMATRIXINDEXPOINTEROESPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLWEIGHTPOINTEROESPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glCurrentPaletteMatrixOES (GLuint matrixpaletteindex);
+GL_API void GL_APIENTRY glLoadPaletteFromModelViewMatrixOES (void);
+GL_API void GL_APIENTRY glMatrixIndexPointerOES (GLint size, GLenum type, GLsizei stride, const void *pointer);
+GL_API void GL_APIENTRY glWeightPointerOES (GLint size, GLenum type, GLsizei stride, const void *pointer);
+#endif
+#endif /* GL_OES_matrix_palette */
+
+#ifndef GL_OES_packed_depth_stencil
+#define GL_OES_packed_depth_stencil 1
+#define GL_DEPTH_STENCIL_OES 0x84F9
+#define GL_UNSIGNED_INT_24_8_OES 0x84FA
+#define GL_DEPTH24_STENCIL8_OES 0x88F0
+#endif /* GL_OES_packed_depth_stencil */
+
+#ifndef GL_OES_query_matrix
+#define GL_OES_query_matrix 1
+typedef GLbitfield (GL_APIENTRYP PFNGLQUERYMATRIXXOESPROC) (GLfixed *mantissa, GLint *exponent);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API GLbitfield GL_APIENTRY glQueryMatrixxOES (GLfixed *mantissa, GLint *exponent);
+#endif
+#endif /* GL_OES_query_matrix */
+
+#ifndef GL_OES_required_internalformat
+#define GL_OES_required_internalformat 1
+#define GL_ALPHA8_OES 0x803C
+#define GL_LUMINANCE4_ALPHA4_OES 0x8043
+#define GL_LUMINANCE8_ALPHA8_OES 0x8045
+#define GL_LUMINANCE8_OES 0x8040
+#define GL_RGB8_OES 0x8051
+#define GL_RGBA8_OES 0x8058
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB10_A2_EXT 0x8059
+#endif /* GL_OES_required_internalformat */
+
+#ifndef GL_OES_rgb8_rgba8
+#define GL_OES_rgb8_rgba8 1
+#endif /* GL_OES_rgb8_rgba8 */
+
+#ifndef GL_OES_single_precision
+#define GL_OES_single_precision 1
+typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFOESPROC) (GLclampf depth);
+typedef void (GL_APIENTRYP PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat *equation);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFOESPROC) (GLclampf n, GLclampf f);
+typedef void (GL_APIENTRYP PFNGLFRUSTUMFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLGETCLIPPLANEFOESPROC) (GLenum plane, GLfloat *equation);
+typedef void (GL_APIENTRYP PFNGLORTHOFOESPROC) (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glClearDepthfOES (GLclampf depth);
+GL_API void GL_APIENTRY glClipPlanefOES (GLenum plane, const GLfloat *equation);
+GL_API void GL_APIENTRY glDepthRangefOES (GLclampf n, GLclampf f);
+GL_API void GL_APIENTRY glFrustumfOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+GL_API void GL_APIENTRY glGetClipPlanefOES (GLenum plane, GLfloat *equation);
+GL_API void GL_APIENTRY glOrthofOES (GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+#endif
+#endif /* GL_OES_single_precision */
+
+#ifndef GL_OES_stencil1
+#define GL_OES_stencil1 1
+#define GL_STENCIL_INDEX1_OES 0x8D46
+#endif /* GL_OES_stencil1 */
+
+#ifndef GL_OES_stencil4
+#define GL_OES_stencil4 1
+#define GL_STENCIL_INDEX4_OES 0x8D47
+#endif /* GL_OES_stencil4 */
+
+#ifndef GL_OES_stencil8
+#define GL_OES_stencil8 1
+#define GL_STENCIL_INDEX8_OES 0x8D48
+#endif /* GL_OES_stencil8 */
+
+#ifndef GL_OES_stencil_wrap
+#define GL_OES_stencil_wrap 1
+#define GL_INCR_WRAP_OES 0x8507
+#define GL_DECR_WRAP_OES 0x8508
+#endif /* GL_OES_stencil_wrap */
+
+#ifndef GL_OES_surfaceless_context
+#define GL_OES_surfaceless_context 1
+#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219
+#endif /* GL_OES_surfaceless_context */
+
+#ifndef GL_OES_texture_cube_map
+#define GL_OES_texture_cube_map 1
+#define GL_NORMAL_MAP_OES 0x8511
+#define GL_REFLECTION_MAP_OES 0x8512
+#define GL_TEXTURE_CUBE_MAP_OES 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_OES 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES 0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES 0x851C
+#define GL_TEXTURE_GEN_MODE_OES 0x2500
+#define GL_TEXTURE_GEN_STR_OES 0x8D60
+typedef void (GL_APIENTRYP PFNGLTEXGENFOESPROC) (GLenum coord, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLTEXGENFVOESPROC) (GLenum coord, GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLTEXGENIOESPROC) (GLenum coord, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLTEXGENIVOESPROC) (GLenum coord, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXGENFVOESPROC) (GLenum coord, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXGENIVOESPROC) (GLenum coord, GLenum pname, GLint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glTexGenfOES (GLenum coord, GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glTexGenfvOES (GLenum coord, GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glTexGeniOES (GLenum coord, GLenum pname, GLint param);
+GL_API void GL_APIENTRY glTexGenivOES (GLenum coord, GLenum pname, const GLint *params);
+GL_API void GL_APIENTRY glGetTexGenfvOES (GLenum coord, GLenum pname, GLfloat *params);
+GL_API void GL_APIENTRY glGetTexGenivOES (GLenum coord, GLenum pname, GLint *params);
+#endif
+#endif /* GL_OES_texture_cube_map */
+
+#ifndef GL_OES_texture_env_crossbar
+#define GL_OES_texture_env_crossbar 1
+#endif /* GL_OES_texture_env_crossbar */
+
+#ifndef GL_OES_texture_mirrored_repeat
+#define GL_OES_texture_mirrored_repeat 1
+#define GL_MIRRORED_REPEAT_OES 0x8370
+#endif /* GL_OES_texture_mirrored_repeat */
+
+#ifndef GL_OES_texture_npot
+#define GL_OES_texture_npot 1
+#endif /* GL_OES_texture_npot */
+
+#ifndef GL_OES_vertex_array_object
+#define GL_OES_vertex_array_object 1
+#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5
+typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays);
+typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glBindVertexArrayOES (GLuint array);
+GL_API void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays);
+GL_API void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays);
+GL_API GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array);
+#endif
+#endif /* GL_OES_vertex_array_object */
+
+#ifndef GL_AMD_compressed_3DC_texture
+#define GL_AMD_compressed_3DC_texture 1
+#define GL_3DC_X_AMD 0x87F9
+#define GL_3DC_XY_AMD 0x87FA
+#endif /* GL_AMD_compressed_3DC_texture */
+
+#ifndef GL_AMD_compressed_ATC_texture
+#define GL_AMD_compressed_ATC_texture 1
+#define GL_ATC_RGB_AMD 0x8C92
+#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93
+#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
+#endif /* GL_AMD_compressed_ATC_texture */
+
+#ifndef GL_APPLE_copy_texture_levels
+#define GL_APPLE_copy_texture_levels 1
+typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glCopyTextureLevelsAPPLE (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount);
+#endif
+#endif /* GL_APPLE_copy_texture_levels */
+
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_APPLE_framebuffer_multisample 1
+#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56
+#define GL_MAX_SAMPLES_APPLE 0x8D57
+#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void);
+#endif
+#endif /* GL_APPLE_framebuffer_multisample */
+
+#ifndef GL_APPLE_sync
+#define GL_APPLE_sync 1
+typedef struct __GLsync *GLsync;
+typedef khronos_uint64_t GLuint64;
+typedef khronos_int64_t GLint64;
+#define GL_SYNC_OBJECT_APPLE 0x8A53
+#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111
+#define GL_OBJECT_TYPE_APPLE 0x9112
+#define GL_SYNC_CONDITION_APPLE 0x9113
+#define GL_SYNC_STATUS_APPLE 0x9114
+#define GL_SYNC_FLAGS_APPLE 0x9115
+#define GL_SYNC_FENCE_APPLE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117
+#define GL_UNSIGNALED_APPLE 0x9118
+#define GL_SIGNALED_APPLE 0x9119
+#define GL_ALREADY_SIGNALED_APPLE 0x911A
+#define GL_TIMEOUT_EXPIRED_APPLE 0x911B
+#define GL_CONDITION_SATISFIED_APPLE 0x911C
+#define GL_WAIT_FAILED_APPLE 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001
+#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull
+typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync);
+typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync);
+typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags);
+GL_API GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync);
+GL_API void GL_APIENTRY glDeleteSyncAPPLE (GLsync sync);
+GL_API GLenum GL_APIENTRY glClientWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_API void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_API void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params);
+GL_API void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif
+#endif /* GL_APPLE_sync */
+
+#ifndef GL_APPLE_texture_2D_limited_npot
+#define GL_APPLE_texture_2D_limited_npot 1
+#endif /* GL_APPLE_texture_2D_limited_npot */
+
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_APPLE_texture_format_BGRA8888 1
+#define GL_BGRA_EXT 0x80E1
+#define GL_BGRA8_EXT 0x93A1
+#endif /* GL_APPLE_texture_format_BGRA8888 */
+
+#ifndef GL_APPLE_texture_max_level
+#define GL_APPLE_texture_max_level 1
+#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D
+#endif /* GL_APPLE_texture_max_level */
+
+#ifndef GL_ARM_rgba8
+#define GL_ARM_rgba8 1
+#endif /* GL_ARM_rgba8 */
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#define GL_MIN_EXT 0x8007
+#define GL_MAX_EXT 0x8008
+#endif /* GL_EXT_blend_minmax */
+
+#ifndef GL_EXT_debug_marker
+#define GL_EXT_debug_marker 1
+typedef char GLchar;
+typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker);
+typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker);
+typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker);
+GL_API void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker);
+GL_API void GL_APIENTRY glPopGroupMarkerEXT (void);
+#endif
+#endif /* GL_EXT_debug_marker */
+
+#ifndef GL_EXT_discard_framebuffer
+#define GL_EXT_discard_framebuffer 1
+#define GL_COLOR_EXT 0x1800
+#define GL_DEPTH_EXT 0x1801
+#define GL_STENCIL_EXT 0x1802
+typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#endif
+#endif /* GL_EXT_discard_framebuffer */
+
+#ifndef GL_EXT_map_buffer_range
+#define GL_EXT_map_buffer_range 1
+#define GL_MAP_READ_BIT_EXT 0x0001
+#define GL_MAP_WRITE_BIT_EXT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020
+typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void *GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_API void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif
+#endif /* GL_EXT_map_buffer_range */
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GL_API void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount);
+#endif
+#endif /* GL_EXT_multi_draw_arrays */
+
+#ifndef GL_EXT_multisampled_render_to_texture
+#define GL_EXT_multisampled_render_to_texture 1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+#endif /* GL_EXT_multisampled_render_to_texture */
+
+#ifndef GL_EXT_read_format_bgra
+#define GL_EXT_read_format_bgra 1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366
+#endif /* GL_EXT_read_format_bgra */
+
+#ifndef GL_EXT_robustness
+#define GL_EXT_robustness 1
+#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255
+#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3
+#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256
+#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252
+#define GL_NO_RESET_NOTIFICATION_EXT 0x8261
+typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void);
+GL_API void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+GL_API void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+GL_API void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#endif
+#endif /* GL_EXT_robustness */
+
+#ifndef GL_EXT_sRGB
+#define GL_EXT_sRGB 1
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210
+#endif /* GL_EXT_sRGB */
+
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#endif /* GL_EXT_texture_compression_dxt1 */
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#endif /* GL_EXT_texture_filter_anisotropic */
+
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_EXT_texture_format_BGRA8888 1
+#endif /* GL_EXT_texture_format_BGRA8888 */
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_EXT_texture_lod_bias 1
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
+#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
+#endif /* GL_EXT_texture_lod_bias */
+
+#ifndef GL_EXT_texture_storage
+#define GL_EXT_texture_storage 1
+#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F
+#define GL_ALPHA8_EXT 0x803C
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_RGBA32F_EXT 0x8814
+#define GL_RGB32F_EXT 0x8815
+#define GL_ALPHA32F_EXT 0x8816
+#define GL_LUMINANCE32F_EXT 0x8818
+#define GL_LUMINANCE_ALPHA32F_EXT 0x8819
+#define GL_RGBA16F_EXT 0x881A
+#define GL_RGB16F_EXT 0x881B
+#define GL_ALPHA16F_EXT 0x881C
+#define GL_LUMINANCE16F_EXT 0x881E
+#define GL_LUMINANCE_ALPHA16F_EXT 0x881F
+#define GL_R8_EXT 0x8229
+#define GL_RG8_EXT 0x822B
+#define GL_R32F_EXT 0x822E
+#define GL_RG32F_EXT 0x8230
+#define GL_R16F_EXT 0x822D
+#define GL_RG16F_EXT 0x822F
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_API void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_API void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_API void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+#endif /* GL_EXT_texture_storage */
+
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_IMG_multisampled_render_to_texture 1
+#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134
+#define GL_MAX_SAMPLES_IMG 0x9135
+#define GL_TEXTURE_SAMPLES_IMG 0x9136
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+#endif /* GL_IMG_multisampled_render_to_texture */
+
+#ifndef GL_IMG_read_format
+#define GL_IMG_read_format 1
+#define GL_BGRA_IMG 0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365
+#endif /* GL_IMG_read_format */
+
+#ifndef GL_IMG_texture_compression_pvrtc
+#define GL_IMG_texture_compression_pvrtc 1
+#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
+#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
+#endif /* GL_IMG_texture_compression_pvrtc */
+
+#ifndef GL_IMG_texture_env_enhanced_fixed_function
+#define GL_IMG_texture_env_enhanced_fixed_function 1
+#define GL_MODULATE_COLOR_IMG 0x8C04
+#define GL_RECIP_ADD_SIGNED_ALPHA_IMG 0x8C05
+#define GL_TEXTURE_ALPHA_MODULATE_IMG 0x8C06
+#define GL_FACTOR_ALPHA_MODULATE_IMG 0x8C07
+#define GL_FRAGMENT_ALPHA_MODULATE_IMG 0x8C08
+#define GL_ADD_BLEND_IMG 0x8C09
+#define GL_DOT3_RGBA_IMG 0x86AF
+#endif /* GL_IMG_texture_env_enhanced_fixed_function */
+
+#ifndef GL_IMG_user_clip_plane
+#define GL_IMG_user_clip_plane 1
+#define GL_CLIP_PLANE0_IMG 0x3000
+#define GL_CLIP_PLANE1_IMG 0x3001
+#define GL_CLIP_PLANE2_IMG 0x3002
+#define GL_CLIP_PLANE3_IMG 0x3003
+#define GL_CLIP_PLANE4_IMG 0x3004
+#define GL_CLIP_PLANE5_IMG 0x3005
+#define GL_MAX_CLIP_PLANES_IMG 0x0D32
+typedef void (GL_APIENTRYP PFNGLCLIPPLANEFIMGPROC) (GLenum p, const GLfloat *eqn);
+typedef void (GL_APIENTRYP PFNGLCLIPPLANEXIMGPROC) (GLenum p, const GLfixed *eqn);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glClipPlanefIMG (GLenum p, const GLfloat *eqn);
+GL_API void GL_APIENTRY glClipPlanexIMG (GLenum p, const GLfixed *eqn);
+#endif
+#endif /* GL_IMG_user_clip_plane */
+
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences);
+typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
+typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
+typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences);
+GL_API void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences);
+GL_API GLboolean GL_APIENTRY glIsFenceNV (GLuint fence);
+GL_API GLboolean GL_APIENTRY glTestFenceNV (GLuint fence);
+GL_API void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glFinishFenceNV (GLuint fence);
+GL_API void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition);
+#endif
+#endif /* GL_NV_fence */
+
+#ifndef GL_QCOM_driver_control
+#define GL_QCOM_driver_control 1
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls);
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
+typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls);
+GL_API void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
+GL_API void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl);
+GL_API void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl);
+#endif
+#endif /* GL_QCOM_driver_control */
+
+#ifndef GL_QCOM_extended_get
+#define GL_QCOM_extended_get 1
+#define GL_TEXTURE_WIDTH_QCOM 0x8BD2
+#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3
+#define GL_TEXTURE_DEPTH_QCOM 0x8BD4
+#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5
+#define GL_TEXTURE_FORMAT_QCOM 0x8BD6
+#define GL_TEXTURE_TYPE_QCOM 0x8BD7
+#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8
+#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9
+#define GL_TEXTURE_TARGET_QCOM 0x8BDA
+#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB
+#define GL_STATE_RESTORE 0x8BDC
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, void **params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures);
+GL_API void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+GL_API void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+GL_API void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+GL_API void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param);
+GL_API void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels);
+GL_API void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, void **params);
+#endif
+#endif /* GL_QCOM_extended_get */
+
+#ifndef GL_QCOM_extended_get2
+#define GL_QCOM_extended_get2 1
+typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+GL_API void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+GL_API GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program);
+GL_API void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#endif
+#endif /* GL_QCOM_extended_get2 */
+
+#ifndef GL_QCOM_perfmon_global_mode
+#define GL_QCOM_perfmon_global_mode 1
+#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0
+#endif /* GL_QCOM_perfmon_global_mode */
+
+#ifndef GL_QCOM_tiled_rendering
+#define GL_QCOM_tiled_rendering 1
+#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001
+#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002
+#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004
+#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008
+#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010
+#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020
+#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040
+#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080
+#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100
+#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200
+#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400
+#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800
+#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000
+#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000
+#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000
+#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000
+#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000
+#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000
+#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000
+#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000
+#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000
+#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000
+#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000
+#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000
+#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000
+#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000
+#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000
+#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000
+#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000
+#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000
+#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000
+#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000
+typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+GL_API void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask);
+#endif
+#endif /* GL_QCOM_tiled_rendering */
+
+#ifndef GL_QCOM_writeonly_rendering
+#define GL_QCOM_writeonly_rendering 1
+#define GL_WRITEONLY_RENDERING_QCOM 0x8823
+#endif /* GL_QCOM_writeonly_rendering */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/include/GLES/glplatform.h b/gfx/angle/checkout/include/GLES/glplatform.h
new file mode 100644
index 0000000000..16060a9a73
--- /dev/null
+++ b/gfx/angle/checkout/include/GLES/glplatform.h
@@ -0,0 +1,38 @@
+#ifndef __glplatform_h_
+#define __glplatform_h_
+
+/*
+** Copyright (c) 2017 The Khronos Group Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+/* Platform-specific types and definitions for OpenGL ES 1.X gl.h
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * Please contribute modifications back to Khronos as pull requests on the
+ * public github repository:
+ * https://github.com/KhronosGroup/OpenGL-Registry
+ */
+
+#include <KHR/khrplatform.h>
+
+#ifndef GL_API
+#define GL_API KHRONOS_APICALL
+#endif
+
+#ifndef GL_APIENTRY
+#define GL_APIENTRY KHRONOS_APIENTRY
+#endif
+
+#endif /* __glplatform_h_ */
diff --git a/gfx/angle/checkout/include/GLES2/gl2.h b/gfx/angle/checkout/include/GLES2/gl2.h
new file mode 100644
index 0000000000..3c5e6d3d6e
--- /dev/null
+++ b/gfx/angle/checkout/include/GLES2/gl2.h
@@ -0,0 +1,656 @@
+#ifndef __gles2_gl2_h_
+#define __gles2_gl2_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright 2013-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: MIT
+**
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** https://github.com/KhronosGroup/OpenGL-Registry
+*/
+
+#include <GLES2/gl2platform.h>
+
+#ifndef GL_APIENTRYP
+#define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+#ifndef GL_GLES_PROTOTYPES
+#define GL_GLES_PROTOTYPES 1
+#endif
+
+/* Generated on date 20210107 */
+
+/* Generated C header for:
+ * API: gles2
+ * Profile: common
+ * Versions considered: 2\.[0-9]
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef GL_ES_VERSION_2_0
+#define GL_ES_VERSION_2_0 1
+#include <KHR/khrplatform.h>
+typedef khronos_int8_t GLbyte;
+typedef khronos_float_t GLclampf;
+typedef khronos_int32_t GLfixed;
+typedef khronos_int16_t GLshort;
+typedef khronos_uint16_t GLushort;
+typedef void GLvoid;
+typedef struct __GLsync *GLsync;
+typedef khronos_int64_t GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef unsigned int GLenum;
+typedef unsigned int GLuint;
+typedef char GLchar;
+typedef khronos_float_t GLfloat;
+typedef khronos_ssize_t GLsizeiptr;
+typedef khronos_intptr_t GLintptr;
+typedef unsigned int GLbitfield;
+typedef int GLint;
+typedef unsigned char GLboolean;
+typedef int GLsizei;
+typedef khronos_uint8_t GLubyte;
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_FALSE 0
+#define GL_TRUE 1
+#define GL_POINTS 0x0000
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_STRIP 0x0003
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_ZERO 0
+#define GL_ONE 1
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_FUNC_ADD 0x8006
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STATIC_DRAW 0x88E4
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_CULL_FACE 0x0B44
+#define GL_BLEND 0x0BE2
+#define GL_DITHER 0x0BD0
+#define GL_STENCIL_TEST 0x0B90
+#define GL_DEPTH_TEST 0x0B71
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_NO_ERROR 0
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+#define GL_LINE_WIDTH 0x0B21
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#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_VIEWPORT 0x0BA2
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_ALPHA_BITS 0x0D55
+#define GL_DEPTH_BITS 0x0D56
+#define GL_STENCIL_BITS 0x0D57
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_FIXED 0x140C
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_DELETE_STATUS 0x8B80
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_NEVER 0x0200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+#define GL_INVERT 0x150A
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+#define GL_NEAREST 0x2600
+#define GL_LINEAR 0x2601
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TEXTURE 0x1702
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#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_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_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_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_REPEAT 0x2901
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGB565 0x8D62
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_NONE 0
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
+typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
+typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);
+typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
+typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);
+typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
+typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
+typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void);
+typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
+typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
+typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode);
+typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
+typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
+typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture);
+typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width);
+typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);
+typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert);
+typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length);
+typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
+typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+#if GL_GLES_PROTOTYPES
+GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
+GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
+GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
+GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
+GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
+GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d);
+GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
+GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
+GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
+GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
+GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
+GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
+GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
+GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
+GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
+GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f);
+GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
+GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
+GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
+GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glFinish (void);
+GL_APICALL void GL_APIENTRY glFlush (void);
+GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
+GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
+GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
+GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
+GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures);
+GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL GLenum GL_APIENTRY glGetError (void);
+GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data);
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data);
+GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name);
+GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
+GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
+GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
+GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
+GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
+GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
+GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
+GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
+GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
+GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
+GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);
+GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length);
+GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0);
+GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0);
+GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
+GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
+GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
+GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
+GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
+GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_ES_VERSION_2_0 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/include/GLES2/gl2ext.h b/gfx/angle/checkout/include/GLES2/gl2ext.h
new file mode 100644
index 0000000000..948cd83541
--- /dev/null
+++ b/gfx/angle/checkout/include/GLES2/gl2ext.h
@@ -0,0 +1,3949 @@
+#ifndef __gles2_gl2ext_h_
+#define __gles2_gl2ext_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright 2013-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: MIT
+**
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** https://github.com/KhronosGroup/OpenGL-Registry
+*/
+
+#ifndef GL_APIENTRYP
+#define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+/* Generated on date 20210107 */
+
+/* Generated C header for:
+ * API: gles2
+ * Profile: common
+ * Versions considered: 2\.[0-9]
+ * Versions emitted: _nomatch_^
+ * Default extensions included: gles2
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef GL_KHR_blend_equation_advanced
+#define GL_KHR_blend_equation_advanced 1
+#define GL_MULTIPLY_KHR 0x9294
+#define GL_SCREEN_KHR 0x9295
+#define GL_OVERLAY_KHR 0x9296
+#define GL_DARKEN_KHR 0x9297
+#define GL_LIGHTEN_KHR 0x9298
+#define GL_COLORDODGE_KHR 0x9299
+#define GL_COLORBURN_KHR 0x929A
+#define GL_HARDLIGHT_KHR 0x929B
+#define GL_SOFTLIGHT_KHR 0x929C
+#define GL_DIFFERENCE_KHR 0x929E
+#define GL_EXCLUSION_KHR 0x92A0
+#define GL_HSL_HUE_KHR 0x92AD
+#define GL_HSL_SATURATION_KHR 0x92AE
+#define GL_HSL_COLOR_KHR 0x92AF
+#define GL_HSL_LUMINOSITY_KHR 0x92B0
+typedef void (GL_APIENTRYP PFNGLBLENDBARRIERKHRPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlendBarrierKHR (void);
+#endif
+#endif /* GL_KHR_blend_equation_advanced */
+
+#ifndef GL_KHR_blend_equation_advanced_coherent
+#define GL_KHR_blend_equation_advanced_coherent 1
+#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285
+#endif /* GL_KHR_blend_equation_advanced_coherent */
+
+#ifndef GL_KHR_context_flush_control
+#define GL_KHR_context_flush_control 1
+#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB
+#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x82FC
+#endif /* GL_KHR_context_flush_control */
+
+#ifndef GL_KHR_debug
+#define GL_KHR_debug 1
+typedef void (GL_APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+#define GL_SAMPLER 0x82E6
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245
+#define GL_DEBUG_SOURCE_API_KHR 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A
+#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B
+#define GL_DEBUG_TYPE_ERROR_KHR 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250
+#define GL_DEBUG_TYPE_OTHER_KHR 0x8251
+#define GL_DEBUG_TYPE_MARKER_KHR 0x8268
+#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269
+#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A
+#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C
+#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D
+#define GL_BUFFER_KHR 0x82E0
+#define GL_SHADER_KHR 0x82E1
+#define GL_PROGRAM_KHR 0x82E2
+#define GL_VERTEX_ARRAY_KHR 0x8074
+#define GL_QUERY_KHR 0x82E3
+#define GL_PROGRAM_PIPELINE_KHR 0x82E4
+#define GL_SAMPLER_KHR 0x82E6
+#define GL_MAX_LABEL_LENGTH_KHR 0x82E8
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147
+#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148
+#define GL_DEBUG_OUTPUT_KHR 0x92E0
+#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002
+#define GL_STACK_OVERFLOW_KHR 0x0503
+#define GL_STACK_UNDERFLOW_KHR 0x0504
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC) (GLDEBUGPROCKHR callback, const void *userParam);
+typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);
+typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC) (void);
+typedef void (GL_APIENTRYP PFNGLOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETPOINTERVKHRPROC) (GLenum pname, void **params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDebugMessageControlKHR (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR (GLDEBUGPROCKHR callback, const void *userParam);
+GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+GL_APICALL void GL_APIENTRY glPushDebugGroupKHR (GLenum source, GLuint id, GLsizei length, const GLchar *message);
+GL_APICALL void GL_APIENTRY glPopDebugGroupKHR (void);
+GL_APICALL void GL_APIENTRY glObjectLabelKHR (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectLabelKHR (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+GL_APICALL void GL_APIENTRY glObjectPtrLabelKHR (const void *ptr, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectPtrLabelKHR (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
+GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, void **params);
+#endif
+#endif /* GL_KHR_debug */
+
+#ifndef GL_KHR_no_error
+#define GL_KHR_no_error 1
+#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
+#endif /* GL_KHR_no_error */
+
+#ifndef GL_KHR_parallel_shader_compile
+#define GL_KHR_parallel_shader_compile 1
+#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0
+#define GL_COMPLETION_STATUS_KHR 0x91B1
+typedef void (GL_APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) (GLuint count);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMaxShaderCompilerThreadsKHR (GLuint count);
+#endif
+#endif /* GL_KHR_parallel_shader_compile */
+
+#ifndef GL_KHR_robust_buffer_access_behavior
+#define GL_KHR_robust_buffer_access_behavior 1
+#endif /* GL_KHR_robust_buffer_access_behavior */
+
+#ifndef GL_KHR_robustness
+#define GL_KHR_robustness 1
+#define GL_CONTEXT_ROBUST_ACCESS_KHR 0x90F3
+#define GL_LOSE_CONTEXT_ON_RESET_KHR 0x8252
+#define GL_GUILTY_CONTEXT_RESET_KHR 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_KHR 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_KHR 0x8255
+#define GL_RESET_NOTIFICATION_STRATEGY_KHR 0x8256
+#define GL_NO_RESET_NOTIFICATION_KHR 0x8261
+#define GL_CONTEXT_LOST_KHR 0x0507
+typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC) (void);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSKHRPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusKHR (void);
+GL_APICALL void GL_APIENTRY glReadnPixelsKHR (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+GL_APICALL void GL_APIENTRY glGetnUniformfvKHR (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetnUniformivKHR (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+GL_APICALL void GL_APIENTRY glGetnUniformuivKHR (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+#endif
+#endif /* GL_KHR_robustness */
+
+#ifndef GL_KHR_shader_subgroup
+#define GL_KHR_shader_subgroup 1
+#define GL_SUBGROUP_SIZE_KHR 0x9532
+#define GL_SUBGROUP_SUPPORTED_STAGES_KHR 0x9533
+#define GL_SUBGROUP_SUPPORTED_FEATURES_KHR 0x9534
+#define GL_SUBGROUP_QUAD_ALL_STAGES_KHR 0x9535
+#define GL_SUBGROUP_FEATURE_BASIC_BIT_KHR 0x00000001
+#define GL_SUBGROUP_FEATURE_VOTE_BIT_KHR 0x00000002
+#define GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR 0x00000004
+#define GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR 0x00000008
+#define GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR 0x00000010
+#define GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR 0x00000020
+#define GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR 0x00000040
+#define GL_SUBGROUP_FEATURE_QUAD_BIT_KHR 0x00000080
+#endif /* GL_KHR_shader_subgroup */
+
+#ifndef GL_KHR_texture_compression_astc_hdr
+#define GL_KHR_texture_compression_astc_hdr 1
+#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
+#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
+#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
+#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
+#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
+#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
+#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
+#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
+#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
+#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
+#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
+#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+#endif /* GL_KHR_texture_compression_astc_hdr */
+
+#ifndef GL_KHR_texture_compression_astc_ldr
+#define GL_KHR_texture_compression_astc_ldr 1
+#endif /* GL_KHR_texture_compression_astc_ldr */
+
+#ifndef GL_KHR_texture_compression_astc_sliced_3d
+#define GL_KHR_texture_compression_astc_sliced_3d 1
+#endif /* GL_KHR_texture_compression_astc_sliced_3d */
+
+#ifndef GL_OES_EGL_image
+#define GL_OES_EGL_image 1
+typedef void *GLeglImageOES;
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image);
+GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image);
+#endif
+#endif /* GL_OES_EGL_image */
+
+#ifndef GL_OES_EGL_image_external
+#define GL_OES_EGL_image_external 1
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67
+#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68
+#define GL_SAMPLER_EXTERNAL_OES 0x8D66
+#endif /* GL_OES_EGL_image_external */
+
+#ifndef GL_OES_EGL_image_external_essl3
+#define GL_OES_EGL_image_external_essl3 1
+#endif /* GL_OES_EGL_image_external_essl3 */
+
+#ifndef GL_OES_compressed_ETC1_RGB8_sub_texture
+#define GL_OES_compressed_ETC1_RGB8_sub_texture 1
+#endif /* GL_OES_compressed_ETC1_RGB8_sub_texture */
+
+#ifndef GL_OES_compressed_ETC1_RGB8_texture
+#define GL_OES_compressed_ETC1_RGB8_texture 1
+#define GL_ETC1_RGB8_OES 0x8D64
+#endif /* GL_OES_compressed_ETC1_RGB8_texture */
+
+#ifndef GL_OES_compressed_paletted_texture
+#define GL_OES_compressed_paletted_texture 1
+#define GL_PALETTE4_RGB8_OES 0x8B90
+#define GL_PALETTE4_RGBA8_OES 0x8B91
+#define GL_PALETTE4_R5_G6_B5_OES 0x8B92
+#define GL_PALETTE4_RGBA4_OES 0x8B93
+#define GL_PALETTE4_RGB5_A1_OES 0x8B94
+#define GL_PALETTE8_RGB8_OES 0x8B95
+#define GL_PALETTE8_RGBA8_OES 0x8B96
+#define GL_PALETTE8_R5_G6_B5_OES 0x8B97
+#define GL_PALETTE8_RGBA4_OES 0x8B98
+#define GL_PALETTE8_RGB5_A1_OES 0x8B99
+#endif /* GL_OES_compressed_paletted_texture */
+
+#ifndef GL_OES_copy_image
+#define GL_OES_copy_image 1
+typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAOESPROC) (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);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL 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);
+#endif
+#endif /* GL_OES_copy_image */
+
+#ifndef GL_OES_depth24
+#define GL_OES_depth24 1
+#define GL_DEPTH_COMPONENT24_OES 0x81A6
+#endif /* GL_OES_depth24 */
+
+#ifndef GL_OES_depth32
+#define GL_OES_depth32 1
+#define GL_DEPTH_COMPONENT32_OES 0x81A7
+#endif /* GL_OES_depth32 */
+
+#ifndef GL_OES_depth_texture
+#define GL_OES_depth_texture 1
+#endif /* GL_OES_depth_texture */
+
+#ifndef GL_OES_draw_buffers_indexed
+#define GL_OES_draw_buffers_indexed 1
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+typedef void (GL_APIENTRYP PFNGLENABLEIOESPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLDISABLEIOESPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIOESPROC) (GLuint buf, GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIOESPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCIOESPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIOESPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKIOESPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIOESPROC) (GLenum target, GLuint index);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEnableiOES (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glDisableiOES (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glBlendEquationiOES (GLuint buf, GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparateiOES (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunciOES (GLuint buf, GLenum src, GLenum dst);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparateiOES (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GL_APICALL void GL_APIENTRY glColorMaskiOES (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GL_APICALL GLboolean GL_APIENTRY glIsEnablediOES (GLenum target, GLuint index);
+#endif
+#endif /* GL_OES_draw_buffers_indexed */
+
+#ifndef GL_OES_draw_elements_base_vertex
+#define GL_OES_draw_elements_base_vertex 1
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexOES (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex);
+#endif
+#endif /* GL_OES_draw_elements_base_vertex */
+
+#ifndef GL_OES_element_index_uint
+#define GL_OES_element_index_uint 1
+#endif /* GL_OES_element_index_uint */
+
+#ifndef GL_OES_fbo_render_mipmap
+#define GL_OES_fbo_render_mipmap 1
+#endif /* GL_OES_fbo_render_mipmap */
+
+#ifndef GL_OES_fragment_precision_high
+#define GL_OES_fragment_precision_high 1
+#endif /* GL_OES_fragment_precision_high */
+
+#ifndef GL_OES_geometry_point_size
+#define GL_OES_geometry_point_size 1
+#endif /* GL_OES_geometry_point_size */
+
+#ifndef GL_OES_geometry_shader
+#define GL_OES_geometry_shader 1
+#define GL_GEOMETRY_SHADER_OES 0x8DD9
+#define GL_GEOMETRY_SHADER_BIT_OES 0x00000004
+#define GL_GEOMETRY_LINKED_VERTICES_OUT_OES 0x8916
+#define GL_GEOMETRY_LINKED_INPUT_TYPE_OES 0x8917
+#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES 0x8918
+#define GL_GEOMETRY_SHADER_INVOCATIONS_OES 0x887F
+#define GL_LAYER_PROVOKING_VERTEX_OES 0x825E
+#define GL_LINES_ADJACENCY_OES 0x000A
+#define GL_LINE_STRIP_ADJACENCY_OES 0x000B
+#define GL_TRIANGLES_ADJACENCY_OES 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_OES 0x000D
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8DDF
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES 0x8A2C
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8A32
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES 0x9124
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES 0x8DE1
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES 0x8E5A
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES 0x8C29
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES 0x92CF
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES 0x92D5
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES 0x90CD
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES 0x90D7
+#define GL_FIRST_VERTEX_CONVENTION_OES 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_OES 0x8E4E
+#define GL_UNDEFINED_VERTEX_OES 0x8260
+#define GL_PRIMITIVES_GENERATED_OES 0x8C87
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS_OES 0x9312
+#define GL_MAX_FRAMEBUFFER_LAYERS_OES 0x9317
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES 0x8DA8
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES 0x8DA7
+#define GL_REFERENCED_BY_GEOMETRY_SHADER_OES 0x9309
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREOESPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureOES (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif
+#endif /* GL_OES_geometry_shader */
+
+#ifndef GL_OES_get_program_binary
+#define GL_OES_get_program_binary 1
+#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLint length);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const void *binary, GLint length);
+#endif
+#endif /* GL_OES_get_program_binary */
+
+#ifndef GL_OES_gpu_shader5
+#define GL_OES_gpu_shader5 1
+#endif /* GL_OES_gpu_shader5 */
+
+#ifndef GL_OES_mapbuffer
+#define GL_OES_mapbuffer 1
+#define GL_WRITE_ONLY_OES 0x88B9
+#define GL_BUFFER_ACCESS_OES 0x88BB
+#define GL_BUFFER_MAPPED_OES 0x88BC
+#define GL_BUFFER_MAP_POINTER_OES 0x88BD
+typedef void *(GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access);
+typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void **params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void *GL_APIENTRY glMapBufferOES (GLenum target, GLenum access);
+GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target);
+GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, void **params);
+#endif
+#endif /* GL_OES_mapbuffer */
+
+#ifndef GL_OES_packed_depth_stencil
+#define GL_OES_packed_depth_stencil 1
+#define GL_DEPTH_STENCIL_OES 0x84F9
+#define GL_UNSIGNED_INT_24_8_OES 0x84FA
+#define GL_DEPTH24_STENCIL8_OES 0x88F0
+#endif /* GL_OES_packed_depth_stencil */
+
+#ifndef GL_OES_primitive_bounding_box
+#define GL_OES_primitive_bounding_box 1
+#define GL_PRIMITIVE_BOUNDING_BOX_OES 0x92BE
+typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXOESPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxOES (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#endif
+#endif /* GL_OES_primitive_bounding_box */
+
+#ifndef GL_OES_required_internalformat
+#define GL_OES_required_internalformat 1
+#define GL_ALPHA8_OES 0x803C
+#define GL_DEPTH_COMPONENT16_OES 0x81A5
+#define GL_LUMINANCE4_ALPHA4_OES 0x8043
+#define GL_LUMINANCE8_ALPHA8_OES 0x8045
+#define GL_LUMINANCE8_OES 0x8040
+#define GL_RGBA4_OES 0x8056
+#define GL_RGB5_A1_OES 0x8057
+#define GL_RGB565_OES 0x8D62
+#define GL_RGB8_OES 0x8051
+#define GL_RGBA8_OES 0x8058
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB10_A2_EXT 0x8059
+#endif /* GL_OES_required_internalformat */
+
+#ifndef GL_OES_rgb8_rgba8
+#define GL_OES_rgb8_rgba8 1
+#endif /* GL_OES_rgb8_rgba8 */
+
+#ifndef GL_OES_sample_shading
+#define GL_OES_sample_shading 1
+#define GL_SAMPLE_SHADING_OES 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE_OES 0x8C37
+typedef void (GL_APIENTRYP PFNGLMINSAMPLESHADINGOESPROC) (GLfloat value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMinSampleShadingOES (GLfloat value);
+#endif
+#endif /* GL_OES_sample_shading */
+
+#ifndef GL_OES_sample_variables
+#define GL_OES_sample_variables 1
+#endif /* GL_OES_sample_variables */
+
+#ifndef GL_OES_shader_image_atomic
+#define GL_OES_shader_image_atomic 1
+#endif /* GL_OES_shader_image_atomic */
+
+#ifndef GL_OES_shader_io_blocks
+#define GL_OES_shader_io_blocks 1
+#endif /* GL_OES_shader_io_blocks */
+
+#ifndef GL_OES_shader_multisample_interpolation
+#define GL_OES_shader_multisample_interpolation 1
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5C
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES 0x8E5D
+#endif /* GL_OES_shader_multisample_interpolation */
+
+#ifndef GL_OES_standard_derivatives
+#define GL_OES_standard_derivatives 1
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B
+#endif /* GL_OES_standard_derivatives */
+
+#ifndef GL_OES_stencil1
+#define GL_OES_stencil1 1
+#define GL_STENCIL_INDEX1_OES 0x8D46
+#endif /* GL_OES_stencil1 */
+
+#ifndef GL_OES_stencil4
+#define GL_OES_stencil4 1
+#define GL_STENCIL_INDEX4_OES 0x8D47
+#endif /* GL_OES_stencil4 */
+
+#ifndef GL_OES_surfaceless_context
+#define GL_OES_surfaceless_context 1
+#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219
+#endif /* GL_OES_surfaceless_context */
+
+#ifndef GL_OES_tessellation_point_size
+#define GL_OES_tessellation_point_size 1
+#endif /* GL_OES_tessellation_point_size */
+
+#ifndef GL_OES_tessellation_shader
+#define GL_OES_tessellation_shader 1
+#define GL_PATCHES_OES 0x000E
+#define GL_PATCH_VERTICES_OES 0x8E72
+#define GL_TESS_CONTROL_OUTPUT_VERTICES_OES 0x8E75
+#define GL_TESS_GEN_MODE_OES 0x8E76
+#define GL_TESS_GEN_SPACING_OES 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER_OES 0x8E78
+#define GL_TESS_GEN_POINT_MODE_OES 0x8E79
+#define GL_ISOLINES_OES 0x8E7A
+#define GL_QUADS_OES 0x0007
+#define GL_FRACTIONAL_ODD_OES 0x8E7B
+#define GL_FRACTIONAL_EVEN_OES 0x8E7C
+#define GL_MAX_PATCH_VERTICES_OES 0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL_OES 0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS_OES 0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES 0x8E86
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES 0x8E8A
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES 0x92CE
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES 0x92D3
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES 0x92D4
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES 0x90CB
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES 0x90CC
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES 0x90D9
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES 0x8221
+#define GL_IS_PER_PATCH_OES 0x92E7
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES 0x9308
+#define GL_TESS_CONTROL_SHADER_OES 0x8E88
+#define GL_TESS_EVALUATION_SHADER_OES 0x8E87
+#define GL_TESS_CONTROL_SHADER_BIT_OES 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT_OES 0x00000010
+typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIOESPROC) (GLenum pname, GLint value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPatchParameteriOES (GLenum pname, GLint value);
+#endif
+#endif /* GL_OES_tessellation_shader */
+
+#ifndef GL_OES_texture_3D
+#define GL_OES_texture_3D 1
+#define GL_TEXTURE_WRAP_R_OES 0x8072
+#define GL_TEXTURE_3D_OES 0x806F
+#define GL_TEXTURE_BINDING_3D_OES 0x806A
+#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073
+#define GL_SAMPLER_3D_OES 0x8B5F
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL 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);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+#endif
+#endif /* GL_OES_texture_3D */
+
+#ifndef GL_OES_texture_border_clamp
+#define GL_OES_texture_border_clamp 1
+#define GL_TEXTURE_BORDER_COLOR_OES 0x1004
+#define GL_CLAMP_TO_BORDER_OES 0x812D
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, const GLuint *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, GLuint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexParameterIivOES (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexParameterIuivOES (GLenum target, GLenum pname, const GLuint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIivOES (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIuivOES (GLenum target, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glSamplerParameterIivOES (GLuint sampler, GLenum pname, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterIuivOES (GLuint sampler, GLenum pname, const GLuint *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIivOES (GLuint sampler, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivOES (GLuint sampler, GLenum pname, GLuint *params);
+#endif
+#endif /* GL_OES_texture_border_clamp */
+
+#ifndef GL_OES_texture_buffer
+#define GL_OES_texture_buffer 1
+#define GL_TEXTURE_BUFFER_OES 0x8C2A
+#define GL_TEXTURE_BUFFER_BINDING_OES 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_OES 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_OES 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES 0x8C2D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES 0x919F
+#define GL_SAMPLER_BUFFER_OES 0x8DC2
+#define GL_INT_SAMPLER_BUFFER_OES 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_OES 0x8DD8
+#define GL_IMAGE_BUFFER_OES 0x9051
+#define GL_INT_IMAGE_BUFFER_OES 0x905C
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_OES 0x9067
+#define GL_TEXTURE_BUFFER_OFFSET_OES 0x919D
+#define GL_TEXTURE_BUFFER_SIZE_OES 0x919E
+typedef void (GL_APIENTRYP PFNGLTEXBUFFEROESPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEOESPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexBufferOES (GLenum target, GLenum internalformat, GLuint buffer);
+GL_APICALL void GL_APIENTRY glTexBufferRangeOES (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#endif
+#endif /* GL_OES_texture_buffer */
+
+#ifndef GL_OES_texture_compression_astc
+#define GL_OES_texture_compression_astc 1
+#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0
+#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1
+#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2
+#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3
+#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4
+#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5
+#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6
+#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7
+#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8
+#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9
+#endif /* GL_OES_texture_compression_astc */
+
+#ifndef GL_OES_texture_cube_map_array
+#define GL_OES_texture_cube_map_array 1
+#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES 0x900A
+#define GL_SAMPLER_CUBE_MAP_ARRAY_OES 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900F
+#define GL_IMAGE_CUBE_MAP_ARRAY_OES 0x9054
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x905F
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x906A
+#endif /* GL_OES_texture_cube_map_array */
+
+#ifndef GL_OES_texture_float
+#define GL_OES_texture_float 1
+#endif /* GL_OES_texture_float */
+
+#ifndef GL_OES_texture_float_linear
+#define GL_OES_texture_float_linear 1
+#endif /* GL_OES_texture_float_linear */
+
+#ifndef GL_OES_texture_half_float
+#define GL_OES_texture_half_float 1
+#define GL_HALF_FLOAT_OES 0x8D61
+#endif /* GL_OES_texture_half_float */
+
+#ifndef GL_OES_texture_half_float_linear
+#define GL_OES_texture_half_float_linear 1
+#endif /* GL_OES_texture_half_float_linear */
+
+#ifndef GL_OES_texture_npot
+#define GL_OES_texture_npot 1
+#endif /* GL_OES_texture_npot */
+
+#ifndef GL_OES_texture_stencil8
+#define GL_OES_texture_stencil8 1
+#define GL_STENCIL_INDEX_OES 0x1901
+#define GL_STENCIL_INDEX8_OES 0x8D48
+#endif /* GL_OES_texture_stencil8 */
+
+#ifndef GL_OES_texture_storage_multisample_2d_array
+#define GL_OES_texture_storage_multisample_2d_array 1
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES 0x9102
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES 0x9105
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910D
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexStorage3DMultisampleOES (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+#endif
+#endif /* GL_OES_texture_storage_multisample_2d_array */
+
+#ifndef GL_OES_texture_view
+#define GL_OES_texture_view 1
+#define GL_TEXTURE_VIEW_MIN_LEVEL_OES 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LEVELS_OES 0x82DC
+#define GL_TEXTURE_VIEW_MIN_LAYER_OES 0x82DD
+#define GL_TEXTURE_VIEW_NUM_LAYERS_OES 0x82DE
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWOESPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTextureViewOES (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#endif
+#endif /* GL_OES_texture_view */
+
+#ifndef GL_OES_vertex_array_object
+#define GL_OES_vertex_array_object 1
+#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5
+typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays);
+typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array);
+GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays);
+GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays);
+GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array);
+#endif
+#endif /* GL_OES_vertex_array_object */
+
+#ifndef GL_OES_vertex_half_float
+#define GL_OES_vertex_half_float 1
+#endif /* GL_OES_vertex_half_float */
+
+#ifndef GL_OES_vertex_type_10_10_10_2
+#define GL_OES_vertex_type_10_10_10_2 1
+#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6
+#define GL_INT_10_10_10_2_OES 0x8DF7
+#endif /* GL_OES_vertex_type_10_10_10_2 */
+
+#ifndef GL_OES_viewport_array
+#define GL_OES_viewport_array 1
+#define GL_MAX_VIEWPORTS_OES 0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS_OES 0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE_OES 0x825D
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_OES 0x825F
+typedef void (GL_APIENTRYP PFNGLVIEWPORTARRAYVOESPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFOESPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFVOESPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLSCISSORARRAYVOESPROC) (GLuint first, GLsizei count, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDOESPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDVOESPROC) (GLuint index, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEARRAYFVOESPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEINDEXEDFOESPROC) (GLuint index, GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLGETFLOATI_VOESPROC) (GLenum target, GLuint index, GLfloat *data);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glViewportArrayvOES (GLuint first, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glViewportIndexedfOES (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+GL_APICALL void GL_APIENTRY glViewportIndexedfvOES (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glScissorArrayvOES (GLuint first, GLsizei count, const GLint *v);
+GL_APICALL void GL_APIENTRY glScissorIndexedOES (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glScissorIndexedvOES (GLuint index, const GLint *v);
+GL_APICALL void GL_APIENTRY glDepthRangeArrayfvOES (GLuint first, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glDepthRangeIndexedfOES (GLuint index, GLfloat n, GLfloat f);
+GL_APICALL void GL_APIENTRY glGetFloati_vOES (GLenum target, GLuint index, GLfloat *data);
+#endif
+#endif /* GL_OES_viewport_array */
+
+#ifndef GL_AMD_compressed_3DC_texture
+#define GL_AMD_compressed_3DC_texture 1
+#define GL_3DC_X_AMD 0x87F9
+#define GL_3DC_XY_AMD 0x87FA
+#endif /* GL_AMD_compressed_3DC_texture */
+
+#ifndef GL_AMD_compressed_ATC_texture
+#define GL_AMD_compressed_ATC_texture 1
+#define GL_ATC_RGB_AMD 0x8C92
+#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93
+#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
+#endif /* GL_AMD_compressed_ATC_texture */
+
+#ifndef GL_AMD_framebuffer_multisample_advanced
+#define GL_AMD_framebuffer_multisample_advanced 1
+#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2
+#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3
+#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4
+#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5
+#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6
+#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAdvancedAMD (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glNamedRenderbufferStorageMultisampleAdvancedAMD (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_AMD_framebuffer_multisample_advanced */
+
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+#define GL_COUNTER_TYPE_AMD 0x8BC0
+#define GL_COUNTER_RANGE_AMD 0x8BC1
+#define GL_UNSIGNED_INT64_AMD 0x8BC2
+#define GL_PERCENTAGE_AMD 0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
+#define GL_PERFMON_RESULT_AMD 0x8BC6
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data);
+typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data);
+GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor);
+GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif
+#endif /* GL_AMD_performance_monitor */
+
+#ifndef GL_AMD_program_binary_Z400
+#define GL_AMD_program_binary_Z400 1
+#define GL_Z400_BINARY_AMD 0x8740
+#endif /* GL_AMD_program_binary_Z400 */
+
+#ifndef GL_ANDROID_extension_pack_es31a
+#define GL_ANDROID_extension_pack_es31a 1
+#endif /* GL_ANDROID_extension_pack_es31a */
+
+#ifndef GL_ANGLE_depth_texture
+#define GL_ANGLE_depth_texture 1
+#endif /* GL_ANGLE_depth_texture */
+
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_ANGLE_framebuffer_blit 1
+#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+#endif /* GL_ANGLE_framebuffer_blit */
+
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_ANGLE_framebuffer_multisample 1
+#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
+#define GL_MAX_SAMPLES_ANGLE 0x8D57
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_ANGLE_framebuffer_multisample */
+
+#ifndef GL_ANGLE_instanced_arrays
+#define GL_ANGLE_instanced_arrays 1
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor);
+#endif
+#endif /* GL_ANGLE_instanced_arrays */
+
+#ifndef GL_ANGLE_pack_reverse_row_order
+#define GL_ANGLE_pack_reverse_row_order 1
+#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4
+#endif /* GL_ANGLE_pack_reverse_row_order */
+
+#ifndef GL_ANGLE_program_binary
+#define GL_ANGLE_program_binary 1
+#define GL_PROGRAM_BINARY_ANGLE 0x93A6
+#endif /* GL_ANGLE_program_binary */
+
+#ifndef GL_ANGLE_texture_compression_dxt3
+#define GL_ANGLE_texture_compression_dxt3 1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2
+#endif /* GL_ANGLE_texture_compression_dxt3 */
+
+#ifndef GL_ANGLE_texture_compression_dxt5
+#define GL_ANGLE_texture_compression_dxt5 1
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3
+#endif /* GL_ANGLE_texture_compression_dxt5 */
+
+#ifndef GL_ANGLE_texture_usage
+#define GL_ANGLE_texture_usage 1
+#define GL_TEXTURE_USAGE_ANGLE 0x93A2
+#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
+#endif /* GL_ANGLE_texture_usage */
+
+#ifndef GL_ANGLE_translated_shader_source
+#define GL_ANGLE_translated_shader_source 1
+#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0
+typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+#endif
+#endif /* GL_ANGLE_translated_shader_source */
+
+#ifndef GL_APPLE_clip_distance
+#define GL_APPLE_clip_distance 1
+#define GL_MAX_CLIP_DISTANCES_APPLE 0x0D32
+#define GL_CLIP_DISTANCE0_APPLE 0x3000
+#define GL_CLIP_DISTANCE1_APPLE 0x3001
+#define GL_CLIP_DISTANCE2_APPLE 0x3002
+#define GL_CLIP_DISTANCE3_APPLE 0x3003
+#define GL_CLIP_DISTANCE4_APPLE 0x3004
+#define GL_CLIP_DISTANCE5_APPLE 0x3005
+#define GL_CLIP_DISTANCE6_APPLE 0x3006
+#define GL_CLIP_DISTANCE7_APPLE 0x3007
+#endif /* GL_APPLE_clip_distance */
+
+#ifndef GL_APPLE_color_buffer_packed_float
+#define GL_APPLE_color_buffer_packed_float 1
+#endif /* GL_APPLE_color_buffer_packed_float */
+
+#ifndef GL_APPLE_copy_texture_levels
+#define GL_APPLE_copy_texture_levels 1
+typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCopyTextureLevelsAPPLE (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount);
+#endif
+#endif /* GL_APPLE_copy_texture_levels */
+
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_APPLE_framebuffer_multisample 1
+#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56
+#define GL_MAX_SAMPLES_APPLE 0x8D57
+#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void);
+#endif
+#endif /* GL_APPLE_framebuffer_multisample */
+
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+#define GL_RGB_422_APPLE 0x8A1F
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#define GL_RGB_RAW_422_APPLE 0x8A51
+#endif /* GL_APPLE_rgb_422 */
+
+#ifndef GL_APPLE_sync
+#define GL_APPLE_sync 1
+#define GL_SYNC_OBJECT_APPLE 0x8A53
+#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111
+#define GL_OBJECT_TYPE_APPLE 0x9112
+#define GL_SYNC_CONDITION_APPLE 0x9113
+#define GL_SYNC_STATUS_APPLE 0x9114
+#define GL_SYNC_FLAGS_APPLE 0x9115
+#define GL_SYNC_FENCE_APPLE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117
+#define GL_UNSIGNALED_APPLE 0x9118
+#define GL_SIGNALED_APPLE 0x9119
+#define GL_ALREADY_SIGNALED_APPLE 0x911A
+#define GL_TIMEOUT_EXPIRED_APPLE 0x911B
+#define GL_CONDITION_SATISFIED_APPLE 0x911C
+#define GL_WAIT_FAILED_APPLE 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001
+#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull
+typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync);
+typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync);
+typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags);
+GL_APICALL GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync);
+GL_APICALL void GL_APIENTRY glDeleteSyncAPPLE (GLsync sync);
+GL_APICALL GLenum GL_APIENTRY glClientWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params);
+GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values);
+#endif
+#endif /* GL_APPLE_sync */
+
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_APPLE_texture_format_BGRA8888 1
+#define GL_BGRA_EXT 0x80E1
+#define GL_BGRA8_EXT 0x93A1
+#endif /* GL_APPLE_texture_format_BGRA8888 */
+
+#ifndef GL_APPLE_texture_max_level
+#define GL_APPLE_texture_max_level 1
+#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D
+#endif /* GL_APPLE_texture_max_level */
+
+#ifndef GL_APPLE_texture_packed_float
+#define GL_APPLE_texture_packed_float 1
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE 0x8C3B
+#define GL_UNSIGNED_INT_5_9_9_9_REV_APPLE 0x8C3E
+#define GL_R11F_G11F_B10F_APPLE 0x8C3A
+#define GL_RGB9_E5_APPLE 0x8C3D
+#endif /* GL_APPLE_texture_packed_float */
+
+#ifndef GL_ARM_mali_program_binary
+#define GL_ARM_mali_program_binary 1
+#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61
+#endif /* GL_ARM_mali_program_binary */
+
+#ifndef GL_ARM_mali_shader_binary
+#define GL_ARM_mali_shader_binary 1
+#define GL_MALI_SHADER_BINARY_ARM 0x8F60
+#endif /* GL_ARM_mali_shader_binary */
+
+#ifndef GL_ARM_rgba8
+#define GL_ARM_rgba8 1
+#endif /* GL_ARM_rgba8 */
+
+#ifndef GL_ARM_shader_framebuffer_fetch
+#define GL_ARM_shader_framebuffer_fetch 1
+#define GL_FETCH_PER_SAMPLE_ARM 0x8F65
+#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66
+#endif /* GL_ARM_shader_framebuffer_fetch */
+
+#ifndef GL_ARM_shader_framebuffer_fetch_depth_stencil
+#define GL_ARM_shader_framebuffer_fetch_depth_stencil 1
+#endif /* GL_ARM_shader_framebuffer_fetch_depth_stencil */
+
+#ifndef GL_ARM_texture_unnormalized_coordinates
+#define GL_ARM_texture_unnormalized_coordinates 1
+#define GL_TEXTURE_UNNORMALIZED_COORDINATES_ARM 0x8F6A
+#endif /* GL_ARM_texture_unnormalized_coordinates */
+
+#ifndef GL_DMP_program_binary
+#define GL_DMP_program_binary 1
+#define GL_SMAPHS30_PROGRAM_BINARY_DMP 0x9251
+#define GL_SMAPHS_PROGRAM_BINARY_DMP 0x9252
+#define GL_DMP_PROGRAM_BINARY_DMP 0x9253
+#endif /* GL_DMP_program_binary */
+
+#ifndef GL_DMP_shader_binary
+#define GL_DMP_shader_binary 1
+#define GL_SHADER_BINARY_DMP 0x9250
+#endif /* GL_DMP_shader_binary */
+
+#ifndef GL_EXT_EGL_image_array
+#define GL_EXT_EGL_image_array 1
+#endif /* GL_EXT_EGL_image_array */
+
+#ifndef GL_EXT_EGL_image_storage
+#define GL_EXT_EGL_image_storage 1
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC) (GLenum target, GLeglImageOES image, const GLint* attrib_list);
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC) (GLuint texture, GLeglImageOES image, const GLint* attrib_list);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEGLImageTargetTexStorageEXT (GLenum target, GLeglImageOES image, const GLint* attrib_list);
+GL_APICALL void GL_APIENTRY glEGLImageTargetTextureStorageEXT (GLuint texture, GLeglImageOES image, const GLint* attrib_list);
+#endif
+#endif /* GL_EXT_EGL_image_storage */
+
+#ifndef GL_EXT_YUV_target
+#define GL_EXT_YUV_target 1
+#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7
+#endif /* GL_EXT_YUV_target */
+
+#ifndef GL_EXT_base_instance
+#define GL_EXT_base_instance 1
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedBaseInstanceEXT (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseInstanceEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
+#endif
+#endif /* GL_EXT_base_instance */
+
+#ifndef GL_EXT_blend_func_extended
+#define GL_EXT_blend_func_extended 1
+#define GL_SRC1_COLOR_EXT 0x88F9
+#define GL_SRC1_ALPHA_EXT 0x8589
+#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA
+#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB
+#define GL_SRC_ALPHA_SATURATE_EXT 0x0308
+#define GL_LOCATION_INDEX_EXT 0x930F
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC
+typedef void (GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC) (GLuint program, GLenum programInterface, const GLchar *name);
+typedef GLint (GL_APIENTRYP PFNGLGETFRAGDATAINDEXEXTPROC) (GLuint program, const GLchar *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBindFragDataLocationIndexedEXT (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+GL_APICALL void GL_APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name);
+GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocationIndexEXT (GLuint program, GLenum programInterface, const GLchar *name);
+GL_APICALL GLint GL_APIENTRY glGetFragDataIndexEXT (GLuint program, const GLchar *name);
+#endif
+#endif /* GL_EXT_blend_func_extended */
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#define GL_MIN_EXT 0x8007
+#define GL_MAX_EXT 0x8008
+#endif /* GL_EXT_blend_minmax */
+
+#ifndef GL_EXT_buffer_storage
+#define GL_EXT_buffer_storage 1
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_PERSISTENT_BIT_EXT 0x0040
+#define GL_MAP_COHERENT_BIT_EXT 0x0080
+#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100
+#define GL_CLIENT_STORAGE_BIT_EXT 0x0200
+#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000
+#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F
+#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220
+typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEEXTPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBufferStorageEXT (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);
+#endif
+#endif /* GL_EXT_buffer_storage */
+
+#ifndef GL_EXT_clear_texture
+#define GL_EXT_clear_texture 1
+typedef void (GL_APIENTRYP PFNGLCLEARTEXIMAGEEXTPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);
+typedef void (GL_APIENTRYP PFNGLCLEARTEXSUBIMAGEEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glClearTexImageEXT (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);
+GL_APICALL void GL_APIENTRY glClearTexSubImageEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
+#endif
+#endif /* GL_EXT_clear_texture */
+
+#ifndef GL_EXT_clip_control
+#define GL_EXT_clip_control 1
+#define GL_LOWER_LEFT_EXT 0x8CA1
+#define GL_UPPER_LEFT_EXT 0x8CA2
+#define GL_NEGATIVE_ONE_TO_ONE_EXT 0x935E
+#define GL_ZERO_TO_ONE_EXT 0x935F
+#define GL_CLIP_ORIGIN_EXT 0x935C
+#define GL_CLIP_DEPTH_MODE_EXT 0x935D
+typedef void (GL_APIENTRYP PFNGLCLIPCONTROLEXTPROC) (GLenum origin, GLenum depth);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glClipControlEXT (GLenum origin, GLenum depth);
+#endif
+#endif /* GL_EXT_clip_control */
+
+#ifndef GL_EXT_clip_cull_distance
+#define GL_EXT_clip_cull_distance 1
+#define GL_MAX_CLIP_DISTANCES_EXT 0x0D32
+#define GL_MAX_CULL_DISTANCES_EXT 0x82F9
+#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT 0x82FA
+#define GL_CLIP_DISTANCE0_EXT 0x3000
+#define GL_CLIP_DISTANCE1_EXT 0x3001
+#define GL_CLIP_DISTANCE2_EXT 0x3002
+#define GL_CLIP_DISTANCE3_EXT 0x3003
+#define GL_CLIP_DISTANCE4_EXT 0x3004
+#define GL_CLIP_DISTANCE5_EXT 0x3005
+#define GL_CLIP_DISTANCE6_EXT 0x3006
+#define GL_CLIP_DISTANCE7_EXT 0x3007
+#endif /* GL_EXT_clip_cull_distance */
+
+#ifndef GL_EXT_color_buffer_float
+#define GL_EXT_color_buffer_float 1
+#endif /* GL_EXT_color_buffer_float */
+
+#ifndef GL_EXT_color_buffer_half_float
+#define GL_EXT_color_buffer_half_float 1
+#define GL_RGBA16F_EXT 0x881A
+#define GL_RGB16F_EXT 0x881B
+#define GL_RG16F_EXT 0x822F
+#define GL_R16F_EXT 0x822D
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211
+#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17
+#endif /* GL_EXT_color_buffer_half_float */
+
+#ifndef GL_EXT_conservative_depth
+#define GL_EXT_conservative_depth 1
+#endif /* GL_EXT_conservative_depth */
+
+#ifndef GL_EXT_copy_image
+#define GL_EXT_copy_image 1
+typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAEXTPROC) (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);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL 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);
+#endif
+#endif /* GL_EXT_copy_image */
+
+#ifndef GL_EXT_debug_label
+#define GL_EXT_debug_label 1
+#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F
+#define GL_PROGRAM_OBJECT_EXT 0x8B40
+#define GL_SHADER_OBJECT_EXT 0x8B48
+#define GL_BUFFER_OBJECT_EXT 0x9151
+#define GL_QUERY_OBJECT_EXT 0x9153
+#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
+#endif
+#endif /* GL_EXT_debug_label */
+
+#ifndef GL_EXT_debug_marker
+#define GL_EXT_debug_marker 1
+typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker);
+typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker);
+typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker);
+GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker);
+GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void);
+#endif
+#endif /* GL_EXT_debug_marker */
+
+#ifndef GL_EXT_depth_clamp
+#define GL_EXT_depth_clamp 1
+#define GL_DEPTH_CLAMP_EXT 0x864F
+#endif /* GL_EXT_depth_clamp */
+
+#ifndef GL_EXT_discard_framebuffer
+#define GL_EXT_discard_framebuffer 1
+#define GL_COLOR_EXT 0x1800
+#define GL_DEPTH_EXT 0x1801
+#define GL_STENCIL_EXT 0x1802
+typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#endif
+#endif /* GL_EXT_discard_framebuffer */
+
+#ifndef GL_EXT_disjoint_timer_query
+#define GL_EXT_disjoint_timer_query 1
+#define GL_QUERY_COUNTER_BITS_EXT 0x8864
+#define GL_CURRENT_QUERY_EXT 0x8865
+#define GL_QUERY_RESULT_EXT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867
+#define GL_TIME_ELAPSED_EXT 0x88BF
+#define GL_TIMESTAMP_EXT 0x8E28
+#define GL_GPU_DISJOINT_EXT 0x8FBB
+typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids);
+typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id);
+typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id);
+typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLQUERYCOUNTEREXTPROC) (GLuint id, GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64VEXTPROC) (GLenum pname, GLint64 *data);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids);
+GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids);
+GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id);
+GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target);
+GL_APICALL void GL_APIENTRY glQueryCounterEXT (GLuint id, GLenum target);
+GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectivEXT (GLuint id, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params);
+GL_APICALL void GL_APIENTRY glGetInteger64vEXT (GLenum pname, GLint64 *data);
+#endif
+#endif /* GL_EXT_disjoint_timer_query */
+
+#ifndef GL_EXT_draw_buffers
+#define GL_EXT_draw_buffers 1
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#define GL_MAX_DRAW_BUFFERS_EXT 0x8824
+#define GL_DRAW_BUFFER0_EXT 0x8825
+#define GL_DRAW_BUFFER1_EXT 0x8826
+#define GL_DRAW_BUFFER2_EXT 0x8827
+#define GL_DRAW_BUFFER3_EXT 0x8828
+#define GL_DRAW_BUFFER4_EXT 0x8829
+#define GL_DRAW_BUFFER5_EXT 0x882A
+#define GL_DRAW_BUFFER6_EXT 0x882B
+#define GL_DRAW_BUFFER7_EXT 0x882C
+#define GL_DRAW_BUFFER8_EXT 0x882D
+#define GL_DRAW_BUFFER9_EXT 0x882E
+#define GL_DRAW_BUFFER10_EXT 0x882F
+#define GL_DRAW_BUFFER11_EXT 0x8830
+#define GL_DRAW_BUFFER12_EXT 0x8831
+#define GL_DRAW_BUFFER13_EXT 0x8832
+#define GL_DRAW_BUFFER14_EXT 0x8833
+#define GL_DRAW_BUFFER15_EXT 0x8834
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs);
+#endif
+#endif /* GL_EXT_draw_buffers */
+
+#ifndef GL_EXT_draw_buffers_indexed
+#define GL_EXT_draw_buffers_indexed 1
+typedef void (GL_APIENTRYP PFNGLENABLEIEXTPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLDISABLEIEXTPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIEXTPROC) (GLuint buf, GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIEXTPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCIEXTPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIEXTPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKIEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIEXTPROC) (GLenum target, GLuint index);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEnableiEXT (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glDisableiEXT (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glBlendEquationiEXT (GLuint buf, GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparateiEXT (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunciEXT (GLuint buf, GLenum src, GLenum dst);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparateiEXT (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GL_APICALL void GL_APIENTRY glColorMaskiEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GL_APICALL GLboolean GL_APIENTRY glIsEnablediEXT (GLenum target, GLuint index);
+#endif
+#endif /* GL_EXT_draw_buffers_indexed */
+
+#ifndef GL_EXT_draw_elements_base_vertex
+#define GL_EXT_draw_elements_base_vertex 1
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+#endif
+#endif /* GL_EXT_draw_elements_base_vertex */
+
+#ifndef GL_EXT_draw_instanced
+#define GL_EXT_draw_instanced 1
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+#endif
+#endif /* GL_EXT_draw_instanced */
+
+#ifndef GL_EXT_draw_transform_feedback
+#define GL_EXT_draw_transform_feedback 1
+typedef void (GL_APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKEXTPROC) (GLenum mode, GLuint id);
+typedef void (GL_APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDEXTPROC) (GLenum mode, GLuint id, GLsizei instancecount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawTransformFeedbackEXT (GLenum mode, GLuint id);
+GL_APICALL void GL_APIENTRY glDrawTransformFeedbackInstancedEXT (GLenum mode, GLuint id, GLsizei instancecount);
+#endif
+#endif /* GL_EXT_draw_transform_feedback */
+
+#ifndef GL_EXT_external_buffer
+#define GL_EXT_external_buffer 1
+typedef void *GLeglClientBufferEXT;
+typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEEXTERNALEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBufferStorageExternalEXT (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+GL_APICALL void GL_APIENTRY glNamedBufferStorageExternalEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+#endif
+#endif /* GL_EXT_external_buffer */
+
+#ifndef GL_EXT_float_blend
+#define GL_EXT_float_blend 1
+#endif /* GL_EXT_float_blend */
+
+#ifndef GL_EXT_geometry_point_size
+#define GL_EXT_geometry_point_size 1
+#endif /* GL_EXT_geometry_point_size */
+
+#ifndef GL_EXT_geometry_shader
+#define GL_EXT_geometry_shader 1
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004
+#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916
+#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917
+#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918
+#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F
+#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E
+#define GL_LINES_ADJACENCY_EXT 0x000A
+#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B
+#define GL_TRIANGLES_ADJACENCY_EXT 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7
+#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define GL_UNDEFINED_VERTEX_EXT 0x8260
+#define GL_PRIMITIVES_GENERATED_EXT 0x8C87
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312
+#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif
+#endif /* GL_EXT_geometry_shader */
+
+#ifndef GL_EXT_gpu_shader5
+#define GL_EXT_gpu_shader5 1
+#endif /* GL_EXT_gpu_shader5 */
+
+#ifndef GL_EXT_instanced_arrays
+#define GL_EXT_instanced_arrays 1
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorEXT (GLuint index, GLuint divisor);
+#endif
+#endif /* GL_EXT_instanced_arrays */
+
+#ifndef GL_EXT_map_buffer_range
+#define GL_EXT_map_buffer_range 1
+#define GL_MAP_READ_BIT_EXT 0x0001
+#define GL_MAP_WRITE_BIT_EXT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020
+typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void *GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif
+#endif /* GL_EXT_map_buffer_range */
+
+#ifndef GL_EXT_memory_object
+#define GL_EXT_memory_object 1
+#define GL_TEXTURE_TILING_EXT 0x9580
+#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581
+#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B
+#define GL_NUM_TILING_TYPES_EXT 0x9582
+#define GL_TILING_TYPES_EXT 0x9583
+#define GL_OPTIMAL_TILING_EXT 0x9584
+#define GL_LINEAR_TILING_EXT 0x9585
+#define GL_NUM_DEVICE_UUIDS_EXT 0x9596
+#define GL_DEVICE_UUID_EXT 0x9597
+#define GL_DRIVER_UUID_EXT 0x9598
+#define GL_UUID_SIZE_EXT 16
+typedef void (GL_APIENTRYP PFNGLGETUNSIGNEDBYTEVEXTPROC) (GLenum pname, GLubyte *data);
+typedef void (GL_APIENTRYP PFNGLGETUNSIGNEDBYTEI_VEXTPROC) (GLenum target, GLuint index, GLubyte *data);
+typedef void (GL_APIENTRYP PFNGLDELETEMEMORYOBJECTSEXTPROC) (GLsizei n, const GLuint *memoryObjects);
+typedef GLboolean (GL_APIENTRYP PFNGLISMEMORYOBJECTEXTPROC) (GLuint memoryObject);
+typedef void (GL_APIENTRYP PFNGLCREATEMEMORYOBJECTSEXTPROC) (GLsizei n, GLuint *memoryObjects);
+typedef void (GL_APIENTRYP PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEMEMEXTPROC) (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM2DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM3DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetUnsignedBytevEXT (GLenum pname, GLubyte *data);
+GL_APICALL void GL_APIENTRY glGetUnsignedBytei_vEXT (GLenum target, GLuint index, GLubyte *data);
+GL_APICALL void GL_APIENTRY glDeleteMemoryObjectsEXT (GLsizei n, const GLuint *memoryObjects);
+GL_APICALL GLboolean GL_APIENTRY glIsMemoryObjectEXT (GLuint memoryObject);
+GL_APICALL void GL_APIENTRY glCreateMemoryObjectsEXT (GLsizei n, GLuint *memoryObjects);
+GL_APICALL void GL_APIENTRY glMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glGetMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glTexStorageMem2DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTexStorageMem2DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTexStorageMem3DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTexStorageMem3DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glBufferStorageMemEXT (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem2DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem2DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem3DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem3DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glNamedBufferStorageMemEXT (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset);
+#endif
+#endif /* GL_EXT_memory_object */
+
+#ifndef GL_EXT_memory_object_fd
+#define GL_EXT_memory_object_fd 1
+#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586
+typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYFDEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, GLint fd);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportMemoryFdEXT (GLuint memory, GLuint64 size, GLenum handleType, GLint fd);
+#endif
+#endif /* GL_EXT_memory_object_fd */
+
+#ifndef GL_EXT_memory_object_win32
+#define GL_EXT_memory_object_win32 1
+#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587
+#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588
+#define GL_DEVICE_LUID_EXT 0x9599
+#define GL_DEVICE_NODE_MASK_EXT 0x959A
+#define GL_LUID_SIZE_EXT 8
+#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589
+#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A
+#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B
+#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C
+typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, void *handle);
+typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, const void *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportMemoryWin32HandleEXT (GLuint memory, GLuint64 size, GLenum handleType, void *handle);
+GL_APICALL void GL_APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 size, GLenum handleType, const void *name);
+#endif
+#endif /* GL_EXT_memory_object_win32 */
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount);
+#endif
+#endif /* GL_EXT_multi_draw_arrays */
+
+#ifndef GL_EXT_multi_draw_indirect
+#define GL_EXT_multi_draw_indirect 1
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMultiDrawArraysIndirectEXT (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsIndirectEXT (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);
+#endif
+#endif /* GL_EXT_multi_draw_indirect */
+
+#ifndef GL_EXT_multisampled_compatibility
+#define GL_EXT_multisampled_compatibility 1
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#endif /* GL_EXT_multisampled_compatibility */
+
+#ifndef GL_EXT_multisampled_render_to_texture
+#define GL_EXT_multisampled_render_to_texture 1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+#endif /* GL_EXT_multisampled_render_to_texture */
+
+#ifndef GL_EXT_multisampled_render_to_texture2
+#define GL_EXT_multisampled_render_to_texture2 1
+#endif /* GL_EXT_multisampled_render_to_texture2 */
+
+#ifndef GL_EXT_multiview_draw_buffers
+#define GL_EXT_multiview_draw_buffers 1
+#define GL_COLOR_ATTACHMENT_EXT 0x90F0
+#define GL_MULTIVIEW_EXT 0x90F1
+#define GL_DRAW_BUFFER_EXT 0x0C01
+#define GL_READ_BUFFER_EXT 0x0C02
+#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2
+typedef void (GL_APIENTRYP PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index);
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum *location, const GLint *indices);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint *data);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glReadBufferIndexedEXT (GLenum src, GLint index);
+GL_APICALL void GL_APIENTRY glDrawBuffersIndexedEXT (GLint n, const GLenum *location, const GLint *indices);
+GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLint *data);
+#endif
+#endif /* GL_EXT_multiview_draw_buffers */
+
+#ifndef GL_EXT_multiview_tessellation_geometry_shader
+#define GL_EXT_multiview_tessellation_geometry_shader 1
+#endif /* GL_EXT_multiview_tessellation_geometry_shader */
+
+#ifndef GL_EXT_multiview_texture_multisample
+#define GL_EXT_multiview_texture_multisample 1
+#endif /* GL_EXT_multiview_texture_multisample */
+
+#ifndef GL_EXT_multiview_timer_query
+#define GL_EXT_multiview_timer_query 1
+#endif /* GL_EXT_multiview_timer_query */
+
+#ifndef GL_EXT_occlusion_query_boolean
+#define GL_EXT_occlusion_query_boolean 1
+#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A
+#endif /* GL_EXT_occlusion_query_boolean */
+
+#ifndef GL_EXT_polygon_offset_clamp
+#define GL_EXT_polygon_offset_clamp 1
+#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B
+typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETCLAMPEXTPROC) (GLfloat factor, GLfloat units, GLfloat clamp);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPolygonOffsetClampEXT (GLfloat factor, GLfloat units, GLfloat clamp);
+#endif
+#endif /* GL_EXT_polygon_offset_clamp */
+
+#ifndef GL_EXT_post_depth_coverage
+#define GL_EXT_post_depth_coverage 1
+#endif /* GL_EXT_post_depth_coverage */
+
+#ifndef GL_EXT_primitive_bounding_box
+#define GL_EXT_primitive_bounding_box 1
+#define GL_PRIMITIVE_BOUNDING_BOX_EXT 0x92BE
+typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXEXTPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxEXT (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+#endif
+#endif /* GL_EXT_primitive_bounding_box */
+
+#ifndef GL_EXT_protected_textures
+#define GL_EXT_protected_textures 1
+#define GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT 0x00000010
+#define GL_TEXTURE_PROTECTED_EXT 0x8BFA
+#endif /* GL_EXT_protected_textures */
+
+#ifndef GL_EXT_pvrtc_sRGB
+#define GL_EXT_pvrtc_sRGB 1
+#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54
+#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG 0x93F0
+#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG 0x93F1
+#endif /* GL_EXT_pvrtc_sRGB */
+
+#ifndef GL_EXT_raster_multisample
+#define GL_EXT_raster_multisample 1
+#define GL_RASTER_MULTISAMPLE_EXT 0x9327
+#define GL_RASTER_SAMPLES_EXT 0x9328
+#define GL_MAX_RASTER_SAMPLES_EXT 0x9329
+#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A
+#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B
+#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C
+typedef void (GL_APIENTRYP PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRasterSamplesEXT (GLuint samples, GLboolean fixedsamplelocations);
+#endif
+#endif /* GL_EXT_raster_multisample */
+
+#ifndef GL_EXT_read_format_bgra
+#define GL_EXT_read_format_bgra 1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366
+#endif /* GL_EXT_read_format_bgra */
+
+#ifndef GL_EXT_render_snorm
+#define GL_EXT_render_snorm 1
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM_EXT 0x8F98
+#define GL_RG16_SNORM_EXT 0x8F99
+#define GL_RGBA16_SNORM_EXT 0x8F9B
+#endif /* GL_EXT_render_snorm */
+
+#ifndef GL_EXT_robustness
+#define GL_EXT_robustness 1
+#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255
+#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3
+#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256
+#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252
+#define GL_NO_RESET_NOTIFICATION_EXT 0x8261
+typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void);
+GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#endif
+#endif /* GL_EXT_robustness */
+
+#ifndef GL_EXT_sRGB
+#define GL_EXT_sRGB 1
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210
+#endif /* GL_EXT_sRGB */
+
+#ifndef GL_EXT_sRGB_write_control
+#define GL_EXT_sRGB_write_control 1
+#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+#endif /* GL_EXT_sRGB_write_control */
+
+#ifndef GL_EXT_semaphore
+#define GL_EXT_semaphore 1
+#define GL_LAYOUT_GENERAL_EXT 0x958D
+#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E
+#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F
+#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590
+#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591
+#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592
+#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593
+#define GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT 0x9530
+#define GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT 0x9531
+typedef void (GL_APIENTRYP PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint *semaphores);
+typedef void (GL_APIENTRYP PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint *semaphores);
+typedef GLboolean (GL_APIENTRYP PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore);
+typedef void (GL_APIENTRYP PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, const GLuint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, GLuint64 *params);
+typedef void (GL_APIENTRYP PFNGLWAITSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts);
+typedef void (GL_APIENTRYP PFNGLSIGNALSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGenSemaphoresEXT (GLsizei n, GLuint *semaphores);
+GL_APICALL void GL_APIENTRY glDeleteSemaphoresEXT (GLsizei n, const GLuint *semaphores);
+GL_APICALL GLboolean GL_APIENTRY glIsSemaphoreEXT (GLuint semaphore);
+GL_APICALL void GL_APIENTRY glSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, const GLuint64 *params);
+GL_APICALL void GL_APIENTRY glGetSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, GLuint64 *params);
+GL_APICALL void GL_APIENTRY glWaitSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts);
+GL_APICALL void GL_APIENTRY glSignalSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts);
+#endif
+#endif /* GL_EXT_semaphore */
+
+#ifndef GL_EXT_semaphore_fd
+#define GL_EXT_semaphore_fd 1
+typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREFDEXTPROC) (GLuint semaphore, GLenum handleType, GLint fd);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportSemaphoreFdEXT (GLuint semaphore, GLenum handleType, GLint fd);
+#endif
+#endif /* GL_EXT_semaphore_fd */
+
+#ifndef GL_EXT_semaphore_win32
+#define GL_EXT_semaphore_win32 1
+#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594
+#define GL_D3D12_FENCE_VALUE_EXT 0x9595
+typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) (GLuint semaphore, GLenum handleType, void *handle);
+typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) (GLuint semaphore, GLenum handleType, const void *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportSemaphoreWin32HandleEXT (GLuint semaphore, GLenum handleType, void *handle);
+GL_APICALL void GL_APIENTRY glImportSemaphoreWin32NameEXT (GLuint semaphore, GLenum handleType, const void *name);
+#endif
+#endif /* GL_EXT_semaphore_win32 */
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+#define GL_ACTIVE_PROGRAM_EXT 0x8259
+#define GL_VERTEX_SHADER_BIT_EXT 0x00000001
+#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002
+#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF
+#define GL_PROGRAM_SEPARABLE_EXT 0x8258
+#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A
+typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program);
+typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings);
+typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines);
+typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params);
+typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program);
+GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline);
+GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings);
+GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines);
+GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params);
+GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0);
+GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0);
+GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1);
+GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program);
+GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0);
+GL_APICALL void GL_APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1);
+GL_APICALL void GL_APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void GL_APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void GL_APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif
+#endif /* GL_EXT_separate_shader_objects */
+
+#ifndef GL_EXT_shader_framebuffer_fetch
+#define GL_EXT_shader_framebuffer_fetch 1
+#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
+#endif /* GL_EXT_shader_framebuffer_fetch */
+
+#ifndef GL_EXT_shader_framebuffer_fetch_non_coherent
+#define GL_EXT_shader_framebuffer_fetch_non_coherent 1
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferFetchBarrierEXT (void);
+#endif
+#endif /* GL_EXT_shader_framebuffer_fetch_non_coherent */
+
+#ifndef GL_EXT_shader_group_vote
+#define GL_EXT_shader_group_vote 1
+#endif /* GL_EXT_shader_group_vote */
+
+#ifndef GL_EXT_shader_implicit_conversions
+#define GL_EXT_shader_implicit_conversions 1
+#endif /* GL_EXT_shader_implicit_conversions */
+
+#ifndef GL_EXT_shader_integer_mix
+#define GL_EXT_shader_integer_mix 1
+#endif /* GL_EXT_shader_integer_mix */
+
+#ifndef GL_EXT_shader_io_blocks
+#define GL_EXT_shader_io_blocks 1
+#endif /* GL_EXT_shader_io_blocks */
+
+#ifndef GL_EXT_shader_non_constant_global_initializers
+#define GL_EXT_shader_non_constant_global_initializers 1
+#endif /* GL_EXT_shader_non_constant_global_initializers */
+
+#ifndef GL_EXT_shader_pixel_local_storage
+#define GL_EXT_shader_pixel_local_storage 1
+#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63
+#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67
+#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64
+#endif /* GL_EXT_shader_pixel_local_storage */
+
+#ifndef GL_EXT_shader_pixel_local_storage2
+#define GL_EXT_shader_pixel_local_storage2 1
+#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT 0x9650
+#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT 0x9651
+#define GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT 0x9652
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target, GLsizei size);
+typedef GLsizei (GL_APIENTRYP PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target);
+typedef void (GL_APIENTRYP PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC) (GLsizei offset, GLsizei n, const GLuint *values);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferPixelLocalStorageSizeEXT (GLuint target, GLsizei size);
+GL_APICALL GLsizei GL_APIENTRY glGetFramebufferPixelLocalStorageSizeEXT (GLuint target);
+GL_APICALL void GL_APIENTRY glClearPixelLocalStorageuiEXT (GLsizei offset, GLsizei n, const GLuint *values);
+#endif
+#endif /* GL_EXT_shader_pixel_local_storage2 */
+
+#ifndef GL_EXT_shader_texture_lod
+#define GL_EXT_shader_texture_lod 1
+#endif /* GL_EXT_shader_texture_lod */
+
+#ifndef GL_EXT_shadow_samplers
+#define GL_EXT_shadow_samplers 1
+#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C
+#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D
+#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E
+#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62
+#endif /* GL_EXT_shadow_samplers */
+
+#ifndef GL_EXT_sparse_texture
+#define GL_EXT_sparse_texture 1
+#define GL_TEXTURE_SPARSE_EXT 0x91A6
+#define GL_VIRTUAL_PAGE_SIZE_INDEX_EXT 0x91A7
+#define GL_NUM_SPARSE_LEVELS_EXT 0x91AA
+#define GL_NUM_VIRTUAL_PAGE_SIZES_EXT 0x91A8
+#define GL_VIRTUAL_PAGE_SIZE_X_EXT 0x9195
+#define GL_VIRTUAL_PAGE_SIZE_Y_EXT 0x9196
+#define GL_VIRTUAL_PAGE_SIZE_Z_EXT 0x9197
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_3D 0x806F
+#define GL_MAX_SPARSE_TEXTURE_SIZE_EXT 0x9198
+#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT 0x9199
+#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT 0x919A
+#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT 0x91A9
+typedef void (GL_APIENTRYP PFNGLTEXPAGECOMMITMENTEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexPageCommitmentEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit);
+#endif
+#endif /* GL_EXT_sparse_texture */
+
+#ifndef GL_EXT_sparse_texture2
+#define GL_EXT_sparse_texture2 1
+#endif /* GL_EXT_sparse_texture2 */
+
+#ifndef GL_EXT_tessellation_point_size
+#define GL_EXT_tessellation_point_size 1
+#endif /* GL_EXT_tessellation_point_size */
+
+#ifndef GL_EXT_tessellation_shader
+#define GL_EXT_tessellation_shader 1
+#define GL_PATCHES_EXT 0x000E
+#define GL_PATCH_VERTICES_EXT 0x8E72
+#define GL_TESS_CONTROL_OUTPUT_VERTICES_EXT 0x8E75
+#define GL_TESS_GEN_MODE_EXT 0x8E76
+#define GL_TESS_GEN_SPACING_EXT 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER_EXT 0x8E78
+#define GL_TESS_GEN_POINT_MODE_EXT 0x8E79
+#define GL_ISOLINES_EXT 0x8E7A
+#define GL_QUADS_EXT 0x0007
+#define GL_FRACTIONAL_ODD_EXT 0x8E7B
+#define GL_FRACTIONAL_EVEN_EXT 0x8E7C
+#define GL_MAX_PATCH_VERTICES_EXT 0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL_EXT 0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS_EXT 0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT 0x8E86
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT 0x8E8A
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E1F
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT 0x92CD
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT 0x92CE
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT 0x92D3
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT 0x92D4
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT 0x90CB
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT 0x90CC
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT 0x90D9
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221
+#define GL_IS_PER_PATCH_EXT 0x92E7
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT 0x9308
+#define GL_TESS_CONTROL_SHADER_EXT 0x8E88
+#define GL_TESS_EVALUATION_SHADER_EXT 0x8E87
+#define GL_TESS_CONTROL_SHADER_BIT_EXT 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT_EXT 0x00000010
+typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIEXTPROC) (GLenum pname, GLint value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPatchParameteriEXT (GLenum pname, GLint value);
+#endif
+#endif /* GL_EXT_tessellation_shader */
+
+#ifndef GL_EXT_texture_border_clamp
+#define GL_EXT_texture_border_clamp 1
+#define GL_TEXTURE_BORDER_COLOR_EXT 0x1004
+#define GL_CLAMP_TO_BORDER_EXT 0x812D
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, const GLuint *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, GLuint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glSamplerParameterIivEXT (GLuint sampler, GLenum pname, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterIuivEXT (GLuint sampler, GLenum pname, const GLuint *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIivEXT (GLuint sampler, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivEXT (GLuint sampler, GLenum pname, GLuint *params);
+#endif
+#endif /* GL_EXT_texture_border_clamp */
+
+#ifndef GL_EXT_texture_buffer
+#define GL_EXT_texture_buffer 1
+#define GL_TEXTURE_BUFFER_EXT 0x8C2A
+#define GL_TEXTURE_BUFFER_BINDING_EXT 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT 0x919F
+#define GL_SAMPLER_BUFFER_EXT 0x8DC2
+#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+#define GL_IMAGE_BUFFER_EXT 0x9051
+#define GL_INT_IMAGE_BUFFER_EXT 0x905C
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067
+#define GL_TEXTURE_BUFFER_OFFSET_EXT 0x919D
+#define GL_TEXTURE_BUFFER_SIZE_EXT 0x919E
+typedef void (GL_APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEEXTPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer);
+GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#endif
+#endif /* GL_EXT_texture_buffer */
+
+#ifndef GL_EXT_texture_compression_astc_decode_mode
+#define GL_EXT_texture_compression_astc_decode_mode 1
+#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69
+#endif /* GL_EXT_texture_compression_astc_decode_mode */
+
+#ifndef GL_EXT_texture_compression_bptc
+#define GL_EXT_texture_compression_bptc 1
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_EXT 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT 0x8E8F
+#endif /* GL_EXT_texture_compression_bptc */
+
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#endif /* GL_EXT_texture_compression_dxt1 */
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_EXT_texture_compression_rgtc 1
+#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+#endif /* GL_EXT_texture_compression_rgtc */
+
+#ifndef GL_EXT_texture_compression_s3tc
+#define GL_EXT_texture_compression_s3tc 1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+#endif /* GL_EXT_texture_compression_s3tc */
+
+#ifndef GL_EXT_texture_compression_s3tc_srgb
+#define GL_EXT_texture_compression_s3tc_srgb 1
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#endif /* GL_EXT_texture_compression_s3tc_srgb */
+
+#ifndef GL_EXT_texture_cube_map_array
+#define GL_EXT_texture_cube_map_array 1
+#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT 0x900A
+#define GL_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900F
+#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+#endif /* GL_EXT_texture_cube_map_array */
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#endif /* GL_EXT_texture_filter_anisotropic */
+
+#ifndef GL_EXT_texture_filter_minmax
+#define GL_EXT_texture_filter_minmax 1
+#define GL_TEXTURE_REDUCTION_MODE_EXT 0x9366
+#define GL_WEIGHTED_AVERAGE_EXT 0x9367
+#endif /* GL_EXT_texture_filter_minmax */
+
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_EXT_texture_format_BGRA8888 1
+#endif /* GL_EXT_texture_format_BGRA8888 */
+
+#ifndef GL_EXT_texture_format_sRGB_override
+#define GL_EXT_texture_format_sRGB_override 1
+#define GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT 0x8FBF
+#endif /* GL_EXT_texture_format_sRGB_override */
+
+#ifndef GL_EXT_texture_mirror_clamp_to_edge
+#define GL_EXT_texture_mirror_clamp_to_edge 1
+#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
+#endif /* GL_EXT_texture_mirror_clamp_to_edge */
+
+#ifndef GL_EXT_texture_norm16
+#define GL_EXT_texture_norm16 1
+#define GL_R16_EXT 0x822A
+#define GL_RG16_EXT 0x822C
+#define GL_RGBA16_EXT 0x805B
+#define GL_RGB16_EXT 0x8054
+#define GL_RGB16_SNORM_EXT 0x8F9A
+#endif /* GL_EXT_texture_norm16 */
+
+#ifndef GL_EXT_texture_query_lod
+#define GL_EXT_texture_query_lod 1
+#endif /* GL_EXT_texture_query_lod */
+
+#ifndef GL_EXT_texture_rg
+#define GL_EXT_texture_rg 1
+#define GL_RED_EXT 0x1903
+#define GL_RG_EXT 0x8227
+#define GL_R8_EXT 0x8229
+#define GL_RG8_EXT 0x822B
+#endif /* GL_EXT_texture_rg */
+
+#ifndef GL_EXT_texture_sRGB_R8
+#define GL_EXT_texture_sRGB_R8 1
+#define GL_SR8_EXT 0x8FBD
+#endif /* GL_EXT_texture_sRGB_R8 */
+
+#ifndef GL_EXT_texture_sRGB_RG8
+#define GL_EXT_texture_sRGB_RG8 1
+#define GL_SRG8_EXT 0x8FBE
+#endif /* GL_EXT_texture_sRGB_RG8 */
+
+#ifndef GL_EXT_texture_sRGB_decode
+#define GL_EXT_texture_sRGB_decode 1
+#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
+#define GL_DECODE_EXT 0x8A49
+#define GL_SKIP_DECODE_EXT 0x8A4A
+#endif /* GL_EXT_texture_sRGB_decode */
+
+#ifndef GL_EXT_texture_shadow_lod
+#define GL_EXT_texture_shadow_lod 1
+#endif /* GL_EXT_texture_shadow_lod */
+
+#ifndef GL_EXT_texture_storage
+#define GL_EXT_texture_storage 1
+#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F
+#define GL_ALPHA8_EXT 0x803C
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_RGBA32F_EXT 0x8814
+#define GL_RGB32F_EXT 0x8815
+#define GL_ALPHA32F_EXT 0x8816
+#define GL_LUMINANCE32F_EXT 0x8818
+#define GL_LUMINANCE_ALPHA32F_EXT 0x8819
+#define GL_ALPHA16F_EXT 0x881C
+#define GL_LUMINANCE16F_EXT 0x881E
+#define GL_LUMINANCE_ALPHA16F_EXT 0x881F
+#define GL_R32F_EXT 0x822E
+#define GL_RG32F_EXT 0x8230
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+#endif /* GL_EXT_texture_storage */
+
+#ifndef GL_EXT_texture_type_2_10_10_10_REV
+#define GL_EXT_texture_type_2_10_10_10_REV 1
+#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
+#endif /* GL_EXT_texture_type_2_10_10_10_REV */
+
+#ifndef GL_EXT_texture_view
+#define GL_EXT_texture_view 1
+#define GL_TEXTURE_VIEW_MIN_LEVEL_EXT 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT 0x82DC
+#define GL_TEXTURE_VIEW_MIN_LAYER_EXT 0x82DD
+#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT 0x82DE
+typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWEXTPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTextureViewEXT (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#endif
+#endif /* GL_EXT_texture_view */
+
+#ifndef GL_EXT_unpack_subimage
+#define GL_EXT_unpack_subimage 1
+#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2
+#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4
+#endif /* GL_EXT_unpack_subimage */
+
+#ifndef GL_EXT_win32_keyed_mutex
+#define GL_EXT_win32_keyed_mutex 1
+typedef GLboolean (GL_APIENTRYP PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key, GLuint timeout);
+typedef GLboolean (GL_APIENTRYP PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLboolean GL_APIENTRY glAcquireKeyedMutexWin32EXT (GLuint memory, GLuint64 key, GLuint timeout);
+GL_APICALL GLboolean GL_APIENTRY glReleaseKeyedMutexWin32EXT (GLuint memory, GLuint64 key);
+#endif
+#endif /* GL_EXT_win32_keyed_mutex */
+
+#ifndef GL_EXT_window_rectangles
+#define GL_EXT_window_rectangles 1
+#define GL_INCLUSIVE_EXT 0x8F10
+#define GL_EXCLUSIVE_EXT 0x8F11
+#define GL_WINDOW_RECTANGLE_EXT 0x8F12
+#define GL_WINDOW_RECTANGLE_MODE_EXT 0x8F13
+#define GL_MAX_WINDOW_RECTANGLES_EXT 0x8F14
+#define GL_NUM_WINDOW_RECTANGLES_EXT 0x8F15
+typedef void (GL_APIENTRYP PFNGLWINDOWRECTANGLESEXTPROC) (GLenum mode, GLsizei count, const GLint *box);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glWindowRectanglesEXT (GLenum mode, GLsizei count, const GLint *box);
+#endif
+#endif /* GL_EXT_window_rectangles */
+
+#ifndef GL_FJ_shader_binary_GCCSO
+#define GL_FJ_shader_binary_GCCSO 1
+#define GL_GCCSO_SHADER_BINARY_FJ 0x9260
+#endif /* GL_FJ_shader_binary_GCCSO */
+
+#ifndef GL_IMG_bindless_texture
+#define GL_IMG_bindless_texture 1
+typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLEIMGPROC) (GLuint texture);
+typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEIMGPROC) (GLuint texture, GLuint sampler);
+typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64IMGPROC) (GLint location, GLuint64 value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64VIMGPROC) (GLint location, GLsizei count, const GLuint64 *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64IMGPROC) (GLuint program, GLint location, GLuint64 value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VIMGPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLuint64 GL_APIENTRY glGetTextureHandleIMG (GLuint texture);
+GL_APICALL GLuint64 GL_APIENTRY glGetTextureSamplerHandleIMG (GLuint texture, GLuint sampler);
+GL_APICALL void GL_APIENTRY glUniformHandleui64IMG (GLint location, GLuint64 value);
+GL_APICALL void GL_APIENTRY glUniformHandleui64vIMG (GLint location, GLsizei count, const GLuint64 *value);
+GL_APICALL void GL_APIENTRY glProgramUniformHandleui64IMG (GLuint program, GLint location, GLuint64 value);
+GL_APICALL void GL_APIENTRY glProgramUniformHandleui64vIMG (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+#endif
+#endif /* GL_IMG_bindless_texture */
+
+#ifndef GL_IMG_framebuffer_downsample
+#define GL_IMG_framebuffer_downsample 1
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG 0x913C
+#define GL_NUM_DOWNSAMPLE_SCALES_IMG 0x913D
+#define GL_DOWNSAMPLE_SCALES_IMG 0x913E
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG 0x913F
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DDOWNSAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint xscale, GLint yscale);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERDOWNSAMPLEIMGPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer, GLint xscale, GLint yscale);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DDownsampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint xscale, GLint yscale);
+GL_APICALL void GL_APIENTRY glFramebufferTextureLayerDownsampleIMG (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer, GLint xscale, GLint yscale);
+#endif
+#endif /* GL_IMG_framebuffer_downsample */
+
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_IMG_multisampled_render_to_texture 1
+#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134
+#define GL_MAX_SAMPLES_IMG 0x9135
+#define GL_TEXTURE_SAMPLES_IMG 0x9136
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+#endif /* GL_IMG_multisampled_render_to_texture */
+
+#ifndef GL_IMG_program_binary
+#define GL_IMG_program_binary 1
+#define GL_SGX_PROGRAM_BINARY_IMG 0x9130
+#endif /* GL_IMG_program_binary */
+
+#ifndef GL_IMG_read_format
+#define GL_IMG_read_format 1
+#define GL_BGRA_IMG 0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365
+#endif /* GL_IMG_read_format */
+
+#ifndef GL_IMG_shader_binary
+#define GL_IMG_shader_binary 1
+#define GL_SGX_BINARY_IMG 0x8C0A
+#endif /* GL_IMG_shader_binary */
+
+#ifndef GL_IMG_texture_compression_pvrtc
+#define GL_IMG_texture_compression_pvrtc 1
+#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
+#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
+#endif /* GL_IMG_texture_compression_pvrtc */
+
+#ifndef GL_IMG_texture_compression_pvrtc2
+#define GL_IMG_texture_compression_pvrtc2 1
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
+#endif /* GL_IMG_texture_compression_pvrtc2 */
+
+#ifndef GL_IMG_texture_filter_cubic
+#define GL_IMG_texture_filter_cubic 1
+#define GL_CUBIC_IMG 0x9139
+#define GL_CUBIC_MIPMAP_NEAREST_IMG 0x913A
+#define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B
+#endif /* GL_IMG_texture_filter_cubic */
+
+#ifndef GL_INTEL_blackhole_render
+#define GL_INTEL_blackhole_render 1
+#define GL_BLACKHOLE_RENDER_INTEL 0x83FC
+#endif /* GL_INTEL_blackhole_render */
+
+#ifndef GL_INTEL_conservative_rasterization
+#define GL_INTEL_conservative_rasterization 1
+#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE
+#endif /* GL_INTEL_conservative_rasterization */
+
+#ifndef GL_INTEL_framebuffer_CMAA
+#define GL_INTEL_framebuffer_CMAA 1
+typedef void (GL_APIENTRYP PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glApplyFramebufferAttachmentCMAAINTEL (void);
+#endif
+#endif /* GL_INTEL_framebuffer_CMAA */
+
+#ifndef GL_INTEL_performance_query
+#define GL_INTEL_performance_query 1
+#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000
+#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001
+#define GL_PERFQUERY_WAIT_INTEL 0x83FB
+#define GL_PERFQUERY_FLUSH_INTEL 0x83FA
+#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9
+#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0
+#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1
+#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2
+#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3
+#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4
+#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5
+#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8
+#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9
+#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA
+#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB
+#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC
+#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD
+#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE
+#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF
+#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500
+typedef void (GL_APIENTRYP PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GL_APIENTRYP PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint *queryHandle);
+typedef void (GL_APIENTRYP PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GL_APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle);
+typedef void (GL_APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId);
+typedef void (GL_APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId);
+typedef void (GL_APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);
+typedef void (GL_APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten);
+typedef void (GL_APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId);
+typedef void (GL_APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBeginPerfQueryINTEL (GLuint queryHandle);
+GL_APICALL void GL_APIENTRY glCreatePerfQueryINTEL (GLuint queryId, GLuint *queryHandle);
+GL_APICALL void GL_APIENTRY glDeletePerfQueryINTEL (GLuint queryHandle);
+GL_APICALL void GL_APIENTRY glEndPerfQueryINTEL (GLuint queryHandle);
+GL_APICALL void GL_APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId);
+GL_APICALL void GL_APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId);
+GL_APICALL void GL_APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);
+GL_APICALL void GL_APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten);
+GL_APICALL void GL_APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId);
+GL_APICALL void GL_APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);
+#endif
+#endif /* GL_INTEL_performance_query */
+
+#ifndef GL_MESA_framebuffer_flip_x
+#define GL_MESA_framebuffer_flip_x 1
+#define GL_FRAMEBUFFER_FLIP_X_MESA 0x8BBC
+#endif /* GL_MESA_framebuffer_flip_x */
+
+#ifndef GL_MESA_framebuffer_flip_y
+#define GL_MESA_framebuffer_flip_y 1
+#define GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPARAMETERIMESAPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC) (GLenum target, GLenum pname, GLint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferParameteriMESA (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glGetFramebufferParameterivMESA (GLenum target, GLenum pname, GLint *params);
+#endif
+#endif /* GL_MESA_framebuffer_flip_y */
+
+#ifndef GL_MESA_framebuffer_swap_xy
+#define GL_MESA_framebuffer_swap_xy 1
+#define GL_FRAMEBUFFER_SWAP_XY_MESA 0x8BBD
+#endif /* GL_MESA_framebuffer_swap_xy */
+
+#ifndef GL_MESA_program_binary_formats
+#define GL_MESA_program_binary_formats 1
+#define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F
+#endif /* GL_MESA_program_binary_formats */
+
+#ifndef GL_MESA_shader_integer_functions
+#define GL_MESA_shader_integer_functions 1
+#endif /* GL_MESA_shader_integer_functions */
+
+#ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers
+#define GL_NVX_blend_equation_advanced_multi_draw_buffers 1
+#endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */
+
+#ifndef GL_NV_bindless_texture
+#define GL_NV_bindless_texture 1
+typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture);
+typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler);
+typedef void (GL_APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef void (GL_APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef GLuint64 (GL_APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+typedef void (GL_APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access);
+typedef void (GL_APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef GLboolean (GL_APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLuint64 GL_APIENTRY glGetTextureHandleNV (GLuint texture);
+GL_APICALL GLuint64 GL_APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler);
+GL_APICALL void GL_APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle);
+GL_APICALL void GL_APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle);
+GL_APICALL GLuint64 GL_APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+GL_APICALL void GL_APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access);
+GL_APICALL void GL_APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle);
+GL_APICALL void GL_APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value);
+GL_APICALL void GL_APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value);
+GL_APICALL void GL_APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value);
+GL_APICALL void GL_APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+GL_APICALL GLboolean GL_APIENTRY glIsTextureHandleResidentNV (GLuint64 handle);
+GL_APICALL GLboolean GL_APIENTRY glIsImageHandleResidentNV (GLuint64 handle);
+#endif
+#endif /* GL_NV_bindless_texture */
+
+#ifndef GL_NV_blend_equation_advanced
+#define GL_NV_blend_equation_advanced 1
+#define GL_BLEND_OVERLAP_NV 0x9281
+#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280
+#define GL_BLUE_NV 0x1905
+#define GL_COLORBURN_NV 0x929A
+#define GL_COLORDODGE_NV 0x9299
+#define GL_CONJOINT_NV 0x9284
+#define GL_CONTRAST_NV 0x92A1
+#define GL_DARKEN_NV 0x9297
+#define GL_DIFFERENCE_NV 0x929E
+#define GL_DISJOINT_NV 0x9283
+#define GL_DST_ATOP_NV 0x928F
+#define GL_DST_IN_NV 0x928B
+#define GL_DST_NV 0x9287
+#define GL_DST_OUT_NV 0x928D
+#define GL_DST_OVER_NV 0x9289
+#define GL_EXCLUSION_NV 0x92A0
+#define GL_GREEN_NV 0x1904
+#define GL_HARDLIGHT_NV 0x929B
+#define GL_HARDMIX_NV 0x92A9
+#define GL_HSL_COLOR_NV 0x92AF
+#define GL_HSL_HUE_NV 0x92AD
+#define GL_HSL_LUMINOSITY_NV 0x92B0
+#define GL_HSL_SATURATION_NV 0x92AE
+#define GL_INVERT_OVG_NV 0x92B4
+#define GL_INVERT_RGB_NV 0x92A3
+#define GL_LIGHTEN_NV 0x9298
+#define GL_LINEARBURN_NV 0x92A5
+#define GL_LINEARDODGE_NV 0x92A4
+#define GL_LINEARLIGHT_NV 0x92A7
+#define GL_MINUS_CLAMPED_NV 0x92B3
+#define GL_MINUS_NV 0x929F
+#define GL_MULTIPLY_NV 0x9294
+#define GL_OVERLAY_NV 0x9296
+#define GL_PINLIGHT_NV 0x92A8
+#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2
+#define GL_PLUS_CLAMPED_NV 0x92B1
+#define GL_PLUS_DARKER_NV 0x9292
+#define GL_PLUS_NV 0x9291
+#define GL_RED_NV 0x1903
+#define GL_SCREEN_NV 0x9295
+#define GL_SOFTLIGHT_NV 0x929C
+#define GL_SRC_ATOP_NV 0x928E
+#define GL_SRC_IN_NV 0x928A
+#define GL_SRC_NV 0x9286
+#define GL_SRC_OUT_NV 0x928C
+#define GL_SRC_OVER_NV 0x9288
+#define GL_UNCORRELATED_NV 0x9282
+#define GL_VIVIDLIGHT_NV 0x92A6
+#define GL_XOR_NV 0x1506
+typedef void (GL_APIENTRYP PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLBLENDBARRIERNVPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlendParameteriNV (GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glBlendBarrierNV (void);
+#endif
+#endif /* GL_NV_blend_equation_advanced */
+
+#ifndef GL_NV_blend_equation_advanced_coherent
+#define GL_NV_blend_equation_advanced_coherent 1
+#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285
+#endif /* GL_NV_blend_equation_advanced_coherent */
+
+#ifndef GL_NV_blend_minmax_factor
+#define GL_NV_blend_minmax_factor 1
+#define GL_FACTOR_MIN_AMD 0x901C
+#define GL_FACTOR_MAX_AMD 0x901D
+#endif /* GL_NV_blend_minmax_factor */
+
+#ifndef GL_NV_clip_space_w_scaling
+#define GL_NV_clip_space_w_scaling 1
+#define GL_VIEWPORT_POSITION_W_SCALE_NV 0x937C
+#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D
+#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E
+typedef void (GL_APIENTRYP PFNGLVIEWPORTPOSITIONWSCALENVPROC) (GLuint index, GLfloat xcoeff, GLfloat ycoeff);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glViewportPositionWScaleNV (GLuint index, GLfloat xcoeff, GLfloat ycoeff);
+#endif
+#endif /* GL_NV_clip_space_w_scaling */
+
+#ifndef GL_NV_compute_shader_derivatives
+#define GL_NV_compute_shader_derivatives 1
+#endif /* GL_NV_compute_shader_derivatives */
+
+#ifndef GL_NV_conditional_render
+#define GL_NV_conditional_render 1
+#define GL_QUERY_WAIT_NV 0x8E13
+#define GL_QUERY_NO_WAIT_NV 0x8E14
+#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16
+typedef void (GL_APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode);
+typedef void (GL_APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode);
+GL_APICALL void GL_APIENTRY glEndConditionalRenderNV (void);
+#endif
+#endif /* GL_NV_conditional_render */
+
+#ifndef GL_NV_conservative_raster
+#define GL_NV_conservative_raster 1
+#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346
+#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347
+#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348
+#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349
+typedef void (GL_APIENTRYP PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybits);
+#endif
+#endif /* GL_NV_conservative_raster */
+
+#ifndef GL_NV_conservative_raster_pre_snap
+#define GL_NV_conservative_raster_pre_snap 1
+#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV 0x9550
+#endif /* GL_NV_conservative_raster_pre_snap */
+
+#ifndef GL_NV_conservative_raster_pre_snap_triangles
+#define GL_NV_conservative_raster_pre_snap_triangles 1
+#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D
+#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E
+#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F
+typedef void (GL_APIENTRYP PFNGLCONSERVATIVERASTERPARAMETERINVPROC) (GLenum pname, GLint param);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glConservativeRasterParameteriNV (GLenum pname, GLint param);
+#endif
+#endif /* GL_NV_conservative_raster_pre_snap_triangles */
+
+#ifndef GL_NV_copy_buffer
+#define GL_NV_copy_buffer 1
+#define GL_COPY_READ_BUFFER_NV 0x8F36
+#define GL_COPY_WRITE_BUFFER_NV 0x8F37
+typedef void (GL_APIENTRYP PFNGLCOPYBUFFERSUBDATANVPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCopyBufferSubDataNV (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#endif
+#endif /* GL_NV_copy_buffer */
+
+#ifndef GL_NV_coverage_sample
+#define GL_NV_coverage_sample 1
+#define GL_COVERAGE_COMPONENT_NV 0x8ED0
+#define GL_COVERAGE_COMPONENT4_NV 0x8ED1
+#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2
+#define GL_COVERAGE_BUFFERS_NV 0x8ED3
+#define GL_COVERAGE_SAMPLES_NV 0x8ED4
+#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5
+#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6
+#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7
+#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask);
+typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask);
+GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation);
+#endif
+#endif /* GL_NV_coverage_sample */
+
+#ifndef GL_NV_depth_nonlinear
+#define GL_NV_depth_nonlinear 1
+#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C
+#endif /* GL_NV_depth_nonlinear */
+
+#ifndef GL_NV_draw_buffers
+#define GL_NV_draw_buffers 1
+#define GL_MAX_DRAW_BUFFERS_NV 0x8824
+#define GL_DRAW_BUFFER0_NV 0x8825
+#define GL_DRAW_BUFFER1_NV 0x8826
+#define GL_DRAW_BUFFER2_NV 0x8827
+#define GL_DRAW_BUFFER3_NV 0x8828
+#define GL_DRAW_BUFFER4_NV 0x8829
+#define GL_DRAW_BUFFER5_NV 0x882A
+#define GL_DRAW_BUFFER6_NV 0x882B
+#define GL_DRAW_BUFFER7_NV 0x882C
+#define GL_DRAW_BUFFER8_NV 0x882D
+#define GL_DRAW_BUFFER9_NV 0x882E
+#define GL_DRAW_BUFFER10_NV 0x882F
+#define GL_DRAW_BUFFER11_NV 0x8830
+#define GL_DRAW_BUFFER12_NV 0x8831
+#define GL_DRAW_BUFFER13_NV 0x8832
+#define GL_DRAW_BUFFER14_NV 0x8833
+#define GL_DRAW_BUFFER15_NV 0x8834
+#define GL_COLOR_ATTACHMENT0_NV 0x8CE0
+#define GL_COLOR_ATTACHMENT1_NV 0x8CE1
+#define GL_COLOR_ATTACHMENT2_NV 0x8CE2
+#define GL_COLOR_ATTACHMENT3_NV 0x8CE3
+#define GL_COLOR_ATTACHMENT4_NV 0x8CE4
+#define GL_COLOR_ATTACHMENT5_NV 0x8CE5
+#define GL_COLOR_ATTACHMENT6_NV 0x8CE6
+#define GL_COLOR_ATTACHMENT7_NV 0x8CE7
+#define GL_COLOR_ATTACHMENT8_NV 0x8CE8
+#define GL_COLOR_ATTACHMENT9_NV 0x8CE9
+#define GL_COLOR_ATTACHMENT10_NV 0x8CEA
+#define GL_COLOR_ATTACHMENT11_NV 0x8CEB
+#define GL_COLOR_ATTACHMENT12_NV 0x8CEC
+#define GL_COLOR_ATTACHMENT13_NV 0x8CED
+#define GL_COLOR_ATTACHMENT14_NV 0x8CEE
+#define GL_COLOR_ATTACHMENT15_NV 0x8CEF
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs);
+#endif
+#endif /* GL_NV_draw_buffers */
+
+#ifndef GL_NV_draw_instanced
+#define GL_NV_draw_instanced 1
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedNV (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+#endif
+#endif /* GL_NV_draw_instanced */
+
+#ifndef GL_NV_draw_vulkan_image
+#define GL_NV_draw_vulkan_image 1
+typedef void (GL_APIENTRY *GLVULKANPROCNV)(void);
+typedef void (GL_APIENTRYP PFNGLDRAWVKIMAGENVPROC) (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1);
+typedef GLVULKANPROCNV (GL_APIENTRYP PFNGLGETVKPROCADDRNVPROC) (const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLWAITVKSEMAPHORENVPROC) (GLuint64 vkSemaphore);
+typedef void (GL_APIENTRYP PFNGLSIGNALVKSEMAPHORENVPROC) (GLuint64 vkSemaphore);
+typedef void (GL_APIENTRYP PFNGLSIGNALVKFENCENVPROC) (GLuint64 vkFence);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawVkImageNV (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1);
+GL_APICALL GLVULKANPROCNV GL_APIENTRY glGetVkProcAddrNV (const GLchar *name);
+GL_APICALL void GL_APIENTRY glWaitVkSemaphoreNV (GLuint64 vkSemaphore);
+GL_APICALL void GL_APIENTRY glSignalVkSemaphoreNV (GLuint64 vkSemaphore);
+GL_APICALL void GL_APIENTRY glSignalVkFenceNV (GLuint64 vkFence);
+#endif
+#endif /* GL_NV_draw_vulkan_image */
+
+#ifndef GL_NV_explicit_attrib_location
+#define GL_NV_explicit_attrib_location 1
+#endif /* GL_NV_explicit_attrib_location */
+
+#ifndef GL_NV_fbo_color_attachments
+#define GL_NV_fbo_color_attachments 1
+#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF
+#endif /* GL_NV_fbo_color_attachments */
+
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences);
+typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
+typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
+typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences);
+GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences);
+GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint fence);
+GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint fence);
+GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint fence);
+GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition);
+#endif
+#endif /* GL_NV_fence */
+
+#ifndef GL_NV_fill_rectangle
+#define GL_NV_fill_rectangle 1
+#define GL_FILL_RECTANGLE_NV 0x933C
+#endif /* GL_NV_fill_rectangle */
+
+#ifndef GL_NV_fragment_coverage_to_color
+#define GL_NV_fragment_coverage_to_color 1
+#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD
+#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE
+typedef void (GL_APIENTRYP PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFragmentCoverageColorNV (GLuint color);
+#endif
+#endif /* GL_NV_fragment_coverage_to_color */
+
+#ifndef GL_NV_fragment_shader_barycentric
+#define GL_NV_fragment_shader_barycentric 1
+#endif /* GL_NV_fragment_shader_barycentric */
+
+#ifndef GL_NV_fragment_shader_interlock
+#define GL_NV_fragment_shader_interlock 1
+#endif /* GL_NV_fragment_shader_interlock */
+
+#ifndef GL_NV_framebuffer_blit
+#define GL_NV_framebuffer_blit 1
+#define GL_READ_FRAMEBUFFER_NV 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlitFramebufferNV (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+#endif /* GL_NV_framebuffer_blit */
+
+#ifndef GL_NV_framebuffer_mixed_samples
+#define GL_NV_framebuffer_mixed_samples 1
+#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331
+#define GL_COLOR_SAMPLES_NV 0x8E20
+#define GL_DEPTH_SAMPLES_NV 0x932D
+#define GL_STENCIL_SAMPLES_NV 0x932E
+#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F
+#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330
+#define GL_COVERAGE_MODULATION_NV 0x9332
+#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufSize, GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCoverageModulationTableNV (GLsizei n, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glGetCoverageModulationTableNV (GLsizei bufSize, GLfloat *v);
+GL_APICALL void GL_APIENTRY glCoverageModulationNV (GLenum components);
+#endif
+#endif /* GL_NV_framebuffer_mixed_samples */
+
+#ifndef GL_NV_framebuffer_multisample
+#define GL_NV_framebuffer_multisample 1
+#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56
+#define GL_MAX_SAMPLES_NV 0x8D57
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_NV_framebuffer_multisample */
+
+#ifndef GL_NV_generate_mipmap_sRGB
+#define GL_NV_generate_mipmap_sRGB 1
+#endif /* GL_NV_generate_mipmap_sRGB */
+
+#ifndef GL_NV_geometry_shader_passthrough
+#define GL_NV_geometry_shader_passthrough 1
+#endif /* GL_NV_geometry_shader_passthrough */
+
+#ifndef GL_NV_gpu_shader5
+#define GL_NV_gpu_shader5 1
+typedef khronos_int64_t GLint64EXT;
+typedef khronos_uint64_t GLuint64EXT;
+#define GL_INT64_NV 0x140E
+#define GL_UNSIGNED_INT64_NV 0x140F
+#define GL_INT8_NV 0x8FE0
+#define GL_INT8_VEC2_NV 0x8FE1
+#define GL_INT8_VEC3_NV 0x8FE2
+#define GL_INT8_VEC4_NV 0x8FE3
+#define GL_INT16_NV 0x8FE4
+#define GL_INT16_VEC2_NV 0x8FE5
+#define GL_INT16_VEC3_NV 0x8FE6
+#define GL_INT16_VEC4_NV 0x8FE7
+#define GL_INT64_VEC2_NV 0x8FE9
+#define GL_INT64_VEC3_NV 0x8FEA
+#define GL_INT64_VEC4_NV 0x8FEB
+#define GL_UNSIGNED_INT8_NV 0x8FEC
+#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED
+#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE
+#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF
+#define GL_UNSIGNED_INT16_NV 0x8FF0
+#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
+#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
+#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3
+#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5
+#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6
+#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7
+#define GL_FLOAT16_NV 0x8FF8
+#define GL_FLOAT16_VEC2_NV 0x8FF9
+#define GL_FLOAT16_VEC3_NV 0x8FFA
+#define GL_FLOAT16_VEC4_NV 0x8FFB
+#define GL_PATCHES 0x000E
+typedef void (GL_APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glUniform1i64NV (GLint location, GLint64EXT x);
+GL_APICALL void GL_APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y);
+GL_APICALL void GL_APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GL_APICALL void GL_APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GL_APICALL void GL_APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x);
+GL_APICALL void GL_APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y);
+GL_APICALL void GL_APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GL_APICALL void GL_APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GL_APICALL void GL_APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params);
+GL_APICALL void GL_APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x);
+GL_APICALL void GL_APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+GL_APICALL void GL_APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GL_APICALL void GL_APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GL_APICALL void GL_APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x);
+GL_APICALL void GL_APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+GL_APICALL void GL_APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GL_APICALL void GL_APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GL_APICALL void GL_APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+#endif /* GL_NV_gpu_shader5 */
+
+#ifndef GL_NV_image_formats
+#define GL_NV_image_formats 1
+#endif /* GL_NV_image_formats */
+
+#ifndef GL_NV_instanced_arrays
+#define GL_NV_instanced_arrays 1
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint divisor);
+#endif
+#endif /* GL_NV_instanced_arrays */
+
+#ifndef GL_NV_internalformat_sample_query
+#define GL_NV_internalformat_sample_query 1
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_MULTISAMPLES_NV 0x9371
+#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372
+#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373
+#define GL_CONFORMANT_NV 0x9374
+typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params);
+#endif
+#endif /* GL_NV_internalformat_sample_query */
+
+#ifndef GL_NV_memory_attachment
+#define GL_NV_memory_attachment 1
+#define GL_ATTACHED_MEMORY_OBJECT_NV 0x95A4
+#define GL_ATTACHED_MEMORY_OFFSET_NV 0x95A5
+#define GL_MEMORY_ATTACHABLE_ALIGNMENT_NV 0x95A6
+#define GL_MEMORY_ATTACHABLE_SIZE_NV 0x95A7
+#define GL_MEMORY_ATTACHABLE_NV 0x95A8
+#define GL_DETACHED_MEMORY_INCARNATION_NV 0x95A9
+#define GL_DETACHED_TEXTURES_NV 0x95AA
+#define GL_DETACHED_BUFFERS_NV 0x95AB
+#define GL_MAX_DETACHED_TEXTURES_NV 0x95AC
+#define GL_MAX_DETACHED_BUFFERS_NV 0x95AD
+typedef void (GL_APIENTRYP PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC) (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLRESETMEMORYOBJECTPARAMETERNVPROC) (GLuint memory, GLenum pname);
+typedef void (GL_APIENTRYP PFNGLTEXATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLBUFFERATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTUREATTACHMEMORYNVPROC) (GLuint texture, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERATTACHMEMORYNVPROC) (GLuint buffer, GLuint memory, GLuint64 offset);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetMemoryObjectDetachedResourcesuivNV (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params);
+GL_APICALL void GL_APIENTRY glResetMemoryObjectParameterNV (GLuint memory, GLenum pname);
+GL_APICALL void GL_APIENTRY glTexAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glBufferAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureAttachMemoryNV (GLuint texture, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glNamedBufferAttachMemoryNV (GLuint buffer, GLuint memory, GLuint64 offset);
+#endif
+#endif /* GL_NV_memory_attachment */
+
+#ifndef GL_NV_memory_object_sparse
+#define GL_NV_memory_object_sparse 1
+typedef void (GL_APIENTRYP PFNGLBUFFERPAGECOMMITMENTMEMNVPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit);
+typedef void (GL_APIENTRYP PFNGLTEXPAGECOMMITMENTMEMNVPROC) (GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit);
+typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTMEMNVPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit);
+typedef void (GL_APIENTRYP PFNGLTEXTUREPAGECOMMITMENTMEMNVPROC) (GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBufferPageCommitmentMemNV (GLenum target, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit);
+GL_APICALL void GL_APIENTRY glTexPageCommitmentMemNV (GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit);
+GL_APICALL void GL_APIENTRY glNamedBufferPageCommitmentMemNV (GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit);
+GL_APICALL void GL_APIENTRY glTexturePageCommitmentMemNV (GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit);
+#endif
+#endif /* GL_NV_memory_object_sparse */
+
+#ifndef GL_NV_mesh_shader
+#define GL_NV_mesh_shader 1
+#define GL_MESH_SHADER_NV 0x9559
+#define GL_TASK_SHADER_NV 0x955A
+#define GL_MAX_MESH_UNIFORM_BLOCKS_NV 0x8E60
+#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV 0x8E61
+#define GL_MAX_MESH_IMAGE_UNIFORMS_NV 0x8E62
+#define GL_MAX_MESH_UNIFORM_COMPONENTS_NV 0x8E63
+#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV 0x8E64
+#define GL_MAX_MESH_ATOMIC_COUNTERS_NV 0x8E65
+#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV 0x8E66
+#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV 0x8E67
+#define GL_MAX_TASK_UNIFORM_BLOCKS_NV 0x8E68
+#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV 0x8E69
+#define GL_MAX_TASK_IMAGE_UNIFORMS_NV 0x8E6A
+#define GL_MAX_TASK_UNIFORM_COMPONENTS_NV 0x8E6B
+#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV 0x8E6C
+#define GL_MAX_TASK_ATOMIC_COUNTERS_NV 0x8E6D
+#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV 0x8E6E
+#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV 0x8E6F
+#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV 0x95A2
+#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV 0x95A3
+#define GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV 0x9536
+#define GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV 0x9537
+#define GL_MAX_MESH_OUTPUT_VERTICES_NV 0x9538
+#define GL_MAX_MESH_OUTPUT_PRIMITIVES_NV 0x9539
+#define GL_MAX_TASK_OUTPUT_COUNT_NV 0x953A
+#define GL_MAX_DRAW_MESH_TASKS_COUNT_NV 0x953D
+#define GL_MAX_MESH_VIEWS_NV 0x9557
+#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV 0x92DF
+#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV 0x9543
+#define GL_MAX_MESH_WORK_GROUP_SIZE_NV 0x953B
+#define GL_MAX_TASK_WORK_GROUP_SIZE_NV 0x953C
+#define GL_MESH_WORK_GROUP_SIZE_NV 0x953E
+#define GL_TASK_WORK_GROUP_SIZE_NV 0x953F
+#define GL_MESH_VERTICES_OUT_NV 0x9579
+#define GL_MESH_PRIMITIVES_OUT_NV 0x957A
+#define GL_MESH_OUTPUT_TYPE_NV 0x957B
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV 0x959C
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV 0x959D
+#define GL_REFERENCED_BY_MESH_SHADER_NV 0x95A0
+#define GL_REFERENCED_BY_TASK_SHADER_NV 0x95A1
+#define GL_MESH_SHADER_BIT_NV 0x00000040
+#define GL_TASK_SHADER_BIT_NV 0x00000080
+#define GL_MESH_SUBROUTINE_NV 0x957C
+#define GL_TASK_SUBROUTINE_NV 0x957D
+#define GL_MESH_SUBROUTINE_UNIFORM_NV 0x957E
+#define GL_TASK_SUBROUTINE_UNIFORM_NV 0x957F
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV 0x959E
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV 0x959F
+typedef void (GL_APIENTRYP PFNGLDRAWMESHTASKSNVPROC) (GLuint first, GLuint count);
+typedef void (GL_APIENTRYP PFNGLDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawMeshTasksNV (GLuint first, GLuint count);
+GL_APICALL void GL_APIENTRY glDrawMeshTasksIndirectNV (GLintptr indirect);
+GL_APICALL void GL_APIENTRY glMultiDrawMeshTasksIndirectNV (GLintptr indirect, GLsizei drawcount, GLsizei stride);
+GL_APICALL void GL_APIENTRY glMultiDrawMeshTasksIndirectCountNV (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+#endif
+#endif /* GL_NV_mesh_shader */
+
+#ifndef GL_NV_non_square_matrices
+#define GL_NV_non_square_matrices 1
+#define GL_FLOAT_MAT2x3_NV 0x8B65
+#define GL_FLOAT_MAT2x4_NV 0x8B66
+#define GL_FLOAT_MAT3x2_NV 0x8B67
+#define GL_FLOAT_MAT3x4_NV 0x8B68
+#define GL_FLOAT_MAT4x2_NV 0x8B69
+#define GL_FLOAT_MAT4x3_NV 0x8B6A
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glUniformMatrix2x3fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x2fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix2x4fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x2fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x4fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x3fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif
+#endif /* GL_NV_non_square_matrices */
+
+#ifndef GL_NV_path_rendering
+#define GL_NV_path_rendering 1
+typedef double GLdouble;
+#define GL_PATH_FORMAT_SVG_NV 0x9070
+#define GL_PATH_FORMAT_PS_NV 0x9071
+#define GL_STANDARD_FONT_NAME_NV 0x9072
+#define GL_SYSTEM_FONT_NAME_NV 0x9073
+#define GL_FILE_NAME_NV 0x9074
+#define GL_PATH_STROKE_WIDTH_NV 0x9075
+#define GL_PATH_END_CAPS_NV 0x9076
+#define GL_PATH_INITIAL_END_CAP_NV 0x9077
+#define GL_PATH_TERMINAL_END_CAP_NV 0x9078
+#define GL_PATH_JOIN_STYLE_NV 0x9079
+#define GL_PATH_MITER_LIMIT_NV 0x907A
+#define GL_PATH_DASH_CAPS_NV 0x907B
+#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C
+#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D
+#define GL_PATH_DASH_OFFSET_NV 0x907E
+#define GL_PATH_CLIENT_LENGTH_NV 0x907F
+#define GL_PATH_FILL_MODE_NV 0x9080
+#define GL_PATH_FILL_MASK_NV 0x9081
+#define GL_PATH_FILL_COVER_MODE_NV 0x9082
+#define GL_PATH_STROKE_COVER_MODE_NV 0x9083
+#define GL_PATH_STROKE_MASK_NV 0x9084
+#define GL_COUNT_UP_NV 0x9088
+#define GL_COUNT_DOWN_NV 0x9089
+#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A
+#define GL_CONVEX_HULL_NV 0x908B
+#define GL_BOUNDING_BOX_NV 0x908D
+#define GL_TRANSLATE_X_NV 0x908E
+#define GL_TRANSLATE_Y_NV 0x908F
+#define GL_TRANSLATE_2D_NV 0x9090
+#define GL_TRANSLATE_3D_NV 0x9091
+#define GL_AFFINE_2D_NV 0x9092
+#define GL_AFFINE_3D_NV 0x9094
+#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096
+#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098
+#define GL_UTF8_NV 0x909A
+#define GL_UTF16_NV 0x909B
+#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C
+#define GL_PATH_COMMAND_COUNT_NV 0x909D
+#define GL_PATH_COORD_COUNT_NV 0x909E
+#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F
+#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0
+#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1
+#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2
+#define GL_SQUARE_NV 0x90A3
+#define GL_ROUND_NV 0x90A4
+#define GL_TRIANGULAR_NV 0x90A5
+#define GL_BEVEL_NV 0x90A6
+#define GL_MITER_REVERT_NV 0x90A7
+#define GL_MITER_TRUNCATE_NV 0x90A8
+#define GL_SKIP_MISSING_GLYPH_NV 0x90A9
+#define GL_USE_MISSING_GLYPH_NV 0x90AA
+#define GL_PATH_ERROR_POSITION_NV 0x90AB
+#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD
+#define GL_ADJACENT_PAIRS_NV 0x90AE
+#define GL_FIRST_TO_REST_NV 0x90AF
+#define GL_PATH_GEN_MODE_NV 0x90B0
+#define GL_PATH_GEN_COEFF_NV 0x90B1
+#define GL_PATH_GEN_COMPONENTS_NV 0x90B3
+#define GL_PATH_STENCIL_FUNC_NV 0x90B7
+#define GL_PATH_STENCIL_REF_NV 0x90B8
+#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9
+#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD
+#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE
+#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF
+#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4
+#define GL_MOVE_TO_RESETS_NV 0x90B5
+#define GL_MOVE_TO_CONTINUES_NV 0x90B6
+#define GL_CLOSE_PATH_NV 0x00
+#define GL_MOVE_TO_NV 0x02
+#define GL_RELATIVE_MOVE_TO_NV 0x03
+#define GL_LINE_TO_NV 0x04
+#define GL_RELATIVE_LINE_TO_NV 0x05
+#define GL_HORIZONTAL_LINE_TO_NV 0x06
+#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07
+#define GL_VERTICAL_LINE_TO_NV 0x08
+#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09
+#define GL_QUADRATIC_CURVE_TO_NV 0x0A
+#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B
+#define GL_CUBIC_CURVE_TO_NV 0x0C
+#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D
+#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E
+#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F
+#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10
+#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11
+#define GL_SMALL_CCW_ARC_TO_NV 0x12
+#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13
+#define GL_SMALL_CW_ARC_TO_NV 0x14
+#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15
+#define GL_LARGE_CCW_ARC_TO_NV 0x16
+#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17
+#define GL_LARGE_CW_ARC_TO_NV 0x18
+#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19
+#define GL_RESTART_PATH_NV 0xF0
+#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2
+#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4
+#define GL_RECT_NV 0xF6
+#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8
+#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA
+#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC
+#define GL_ARC_TO_NV 0xFE
+#define GL_RELATIVE_ARC_TO_NV 0xFF
+#define GL_BOLD_BIT_NV 0x01
+#define GL_ITALIC_BIT_NV 0x02
+#define GL_GLYPH_WIDTH_BIT_NV 0x01
+#define GL_GLYPH_HEIGHT_BIT_NV 0x02
+#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04
+#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08
+#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10
+#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20
+#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40
+#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80
+#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100
+#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000
+#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000
+#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000
+#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000
+#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000
+#define GL_FONT_ASCENDER_BIT_NV 0x00200000
+#define GL_FONT_DESCENDER_BIT_NV 0x00400000
+#define GL_FONT_HEIGHT_BIT_NV 0x00800000
+#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000
+#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000
+#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000
+#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000
+#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000
+#define GL_ROUNDED_RECT_NV 0xE8
+#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9
+#define GL_ROUNDED_RECT2_NV 0xEA
+#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB
+#define GL_ROUNDED_RECT4_NV 0xEC
+#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED
+#define GL_ROUNDED_RECT8_NV 0xEE
+#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF
+#define GL_RELATIVE_RECT_NV 0xF7
+#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368
+#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369
+#define GL_FONT_UNAVAILABLE_NV 0x936A
+#define GL_FONT_UNINTELLIGIBLE_NV 0x936B
+#define GL_CONIC_CURVE_TO_NV 0x1A
+#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B
+#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000
+#define GL_STANDARD_FONT_FORMAT_NV 0x936C
+#define GL_PATH_PROJECTION_NV 0x1701
+#define GL_PATH_MODELVIEW_NV 0x1700
+#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3
+#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6
+#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36
+#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3
+#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4
+#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7
+#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38
+#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4
+#define GL_FRAGMENT_INPUT_NV 0x936D
+typedef GLuint (GL_APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range);
+typedef void (GL_APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range);
+typedef GLboolean (GL_APIENTRYP PFNGLISPATHNVPROC) (GLuint path);
+typedef void (GL_APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (GL_APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString);
+typedef void (GL_APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GL_APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GL_APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights);
+typedef void (GL_APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath);
+typedef void (GL_APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);
+typedef void (GL_APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value);
+typedef void (GL_APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray);
+typedef void (GL_APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units);
+typedef void (GL_APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func);
+typedef void (GL_APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value);
+typedef void (GL_APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands);
+typedef void (GL_APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords);
+typedef void (GL_APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray);
+typedef void (GL_APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);
+typedef void (GL_APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics);
+typedef void (GL_APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);
+typedef GLboolean (GL_APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y);
+typedef GLboolean (GL_APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y);
+typedef GLfloat (GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments);
+typedef GLboolean (GL_APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]);
+typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef GLenum (GL_APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (GL_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (GL_APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GL_APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GL_APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLuint GL_APIENTRY glGenPathsNV (GLsizei range);
+GL_APICALL void GL_APIENTRY glDeletePathsNV (GLuint path, GLsizei range);
+GL_APICALL GLboolean GL_APIENTRY glIsPathNV (GLuint path);
+GL_APICALL void GL_APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords);
+GL_APICALL void GL_APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const void *pathString);
+GL_APICALL void GL_APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL void GL_APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL void GL_APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights);
+GL_APICALL void GL_APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath);
+GL_APICALL void GL_APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);
+GL_APICALL void GL_APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value);
+GL_APICALL void GL_APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value);
+GL_APICALL void GL_APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray);
+GL_APICALL void GL_APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units);
+GL_APICALL void GL_APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glPathCoverDepthFuncNV (GLenum func);
+GL_APICALL void GL_APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value);
+GL_APICALL void GL_APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value);
+GL_APICALL void GL_APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands);
+GL_APICALL void GL_APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords);
+GL_APICALL void GL_APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray);
+GL_APICALL void GL_APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);
+GL_APICALL void GL_APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics);
+GL_APICALL void GL_APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);
+GL_APICALL GLboolean GL_APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y);
+GL_APICALL GLboolean GL_APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y);
+GL_APICALL GLfloat GL_APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments);
+GL_APICALL GLboolean GL_APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);
+GL_APICALL void GL_APIENTRY glMatrixLoad3x2fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoad3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoadTranspose3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMult3x2fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMult3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMultTranspose3x3fNV (GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]);
+GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL GLenum GL_APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+GL_APICALL void GL_APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);
+GL_APICALL void GL_APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GL_APICALL void GL_APIENTRY glMatrixLoadIdentityEXT (GLenum mode);
+GL_APICALL void GL_APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m);
+GL_APICALL void GL_APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m);
+GL_APICALL void GL_APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m);
+GL_APICALL void GL_APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m);
+GL_APICALL void GL_APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GL_APICALL void GL_APIENTRY glMatrixPopEXT (GLenum mode);
+GL_APICALL void GL_APIENTRY glMatrixPushEXT (GLenum mode);
+GL_APICALL void GL_APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+GL_APICALL void GL_APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+GL_APICALL void GL_APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+#endif
+#endif /* GL_NV_path_rendering */
+
+#ifndef GL_NV_path_rendering_shared_edge
+#define GL_NV_path_rendering_shared_edge 1
+#define GL_SHARED_EDGE_NV 0xC0
+#endif /* GL_NV_path_rendering_shared_edge */
+
+#ifndef GL_NV_pixel_buffer_object
+#define GL_NV_pixel_buffer_object 1
+#define GL_PIXEL_PACK_BUFFER_NV 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_NV 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_NV 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_NV 0x88EF
+#endif /* GL_NV_pixel_buffer_object */
+
+#ifndef GL_NV_polygon_mode
+#define GL_NV_polygon_mode 1
+#define GL_POLYGON_MODE_NV 0x0B40
+#define GL_POLYGON_OFFSET_POINT_NV 0x2A01
+#define GL_POLYGON_OFFSET_LINE_NV 0x2A02
+#define GL_POINT_NV 0x1B00
+#define GL_LINE_NV 0x1B01
+#define GL_FILL_NV 0x1B02
+typedef void (GL_APIENTRYP PFNGLPOLYGONMODENVPROC) (GLenum face, GLenum mode);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glPolygonModeNV (GLenum face, GLenum mode);
+#endif
+#endif /* GL_NV_polygon_mode */
+
+#ifndef GL_NV_primitive_shading_rate
+#define GL_NV_primitive_shading_rate 1
+#define GL_SHADING_RATE_IMAGE_PER_PRIMITIVE_NV 0x95B1
+#define GL_SHADING_RATE_IMAGE_PALETTE_COUNT_NV 0x95B2
+#endif /* GL_NV_primitive_shading_rate */
+
+#ifndef GL_NV_read_buffer
+#define GL_NV_read_buffer 1
+#define GL_READ_BUFFER_NV 0x0C02
+typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode);
+#endif
+#endif /* GL_NV_read_buffer */
+
+#ifndef GL_NV_read_buffer_front
+#define GL_NV_read_buffer_front 1
+#endif /* GL_NV_read_buffer_front */
+
+#ifndef GL_NV_read_depth
+#define GL_NV_read_depth 1
+#endif /* GL_NV_read_depth */
+
+#ifndef GL_NV_read_depth_stencil
+#define GL_NV_read_depth_stencil 1
+#endif /* GL_NV_read_depth_stencil */
+
+#ifndef GL_NV_read_stencil
+#define GL_NV_read_stencil 1
+#endif /* GL_NV_read_stencil */
+
+#ifndef GL_NV_representative_fragment_test
+#define GL_NV_representative_fragment_test 1
+#define GL_REPRESENTATIVE_FRAGMENT_TEST_NV 0x937F
+#endif /* GL_NV_representative_fragment_test */
+
+#ifndef GL_NV_sRGB_formats
+#define GL_NV_sRGB_formats 1
+#define GL_SLUMINANCE_NV 0x8C46
+#define GL_SLUMINANCE_ALPHA_NV 0x8C44
+#define GL_SRGB8_NV 0x8C41
+#define GL_SLUMINANCE8_NV 0x8C47
+#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F
+#define GL_ETC1_SRGB8_NV 0x88EE
+#endif /* GL_NV_sRGB_formats */
+
+#ifndef GL_NV_sample_locations
+#define GL_NV_sample_locations 1
+#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D
+#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E
+#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F
+#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340
+#define GL_SAMPLE_LOCATION_NV 0x8E50
+#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341
+#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342
+#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLRESOLVEDEPTHVALUESNVPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferSampleLocationsfvNV (GLenum target, GLuint start, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glNamedFramebufferSampleLocationsfvNV (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void);
+#endif
+#endif /* GL_NV_sample_locations */
+
+#ifndef GL_NV_sample_mask_override_coverage
+#define GL_NV_sample_mask_override_coverage 1
+#endif /* GL_NV_sample_mask_override_coverage */
+
+#ifndef GL_NV_scissor_exclusive
+#define GL_NV_scissor_exclusive 1
+#define GL_SCISSOR_TEST_EXCLUSIVE_NV 0x9555
+#define GL_SCISSOR_BOX_EXCLUSIVE_NV 0x9556
+typedef void (GL_APIENTRYP PFNGLSCISSOREXCLUSIVENVPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSCISSOREXCLUSIVEARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glScissorExclusiveNV (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glScissorExclusiveArrayvNV (GLuint first, GLsizei count, const GLint *v);
+#endif
+#endif /* GL_NV_scissor_exclusive */
+
+#ifndef GL_NV_shader_atomic_fp16_vector
+#define GL_NV_shader_atomic_fp16_vector 1
+#endif /* GL_NV_shader_atomic_fp16_vector */
+
+#ifndef GL_NV_shader_noperspective_interpolation
+#define GL_NV_shader_noperspective_interpolation 1
+#endif /* GL_NV_shader_noperspective_interpolation */
+
+#ifndef GL_NV_shader_subgroup_partitioned
+#define GL_NV_shader_subgroup_partitioned 1
+#define GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV 0x00000100
+#endif /* GL_NV_shader_subgroup_partitioned */
+
+#ifndef GL_NV_shader_texture_footprint
+#define GL_NV_shader_texture_footprint 1
+#endif /* GL_NV_shader_texture_footprint */
+
+#ifndef GL_NV_shading_rate_image
+#define GL_NV_shading_rate_image 1
+#define GL_SHADING_RATE_IMAGE_NV 0x9563
+#define GL_SHADING_RATE_NO_INVOCATIONS_NV 0x9564
+#define GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV 0x9565
+#define GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV 0x9566
+#define GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV 0x9567
+#define GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV 0x9568
+#define GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV 0x9569
+#define GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV 0x956A
+#define GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV 0x956B
+#define GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV 0x956C
+#define GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV 0x956D
+#define GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV 0x956E
+#define GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV 0x956F
+#define GL_SHADING_RATE_IMAGE_BINDING_NV 0x955B
+#define GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV 0x955C
+#define GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV 0x955D
+#define GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV 0x955E
+#define GL_MAX_COARSE_FRAGMENT_SAMPLES_NV 0x955F
+#define GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV 0x95AE
+#define GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV 0x95AF
+#define GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV 0x95B0
+typedef void (GL_APIENTRYP PFNGLBINDSHADINGRATEIMAGENVPROC) (GLuint texture);
+typedef void (GL_APIENTRYP PFNGLGETSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint entry, GLenum *rate);
+typedef void (GL_APIENTRYP PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC) (GLenum rate, GLuint samples, GLuint index, GLint *location);
+typedef void (GL_APIENTRYP PFNGLSHADINGRATEIMAGEBARRIERNVPROC) (GLboolean synchronize);
+typedef void (GL_APIENTRYP PFNGLSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates);
+typedef void (GL_APIENTRYP PFNGLSHADINGRATESAMPLEORDERNVPROC) (GLenum order);
+typedef void (GL_APIENTRYP PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC) (GLenum rate, GLuint samples, const GLint *locations);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBindShadingRateImageNV (GLuint texture);
+GL_APICALL void GL_APIENTRY glGetShadingRateImagePaletteNV (GLuint viewport, GLuint entry, GLenum *rate);
+GL_APICALL void GL_APIENTRY glGetShadingRateSampleLocationivNV (GLenum rate, GLuint samples, GLuint index, GLint *location);
+GL_APICALL void GL_APIENTRY glShadingRateImageBarrierNV (GLboolean synchronize);
+GL_APICALL void GL_APIENTRY glShadingRateImagePaletteNV (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates);
+GL_APICALL void GL_APIENTRY glShadingRateSampleOrderNV (GLenum order);
+GL_APICALL void GL_APIENTRY glShadingRateSampleOrderCustomNV (GLenum rate, GLuint samples, const GLint *locations);
+#endif
+#endif /* GL_NV_shading_rate_image */
+
+#ifndef GL_NV_shadow_samplers_array
+#define GL_NV_shadow_samplers_array 1
+#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4
+#endif /* GL_NV_shadow_samplers_array */
+
+#ifndef GL_NV_shadow_samplers_cube
+#define GL_NV_shadow_samplers_cube 1
+#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5
+#endif /* GL_NV_shadow_samplers_cube */
+
+#ifndef GL_NV_stereo_view_rendering
+#define GL_NV_stereo_view_rendering 1
+#endif /* GL_NV_stereo_view_rendering */
+
+#ifndef GL_NV_texture_border_clamp
+#define GL_NV_texture_border_clamp 1
+#define GL_TEXTURE_BORDER_COLOR_NV 0x1004
+#define GL_CLAMP_TO_BORDER_NV 0x812D
+#endif /* GL_NV_texture_border_clamp */
+
+#ifndef GL_NV_texture_compression_s3tc_update
+#define GL_NV_texture_compression_s3tc_update 1
+#endif /* GL_NV_texture_compression_s3tc_update */
+
+#ifndef GL_NV_texture_npot_2D_mipmap
+#define GL_NV_texture_npot_2D_mipmap 1
+#endif /* GL_NV_texture_npot_2D_mipmap */
+
+#ifndef GL_NV_timeline_semaphore
+#define GL_NV_timeline_semaphore 1
+#define GL_TIMELINE_SEMAPHORE_VALUE_NV 0x9595
+#define GL_SEMAPHORE_TYPE_NV 0x95B3
+#define GL_SEMAPHORE_TYPE_BINARY_NV 0x95B4
+#define GL_SEMAPHORE_TYPE_TIMELINE_NV 0x95B5
+#define GL_MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV 0x95B6
+typedef void (GL_APIENTRYP PFNGLCREATESEMAPHORESNVPROC) (GLsizei n, GLuint *semaphores);
+typedef void (GL_APIENTRYP PFNGLSEMAPHOREPARAMETERIVNVPROC) (GLuint semaphore, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSEMAPHOREPARAMETERIVNVPROC) (GLuint semaphore, GLenum pname, GLint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCreateSemaphoresNV (GLsizei n, GLuint *semaphores);
+GL_APICALL void GL_APIENTRY glSemaphoreParameterivNV (GLuint semaphore, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glGetSemaphoreParameterivNV (GLuint semaphore, GLenum pname, GLint *params);
+#endif
+#endif /* GL_NV_timeline_semaphore */
+
+#ifndef GL_NV_viewport_array
+#define GL_NV_viewport_array 1
+#define GL_MAX_VIEWPORTS_NV 0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS_NV 0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE_NV 0x825D
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV 0x825F
+typedef void (GL_APIENTRYP PFNGLVIEWPORTARRAYVNVPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLSCISSORARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDNVPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDVNVPROC) (GLuint index, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEARRAYFVNVPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEINDEXEDFNVPROC) (GLuint index, GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLGETFLOATI_VNVPROC) (GLenum target, GLuint index, GLfloat *data);
+typedef void (GL_APIENTRYP PFNGLENABLEINVPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLDISABLEINVPROC) (GLenum target, GLuint index);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDINVPROC) (GLenum target, GLuint index);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glViewportArrayvNV (GLuint first, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glViewportIndexedfNV (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+GL_APICALL void GL_APIENTRY glViewportIndexedfvNV (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glScissorArrayvNV (GLuint first, GLsizei count, const GLint *v);
+GL_APICALL void GL_APIENTRY glScissorIndexedNV (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glScissorIndexedvNV (GLuint index, const GLint *v);
+GL_APICALL void GL_APIENTRY glDepthRangeArrayfvNV (GLuint first, GLsizei count, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glDepthRangeIndexedfNV (GLuint index, GLfloat n, GLfloat f);
+GL_APICALL void GL_APIENTRY glGetFloati_vNV (GLenum target, GLuint index, GLfloat *data);
+GL_APICALL void GL_APIENTRY glEnableiNV (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glDisableiNV (GLenum target, GLuint index);
+GL_APICALL GLboolean GL_APIENTRY glIsEnablediNV (GLenum target, GLuint index);
+#endif
+#endif /* GL_NV_viewport_array */
+
+#ifndef GL_NV_viewport_array2
+#define GL_NV_viewport_array2 1
+#endif /* GL_NV_viewport_array2 */
+
+#ifndef GL_NV_viewport_swizzle
+#define GL_NV_viewport_swizzle 1
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355
+#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356
+#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357
+#define GL_VIEWPORT_SWIZZLE_X_NV 0x9358
+#define GL_VIEWPORT_SWIZZLE_Y_NV 0x9359
+#define GL_VIEWPORT_SWIZZLE_Z_NV 0x935A
+#define GL_VIEWPORT_SWIZZLE_W_NV 0x935B
+typedef void (GL_APIENTRYP PFNGLVIEWPORTSWIZZLENVPROC) (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glViewportSwizzleNV (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew);
+#endif
+#endif /* GL_NV_viewport_swizzle */
+
+#ifndef GL_OVR_multiview
+#define GL_OVR_multiview 1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632
+#define GL_MAX_VIEWS_OVR 0x9631
+#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews);
+#endif
+#endif /* GL_OVR_multiview */
+
+#ifndef GL_OVR_multiview2
+#define GL_OVR_multiview2 1
+#endif /* GL_OVR_multiview2 */
+
+#ifndef GL_OVR_multiview_multisampled_render_to_texture
+#define GL_OVR_multiview_multisampled_render_to_texture 1
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferTextureMultisampleMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews);
+#endif
+#endif /* GL_OVR_multiview_multisampled_render_to_texture */
+
+#ifndef GL_QCOM_YUV_texture_gather
+#define GL_QCOM_YUV_texture_gather 1
+#endif /* GL_QCOM_YUV_texture_gather */
+
+#ifndef GL_QCOM_alpha_test
+#define GL_QCOM_alpha_test 1
+#define GL_ALPHA_TEST_QCOM 0x0BC0
+#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1
+#define GL_ALPHA_TEST_REF_QCOM 0x0BC2
+typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref);
+#endif
+#endif /* GL_QCOM_alpha_test */
+
+#ifndef GL_QCOM_binning_control
+#define GL_QCOM_binning_control 1
+#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0
+#define GL_CPU_OPTIMIZED_QCOM 0x8FB1
+#define GL_GPU_OPTIMIZED_QCOM 0x8FB2
+#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3
+#endif /* GL_QCOM_binning_control */
+
+#ifndef GL_QCOM_driver_control
+#define GL_QCOM_driver_control 1
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls);
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
+typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls);
+GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
+GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl);
+GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl);
+#endif
+#endif /* GL_QCOM_driver_control */
+
+#ifndef GL_QCOM_extended_get
+#define GL_QCOM_extended_get 1
+#define GL_TEXTURE_WIDTH_QCOM 0x8BD2
+#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3
+#define GL_TEXTURE_DEPTH_QCOM 0x8BD4
+#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5
+#define GL_TEXTURE_FORMAT_QCOM 0x8BD6
+#define GL_TEXTURE_TYPE_QCOM 0x8BD7
+#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8
+#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9
+#define GL_TEXTURE_TARGET_QCOM 0x8BDA
+#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB
+#define GL_STATE_RESTORE 0x8BDC
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, void **params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures);
+GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels);
+GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, void **params);
+#endif
+#endif /* GL_QCOM_extended_get */
+
+#ifndef GL_QCOM_extended_get2
+#define GL_QCOM_extended_get2 1
+typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program);
+GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#endif
+#endif /* GL_QCOM_extended_get2 */
+
+#ifndef GL_QCOM_frame_extrapolation
+#define GL_QCOM_frame_extrapolation 1
+typedef void (GL_APIENTRYP PFNGLEXTRAPOLATETEX2DQCOMPROC) (GLuint src1, GLuint src2, GLuint output, GLfloat scaleFactor);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glExtrapolateTex2DQCOM (GLuint src1, GLuint src2, GLuint output, GLfloat scaleFactor);
+#endif
+#endif /* GL_QCOM_frame_extrapolation */
+
+#ifndef GL_QCOM_framebuffer_foveated
+#define GL_QCOM_framebuffer_foveated 1
+#define GL_FOVEATION_ENABLE_BIT_QCOM 0x00000001
+#define GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM 0x00000002
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC) (GLuint framebuffer, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint *providedFeatures);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC) (GLuint framebuffer, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferFoveationConfigQCOM (GLuint framebuffer, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint *providedFeatures);
+GL_APICALL void GL_APIENTRY glFramebufferFoveationParametersQCOM (GLuint framebuffer, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea);
+#endif
+#endif /* GL_QCOM_framebuffer_foveated */
+
+#ifndef GL_QCOM_motion_estimation
+#define GL_QCOM_motion_estimation 1
+#define GL_MOTION_ESTIMATION_SEARCH_BLOCK_X_QCOM 0x8C90
+#define GL_MOTION_ESTIMATION_SEARCH_BLOCK_Y_QCOM 0x8C91
+typedef void (GL_APIENTRYP PFNGLTEXESTIMATEMOTIONQCOMPROC) (GLuint ref, GLuint target, GLuint output);
+typedef void (GL_APIENTRYP PFNGLTEXESTIMATEMOTIONREGIONSQCOMPROC) (GLuint ref, GLuint target, GLuint output, GLuint mask);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexEstimateMotionQCOM (GLuint ref, GLuint target, GLuint output);
+GL_APICALL void GL_APIENTRY glTexEstimateMotionRegionsQCOM (GLuint ref, GLuint target, GLuint output, GLuint mask);
+#endif
+#endif /* GL_QCOM_motion_estimation */
+
+#ifndef GL_QCOM_perfmon_global_mode
+#define GL_QCOM_perfmon_global_mode 1
+#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0
+#endif /* GL_QCOM_perfmon_global_mode */
+
+#ifndef GL_QCOM_shader_framebuffer_fetch_noncoherent
+#define GL_QCOM_shader_framebuffer_fetch_noncoherent 1
+#define GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM 0x96A2
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferFetchBarrierQCOM (void);
+#endif
+#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */
+
+#ifndef GL_QCOM_shader_framebuffer_fetch_rate
+#define GL_QCOM_shader_framebuffer_fetch_rate 1
+#endif /* GL_QCOM_shader_framebuffer_fetch_rate */
+
+#ifndef GL_QCOM_shading_rate
+#define GL_QCOM_shading_rate 1
+#define GL_SHADING_RATE_QCOM 0x96A4
+#define GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM 0x96A5
+#define GL_SHADING_RATE_1X1_PIXELS_QCOM 0x96A6
+#define GL_SHADING_RATE_1X2_PIXELS_QCOM 0x96A7
+#define GL_SHADING_RATE_2X1_PIXELS_QCOM 0x96A8
+#define GL_SHADING_RATE_2X2_PIXELS_QCOM 0x96A9
+#define GL_SHADING_RATE_4X2_PIXELS_QCOM 0x96AC
+#define GL_SHADING_RATE_4X4_PIXELS_QCOM 0x96AE
+typedef void (GL_APIENTRYP PFNGLSHADINGRATEQCOMPROC) (GLenum rate);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glShadingRateQCOM (GLenum rate);
+#endif
+#endif /* GL_QCOM_shading_rate */
+
+#ifndef GL_QCOM_texture_foveated
+#define GL_QCOM_texture_foveated 1
+#define GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM 0x8BFB
+#define GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM 0x8BFC
+#define GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM 0x8BFD
+#define GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM 0x8BFE
+#define GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM 0x8BFF
+typedef void (GL_APIENTRYP PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC) (GLuint texture, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTextureFoveationParametersQCOM (GLuint texture, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea);
+#endif
+#endif /* GL_QCOM_texture_foveated */
+
+#ifndef GL_QCOM_texture_foveated2
+#define GL_QCOM_texture_foveated2 1
+#define GL_TEXTURE_FOVEATED_CUTOFF_DENSITY_QCOM 0x96A0
+#endif /* GL_QCOM_texture_foveated2 */
+
+#ifndef GL_QCOM_texture_foveated_subsampled_layout
+#define GL_QCOM_texture_foveated_subsampled_layout 1
+#define GL_FOVEATION_SUBSAMPLED_LAYOUT_METHOD_BIT_QCOM 0x00000004
+#define GL_MAX_SHADER_SUBSAMPLED_IMAGE_UNITS_QCOM 0x8FA1
+#endif /* GL_QCOM_texture_foveated_subsampled_layout */
+
+#ifndef GL_QCOM_tiled_rendering
+#define GL_QCOM_tiled_rendering 1
+#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001
+#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002
+#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004
+#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008
+#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010
+#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020
+#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040
+#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080
+#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100
+#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200
+#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400
+#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800
+#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000
+#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000
+#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000
+#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000
+#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000
+#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000
+#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000
+#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000
+#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000
+#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000
+#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000
+#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000
+#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000
+#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000
+#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000
+#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000
+#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000
+#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000
+#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000
+#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000
+typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask);
+#endif
+#endif /* GL_QCOM_tiled_rendering */
+
+#ifndef GL_QCOM_writeonly_rendering
+#define GL_QCOM_writeonly_rendering 1
+#define GL_WRITEONLY_RENDERING_QCOM 0x8823
+#endif /* GL_QCOM_writeonly_rendering */
+
+#ifndef GL_VIV_shader_binary
+#define GL_VIV_shader_binary 1
+#define GL_SHADER_BINARY_VIV 0x8FC4
+#endif /* GL_VIV_shader_binary */
+
+/* ANGLE GLES2 extensions */
+#include "gl2ext_angle.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/include/GLES2/gl2ext_angle.h b/gfx/angle/checkout/include/GLES2/gl2ext_angle.h
new file mode 100644
index 0000000000..4d701a39c7
--- /dev/null
+++ b/gfx/angle/checkout/include/GLES2/gl2ext_angle.h
@@ -0,0 +1,667 @@
+//
+// 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.
+//
+// gl2ext_angle.h: ANGLE modifications to the gl2ext.h header file.
+// Currently we don't include this file directly, we patch gl2ext.h
+// to include it implicitly so it is visible throughout our code.
+
+#ifndef INCLUDE_GLES2_GL2EXT_ANGLE_H_
+#define INCLUDE_GLES2_GL2EXT_ANGLE_H_
+
+// clang-format off
+
+#ifndef GL_ANGLE_client_arrays
+#define GL_ANGLE_client_arrays 1
+#define GL_CLIENT_ARRAYS_ANGLE 0x93AA
+#endif /* GL_ANGLE_client_arrays */
+
+#ifndef GL_ANGLE_request_extension
+#define GL_ANGLE_request_extension 1
+#define GL_REQUESTABLE_EXTENSIONS_ANGLE 0x93A8
+#define GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE 0x93A9
+typedef void (GL_APIENTRYP PFNGLREQUESTEXTENSIONANGLEPROC) (const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLDISABLEEXTENSIONANGLEPROC) (const GLchar *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRequestExtensionANGLE (const GLchar *name);
+#endif
+#endif /* GL_ANGLE_webgl_compatibility */
+
+#ifndef GL_ANGLE_robust_resource_initialization
+#define GL_ANGLE_robust_resource_initialization 1
+#define GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93AB
+#define GL_RESOURCE_INITIALIZED_ANGLE 0x969F
+#endif /* GL_ANGLE_robust_resource_initialization */
+
+#ifndef GL_ANGLE_provoking_vertex
+#define GL_ANGLE_provoking_vertex 1
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_PROVOKING_VERTEX 0x8E4F
+typedef void (GL_APIENTRYP PFNGLPROVOKINGVERTEXANGLEPROC) (GLenum);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glProvokingVertexANGLE(GLenum mode);
+#endif
+#endif /* GL_ANGLE_provoking_vertex */
+
+#ifndef GL_CHROMIUM_framebuffer_mixed_samples
+#define GL_CHROMIUM_frambuffer_mixed_samples 1
+#define GL_COVERAGE_MODULATION_CHROMIUM 0x9332
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONCHROMIUMPROC) (GLenum components);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components);
+#endif
+#endif /* GL_CHROMIUM_framebuffer_mixed_samples */
+
+#ifndef GL_CHROMIUM_bind_generates_resource
+#define GL_CHROMIUM_bind_generates_resource 1
+#define GL_BIND_GENERATES_RESOURCE_CHROMIUM 0x9244
+#endif /* GL_CHROMIUM_bind_generates_resource */
+
+#ifndef GL_ANGLE_memory_size
+#define GL_ANGLE_memory_size
+#define GL_MEMORY_SIZE_ANGLE 0x93AD
+#endif /* GL_ANGLE_memory_size */
+
+// needed by NV_path_rendering (and thus CHROMIUM_path_rendering)
+// but CHROMIUM_path_rendering only needs MatrixLoadfEXT, MatrixLoadIdentityEXT
+#ifndef GL_EXT_direct_state_access
+#define GL_EXT_direct_state_access 1
+typedef void(GL_APIENTRYP PFNGLMATRIXLOADFEXTPROC)(GLenum matrixMode, const GLfloat *m);
+typedef void(GL_APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC)(GLenum matrixMode);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMatrixLoadfEXT(GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoadIdentityEXT(GLenum matrixMode);
+#endif
+#endif /* GL_EXT_direct_state_access */
+
+#ifndef GL_CHROMIUM_copy_texture
+#define GL_CHROMIUM_copy_texture 1
+typedef void(GL_APIENTRYP PFNGLCOPYTEXTURECHROMIUMPROC)(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+typedef void(GL_APIENTRYP PFNGLCOPYSUBTEXTURECHROMIUMPROC)(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+#endif
+#endif /* GL_CHROMIUM_copy_texture */
+
+#ifndef GL_CHROMIUM_compressed_copy_texture
+#define GL_CHROMIUM_compressed_copy_texture 1
+typedef void(GL_APIENTRYP PFNGLCOMPRESSEDCOPYTEXTURECHROMIUMPROC)(GLuint sourceId, GLuint destId);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId);
+#endif
+#endif /* GL_CHROMIUM_compressed_copy_texture */
+
+
+#ifndef GL_ANGLE_copy_texture_3d
+#define GL_ANGLE_copy_texture_3d 1
+typedef void(GL_APIENTRYP PFNGLCOPYTEXTURE3DANGLEPROC)(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+typedef void(GL_APIENTRYP PFNGLCOPYSUBTEXTURE3DANGLEPROC)(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint 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);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCopyTexture3DANGLE(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+GL_APICALL 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,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+#endif
+#endif /* GL_ANGLE_copy_texture_3d */
+
+#ifndef GL_CHROMIUM_sync_query
+#define GL_CHROMIUM_sync_query 1
+#define GL_COMMANDS_COMPLETED_CHROMIUM 0x84F7
+#endif /* GL_CHROMIUM_sync_query */
+
+#ifndef GL_EXT_texture_compression_s3tc_srgb
+#define GL_EXT_texture_compression_s3tc_srgb 1
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#endif /* GL_EXT_texture_compression_s3tc_srgb */
+
+#ifndef GL_ANGLE_lossy_etc_decode
+#define GL_ANGLE_lossy_etc_decode 1
+#define GL_ETC1_RGB8_LOSSY_DECODE_ANGLE 0x9690
+#define GL_COMPRESSED_R11_LOSSY_DECODE_EAC_ANGLE 0x9691
+#define GL_COMPRESSED_SIGNED_R11_LOSSY_DECODE_EAC_ANGLE 0x9692
+#define GL_COMPRESSED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9693
+#define GL_COMPRESSED_SIGNED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9694
+#define GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE 0x9695
+#define GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE 0x9696
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9697
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9698
+#define GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x9699
+#define GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x969A
+#endif /* GL_ANGLE_lossy_etc_decode */
+
+#ifndef GL_ANGLE_robust_client_memory
+#define GL_ANGLE_robust_client_memory 1
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANVROBUSTANGLEPROC) (GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETFLOATVROBUSTANGLEPROC) (GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *data);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVROBUSTANGLEPROC) (GLenum target, GLenum attachment, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERVROBUSTANGLEPROC) (GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVROBUSTANGLEPROC) (GLuint program, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERIVROBUSTANGLEPROC) (GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVROBUSTANGLEPROC) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVROBUSTANGLEPROC) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVROBUSTANGLEPROC) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVROBUSTANGLEPROC) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVROBUSTANGLEPROC) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, void **pointer);
+typedef void (GL_APIENTRYP PFNGLREADPIXELSROBUSTANGLEPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, GLsizei *rows, void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DROBUSTANGLEPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DROBUSTANGLEPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DROBUSTANGLEPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DROBUSTANGLEPROC) (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);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DROBUSTANGLEPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DROBUSTANGLEPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLsizei bufSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DROBUSTANGLEPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DROBUSTANGLEPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, GLsizei bufSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLGETQUERYIVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVROBUSTANGLEPROC) (GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VROBUSTANGLEPROC) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data);
+typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATIVROBUSTANGLEPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIIVROBUSTANGLEPROC) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIUIVROBUSTANGLEPROC) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMUIVROBUSTANGLEPROC) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVROBUSTANGLEPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64VROBUSTANGLEPROC) (GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VROBUSTANGLEPROC) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint64 *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVROBUSTANGLEPROC) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVROBUSTANGLEPROC) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLfloat *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVROBUSTANGLEPROC) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVROBUSTANGLEPROC) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMINTERFACEIVROBUSTANGLEPROC) (GLuint program, GLenum programInterface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANI_VROBUSTANGLEPROC) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLGETMULTISAMPLEFVROBUSTANGLEPROC) (GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, GLfloat *val);
+typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERIVROBUSTANGLEPROC) (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERFVROBUSTANGLEPROC) (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETPOINTERVROBUSTANGLEROBUSTANGLEPROC) (GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSROBUSTANGLEPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, GLsizei *rows, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVROBUSTANGLEPROC) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVROBUSTANGLEPROC) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVROBUSTANGLEPROC) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, const GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVROBUSTANGLEPROC) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVROBUSTANGLEPROC) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVROBUSTANGLEPROC) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLuint *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVROBUSTANGLEPROC) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVROBUSTANGLEPROC) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVROBUSTANGLEPROC)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VROBUSTANGLEPROC)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VROBUSTANGLEPROC)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint64 *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetBooleanvRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetFloatvRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *data);
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameterivRobustANGLE (GLenum target, GLenum attachment, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetIntegervRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data);
+GL_APICALL void GL_APIENTRY glGetProgramivRobustANGLE (GLuint program, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderivRobustANGLE (GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterfvRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetUniformfvRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetUniformivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribfvRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribPointervRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, void **pointer);
+GL_APICALL 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);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glTexParameterfvRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLfloat *params);
+GL_APICALL void GL_APIENTRY glTexParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
+GL_APICALL 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);
+GL_APICALL 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);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glCompressedTexImage2DRobustANGLE(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage2DRobustANGLE(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLsizei bufSize, const void *data);
+GL_APICALL void GL_APIENTRY glCompressedTexImage3DRobustANGLE(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data);
+GL_APICALL 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 bufSize, const void *data);
+GL_APICALL void GL_APIENTRY glGetQueryivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectuivRobustANGLE (GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glGetBufferPointervRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
+GL_APICALL void GL_APIENTRY glGetIntegeri_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data);
+GL_APICALL void GL_APIENTRY glGetInternalformativRobustANGLE (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIuivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glGetUniformuivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockivRobustANGLE (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetInteger64vRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data);
+GL_APICALL void GL_APIENTRY glGetInteger64i_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint64 *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameteri64vRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
+GL_APICALL void GL_APIENTRY glSamplerParameterivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterfvRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLfloat *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterfvRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetFramebufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetProgramInterfaceivRobustANGLE (GLuint program, GLenum programInterface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetBooleani_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLboolean *data);
+GL_APICALL void GL_APIENTRY glGetMultisamplefvRobustANGLE (GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, GLfloat *val);
+GL_APICALL void GL_APIENTRY glGetTexLevelParameterivRobustANGLE (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexLevelParameterfvRobustANGLE (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetPointervRobustANGLERobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, void **params);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glGetnUniformfvRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetnUniformivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetnUniformuivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glTexParameterIivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexParameterIuivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLuint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIuivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glSamplerParameterIivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterIuivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLuint *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectivRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjecti64vRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectui64vRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint64 *params);
+#endif
+#endif /* GL_ANGLE_robust_client_memory */
+
+#ifndef GL_ANGLE_program_cache_control
+#define GL_ANGLE_program_cache_control 1
+#define GL_PROGRAM_CACHE_ENABLED_ANGLE 0x93AC
+#endif /* GL_ANGLE_program_cache_control */
+
+#ifndef GL_ANGLE_texture_rectangle
+#define GL_ANGLE_texture_rectangle 1
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE 0x84F8
+#define GL_TEXTURE_RECTANGLE_ANGLE 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_ANGLE 0x84F6
+#define GL_SAMPLER_2D_RECT_ANGLE 0x8B63
+#endif /* GL_ANGLE_texture_rectangle */
+
+#ifndef GL_ANGLE_texture_multisample
+#define GL_ANGLE_texture_multisample 1
+#define GL_SAMPLE_POSITION_ANGLE 0x8E50
+#define GL_SAMPLE_MASK_ANGLE 0x8E51
+#define GL_SAMPLE_MASK_VALUE_ANGLE 0x8E52
+#define GL_TEXTURE_2D_MULTISAMPLE_ANGLE 0x9100
+#define GL_MAX_SAMPLE_MASK_WORDS_ANGLE 0x8E59
+#define GL_MAX_COLOR_TEXTURE_SAMPLES_ANGLE 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES_ANGLE 0x910F
+#define GL_MAX_INTEGER_SAMPLES_ANGLE 0x9110
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ANGLE 0x9104
+#define GL_TEXTURE_SAMPLES_ANGLE 0x9106
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS_ANGLE 0x9107
+typedef void(GL_APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEANGLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void(GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERFVANGLEPROC)(GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void(GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERIVANGLEPROC)(GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETMULTISAMPLEFVANGLEPROC)(GLenum pname, GLuint index, GLfloat *val);
+typedef void (GL_APIENTRYP PFNGLSAMPLEMASKIANGLEPROC)(GLuint maskNumber, GLbitfield mask);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexStorage2DMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+GL_APICALL void GL_APIENTRY glGetTexLevelParameterfvANGLE(GLenum target, GLint level, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetTexLevelParameterivANGLE(GLenum target, GLint level, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetMultisamplefvANGLE(GLenum pname, GLuint index, GLfloat *val);
+GL_APICALL void GL_APIENTRY glSampleMaskiANGLE(GLuint maskNumber, GLbitfield mask);
+#endif
+#endif // !GL_ANGLE_texture_multisample
+
+#ifndef GL_ANGLE_get_tex_level_parameter
+#define GL_ANGLE_get_tex_level_parameter 1
+typedef void(GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERFVANGLEPROC)(GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void(GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERIVANGLEPROC)(GLenum target, GLint level, GLenum pname, GLint *params);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetTexLevelParameterfvANGLE(GLenum target, GLint level, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetTexLevelParameterivANGLE(GLenum target, GLint level, GLenum pname, GLint *params);
+#endif
+#endif /* GL_ANGLE_get_tex_level_parameter */
+
+#ifndef GL_ANGLE_multi_draw
+#define GL_ANGLE_multi_draw 1
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSANGLEPROC) (GLenum mode, const GLint *firsts, const GLsizei *counts, GLsizei drawcount);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, const GLint *firsts, const GLsizei *counts, const GLsizei *instanceCounts, GLsizei drawcount);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSANGLEPROC) (GLenum mode, const GLsizei *counts, GLenum type, const GLvoid* const *indices, GLsizei drawcount);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, const GLsizei *counts, GLenum type, const GLvoid* const *indices, const GLsizei *instanceCounts, GLsizei drawcount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMultiDrawArraysANGLE (GLenum mode, const GLint *firsts, const GLsizei *counts, GLsizei drawcount);
+GL_APICALL void GL_APIENTRY glMultiDrawArraysInstancedANGLE (GLenum mode, const GLint *firsts, const GLsizei *counts, const GLsizei *instanceCounts, GLsizei drawcount);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsANGLE (GLenum mode, const GLsizei *counts, GLenum type, const GLvoid* const *indices, GLsizei drawcount);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsInstancedANGLE (GLenum mode, const GLsizei *counts, GLenum type, const GLvoid* const *indices, const GLsizei *instanceCounts, GLsizei drawcount);
+#endif
+#endif /* GL_ANGLE_multi_draw */
+
+#ifndef GL_ANGLE_base_vertex_base_instance
+#define GL_ANGLE_base_vertex_base_instance 1
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount, GLuint baseInstance);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instanceCount, GLint baseVertex, GLuint baseInstance);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSINSTANCEDBASEINSTANCEANGLEPROC) (GLenum mode, const GLsizei *firsts, const GLsizei *counts, const GLsizei *instanceCounts, const GLuint *baseInstances, GLsizei drawCount);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEANGLEPROC) (GLenum mode, const GLsizei *counts, GLenum type, const GLvoid* const *indices, const GLsizei *instanceCounts, const GLint *baseVertices, const GLuint *baseInstances, GLsizei drawCount);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawArraysInstancedBaseInstanceANGLE (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount, GLuint baseInstance);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceANGLE (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instanceCount, GLint baseVertex, GLuint baseInstance);
+GL_APICALL void GL_APIENTRY glMultiDrawArraysInstancedBaseInstanceANGLE (GLenum mode, const GLsizei *firsts, const GLsizei *counts, const GLsizei *instanceCounts, const GLuint *baseInstances, GLsizei drawCount);
+GL_APICALL 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);
+#endif
+#endif
+
+#ifndef GL_CHROMIUM_bind_uniform_location
+#define GL_CHROMIUM_bind_uniform_location 1
+typedef void (GL_APIENTRYP PFNGLBINDUNIFORMLOCATIONCHROMIUMPROC)(GLuint program, GLint location, const GLchar *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBindUniformLocationCHROMIUM(GLuint program, GLint location, const GLchar *name);
+#endif
+#endif /* GL_CHROMIUM_bind_uniform_location */
+
+/* GL_CHROMIUM_lose_context */
+#ifndef GL_CHROMIUM_lose_context
+#define GL_CHROMIUM_lose_context 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glLoseContextCHROMIUM(GLenum current, GLenum other);
+#endif
+typedef void (GL_APIENTRYP PFNGLLOSECONTEXTCHROMIUMPROC) (GLenum current, GLenum other);
+#endif /* GL_CHROMIUM_lose_context */
+
+#ifndef GL_ANGLE_texture_external_update
+#define GL_ANGLE_texture_external_update 1
+#define GL_TEXTURE_NATIVE_ID_ANGLE 0x3481
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DEXTERNALANGLEPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type);
+typedef void (GL_APIENTRYP PFNGLINVALIDATETEXTUREANGLEPROC) (GLenum target);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexImage2DExternalANGLE (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type);
+GL_APICALL void GL_APIENTRY glInvalidateTextureANGLE (GLenum target);
+#endif
+#endif /* GL_ANGLE_texture_external_update */
+
+#ifndef GL_ANGLE_get_image
+#define GL_ANGLE_get_image
+typedef void (GL_APIENTRYP PFNGLGETTEXIMAGEANGLEPROC) (GLenum target, GLint level, GLenum format, GLenum type, void *pixels);
+typedef void (GL_APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEANGLEPROC) (GLenum target, GLint level, void *pixels);
+typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERIMAGEANGLEPROC) (GLenum target, GLenum format, GLenum type, void *pixels);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetTexImageANGLE (GLenum target, GLint level, GLenum format, GLenum type, void *pixels);
+GL_APICALL void GL_APIENTRY glGetCompressedTexImageANGLE (GLenum target, GLint level, void *pixels);
+GL_APICALL void GL_APIENTRY glGetRenderbufferImageANGLE (GLenum target, GLenum format, GLenum type, void *pixels);
+#endif
+#endif /* GL_ANGLE_get_image */
+
+#ifndef GL_WEBGL_video_texture
+#define GL_WEBGL_video_texture 1
+#define GL_TEXTURE_VIDEO_IMAGE_WEBGL 0x9248
+#define GL_SAMPLER_VIDEO_IMAGE_WEBGL 0x9249
+#endif /* GL_WEBGL_video_texture */
+
+#ifndef GL_ANGLE_memory_object_flags
+#define GL_ANGLE_memory_object_flags 1
+#define GL_CREATE_SPARSE_BINDING_BIT_ANGLE 0x00000001
+#define GL_CREATE_SPARSE_RESIDENCY_BIT_ANGLE 0x00000002
+#define GL_CREATE_SPARSE_ALIASED_BIT_ANGLE 0x00000004
+#define GL_CREATE_MUTABLE_FORMAT_BIT_ANGLE 0x00000008
+#define GL_CREATE_CUBE_COMPATIBLE_BIT_ANGLE 0x00000010
+#define GL_CREATE_ALIAS_BIT_ANGLE 0x00000400
+#define GL_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_ANGLE 0x00000040
+#define GL_CREATE_2D_ARRAY_COMPATIBLE_BIT_ANGLE 0x00000020
+#define GL_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_ANGLE 0x00000080
+#define GL_CREATE_EXTENDED_USAGE_BIT_ANGLE 0x00000100
+#define GL_CREATE_PROTECTED_BIT_ANGLE 0x00000800
+#define GL_CREATE_DISJOINT_BIT_ANGLE 0x00000200
+#define GL_CREATE_CORNER_SAMPLED_BIT_ANGLE 0x00002000
+#define GL_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_ANGLE 0x00001000
+#define GL_CREATE_SUBSAMPLED_BIT_ANGLE 0x00004000
+#define GL_USAGE_TRANSFER_SRC_BIT_ANGLE 0x00000001
+#define GL_USAGE_TRANSFER_DST_BIT_ANGLE 0x00000002
+#define GL_USAGE_SAMPLED_BIT_ANGLE 0x00000004
+#define GL_USAGE_STORAGE_BIT_ANGLE 0x00000008
+#define GL_USAGE_COLOR_ATTACHMENT_BIT_ANGLE 0x00000010
+#define GL_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT_ANGLE 0x00000020
+#define GL_USAGE_TRANSIENT_ATTACHMENT_BIT_ANGLE 0x00000040
+#define GL_USAGE_INPUT_ATTACHMENT_BIT_ANGLE 0x00000080
+#define GL_USAGE_SHADING_RATE_IMAGE_BIT_ANGLE 0x00000100
+#define GL_USAGE_FRAGMENT_DENSITY_MAP_BIT_ANGLE 0x00000200
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEMFLAGS2DANGLEPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset, GLbitfield createFlags, GLbitfield usageFlags, const void *imageCreateInfoPNext);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEMFLAGS2DMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset, GLbitfield createFlags, GLbitfield usageFlags, const void *imageCreateInfoPNext);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEMFLAGS3DANGLEPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLbitfield createFlags, GLbitfield usageFlags, const void *imageCreateInfoPNext);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEMFLAGS3DMULTISAMPLEANGLEPROC) (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);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL 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);
+GL_APICALL 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);
+GL_APICALL 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);
+GL_APICALL 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);
+#endif
+#endif /* GL_ANGLE_memory_object_flags */
+
+#ifndef GL_ANGLE_memory_object_fuchsia
+#define GL_ANGLE_memory_object_fuchsia 1
+#define GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE 0x93AE
+typedef void(GL_APIENTRYP PFNGLIMPORTMEMORYZIRCONHANDLEANGLEPROC)(GLuint memory,
+ GLuint64 size,
+ GLenum handleType,
+ GLuint handle);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportMemoryZirconHandleANGLE(GLuint memory,
+ GLuint64 size,
+ GLenum handleType,
+ GLuint handle);
+#endif
+#endif /* GL_ANGLE_memory_object_fuchsia */
+
+#ifndef GL_ANGLE_semaphore_fuchsia
+#define GL_ANGLE_semaphore_fuchsia 1
+#define GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE 0x93AF
+typedef void(GL_APIENTRYP PFNGLIMPORTSEMAPHOREZIRCONHANDLEANGLEPROC)(GLuint semaphore,
+ GLenum handleType,
+ GLuint handle);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportSemaphoreZirconHandleANGLE(GLuint memory,
+ GLenum handleType,
+ GLuint handle);
+#endif
+#endif /* GL_ANGLE_semaphore_fuchsia */
+
+#ifndef GL_ANGLE_vulkan_image
+#define GL_ANGLE_vulkan_image 1
+typedef void(GL_APIENTRYP PFNGLACQUIRETEXTURESANGLEPROC)(GLuint numTexture, const GLuint *textures, const GLenum *layouts);
+typedef void(GL_APIENTRYP PFNGLRELEASETEXTURESANGLEPROC)(GLuint numTexture, const GLuint *textures, GLenum *layouts);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glAcquireTexturesANGLE(GLuint numTexture, const GLuint *textures, const GLenum *layouts);
+GL_APICALL void GL_APIENTRY glReleaseTexturesANGLE(GLuint numTexture, const GLuint *textures, GLenum *layouts);
+#endif
+#endif /* GL_ANGLE_vulkan_image */
+
+#ifndef GL_CHROMIUM_texture_filtering_hint
+#define GL_CHROMIUM_texture_filtering_hint
+#define GL_TEXTURE_FILTERING_HINT_CHROMIUM 0x8AF0
+#endif /* GL_CHROMIUM_texture_filtering_hint */
+
+#ifndef GL_NV_robustness_video_memory
+#define GL_NV_robustness_video_memory
+#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
+#endif /* GL_NV_robustness_video_memory */
+
+#ifndef GL_ANGLE_get_serialized_context_string
+#define GL_ANGLE_get_serialized_context_string
+#define GL_SERIALIZED_CONTEXT_STRING_ANGLE 0x96B0
+#endif /* GL_ANGLE_get_serialized_context_string */
+
+#ifndef GL_ANGLE_robust_fragment_shader_output
+#define GL_ANGLE_robust_fragment_shader_output
+#define GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE 0x96B9
+#endif /* GL_ANGLE_robust_fragment_shader_output */
+
+#ifndef GL_ANGLE_shader_pixel_local_storage
+#define GL_ANGLE_shader_pixel_local_storage 1
+#define GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE 0x96E0
+#define GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE 0x96E1
+#define GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE 0x96E2
+#define GL_PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE 0x96E3
+#define GL_PIXEL_LOCAL_FORMAT_ANGLE 0x96E4
+#define GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE 0x96E5
+#define GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE 0x96E6
+#define GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE 0x96E7
+#define GL_CLEAR_ANGLE 0x96E8
+#define GL_DISABLE_ANGLE 0x96E9
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERMEMORYLESSPIXELLOCALSTORAGEANGLEPROC) (GLint plane, GLenum internalformat);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREPIXELLOCALSTORAGEANGLEPROC) (GLint plane, GLuint backingtexture, GLint level, GLint layer);
+typedef void (GL_APIENTRYP PFNGLBEGINPIXELLOCALSTORAGEANGLEPROC) (GLsizei planes, const GLenum loadops[], const void *cleardata);
+typedef void (GL_APIENTRYP PFNGLENDPIXELLOCALSTORAGEANGLEPROC) ();
+typedef void (GL_APIENTRYP PFNGLPIXELLOCALSTORAGEBARRIERANGLEPROC) ();
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferMemorylessPixelLocalStorageANGLE (GLint plane, GLenum internalformat);
+GL_APICALL void GL_APIENTRY glFramebufferTexturePixelLocalStorageANGLE (GLint plane, GLuint backingtexture, GLint level, GLint layer);
+GL_APICALL void GL_APIENTRY glBeginPixelLocalStorageANGLE (GLsizei planes, const GLenum loadops[], const void *cleardata);
+GL_APICALL void GL_APIENTRY glEndPixelLocalStorageANGLE ();
+GL_APICALL void GL_APIENTRY glPixelLocalStorageBarrierANGLE ();
+#endif
+#endif /* GL_ANGLE_shader_pixel_local_storage */
+
+// clang-format on
+
+#ifndef GL_ANGLE_yuv_internal_format
+#define GL_ANGLE_yuv_internal_format
+
+// YUV formats introduced by GL_ANGLE_yuv_internal_format
+// 8-bit YUV formats
+#define GL_G8_B8R8_2PLANE_420_UNORM_ANGLE 0x96B1
+#define GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE 0x96B2
+
+// 10-bit YUV formats
+#define GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE 0x96B3
+#define GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE 0x96B4
+
+// 12-bit YUV formats
+#define GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE 0x96B5
+#define GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE 0x96B6
+
+// 16-bit YUV formats
+#define GL_G16_B16R16_2PLANE_420_UNORM_ANGLE 0x96B7
+#define GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE 0x96B8
+
+#endif /* GL_ANGLE_yuv_internal_format */
+
+#ifndef GL_ANGLE_rgbx_internal_format
+#define GL_ANGLE_rgbx_internal_format
+
+#define GL_RGBX8_ANGLE 0x96BA
+
+#endif /* GL_ANGLE_rgbx_internal_format */
+
+#ifndef GL_ANGLE_logic_op
+#define GL_ANGLE_logic_op
+
+// Enums identical to GLES1 and desktop GL
+#define GL_COLOR_LOGIC_OP_ANGLE 0x0BF2
+#define GL_LOGIC_OP_CLEAR_ANGLE 0x1500
+#define GL_LOGIC_OP_AND_ANGLE 0x1501
+#define GL_LOGIC_OP_AND_REVERSE_ANGLE 0x1502
+#define GL_LOGIC_OP_COPY_ANGLE 0x1503
+#define GL_LOGIC_OP_AND_INVERTED_ANGLE 0x1504
+#define GL_LOGIC_OP_NOOP_ANGLE 0x1505
+#define GL_LOGIC_OP_XOR_ANGLE 0x1506
+#define GL_LOGIC_OP_OR_ANGLE 0x1507
+#define GL_LOGIC_OP_NOR_ANGLE 0x1508
+#define GL_LOGIC_OP_EQUIV_ANGLE 0x1509
+#define GL_LOGIC_OP_INVERT_ANGLE 0x150A
+#define GL_LOGIC_OP_OR_REVERSE_ANGLE 0x150B
+#define GL_LOGIC_OP_COPY_INVERTED_ANGLE 0x150C
+#define GL_LOGIC_OP_OR_INVERTED_ANGLE 0x150D
+#define GL_LOGIC_OP_NAND_ANGLE 0x150E
+#define GL_LOGIC_OP_SET_ANGLE 0x150F
+typedef void (GL_APIENTRYP PFNGLLOGICOPANGLEPROC) (GLenum);
+
+#endif /* GL_ANGLE_logic_op */
+
+#endif // INCLUDE_GLES2_GL2EXT_ANGLE_H_
diff --git a/gfx/angle/checkout/include/GLES2/gl2platform.h b/gfx/angle/checkout/include/GLES2/gl2platform.h
new file mode 100644
index 0000000000..5bcce6d89e
--- /dev/null
+++ b/gfx/angle/checkout/include/GLES2/gl2platform.h
@@ -0,0 +1,27 @@
+#ifndef __gl2platform_h_
+#define __gl2platform_h_
+
+/*
+** Copyright 2017-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: Apache-2.0
+*/
+
+/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * Please contribute modifications back to Khronos as pull requests on the
+ * public github repository:
+ * https://github.com/KhronosGroup/OpenGL-Registry
+ */
+
+#include <KHR/khrplatform.h>
+
+#ifndef GL_APICALL
+#define GL_APICALL KHRONOS_APICALL
+#endif
+
+#ifndef GL_APIENTRY
+#define GL_APIENTRY KHRONOS_APIENTRY
+#endif
+
+#endif /* __gl2platform_h_ */
diff --git a/gfx/angle/checkout/include/GLES3/gl3.h b/gfx/angle/checkout/include/GLES3/gl3.h
new file mode 100644
index 0000000000..6bb4d8f919
--- /dev/null
+++ b/gfx/angle/checkout/include/GLES3/gl3.h
@@ -0,0 +1,1192 @@
+#ifndef __gles2_gl3_h_
+#define __gles2_gl3_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright 2013-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: MIT
+**
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** https://github.com/KhronosGroup/OpenGL-Registry
+*/
+
+#include <GLES3/gl3platform.h>
+
+#ifndef GL_APIENTRYP
+#define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+#ifndef GL_GLES_PROTOTYPES
+#define GL_GLES_PROTOTYPES 1
+#endif
+
+/* Generated on date 20210107 */
+
+/* Generated C header for:
+ * API: gles2
+ * Profile: common
+ * Versions considered: 2\.[0-9]|3\.0
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef GL_ES_VERSION_2_0
+#define GL_ES_VERSION_2_0 1
+#include <KHR/khrplatform.h>
+typedef khronos_int8_t GLbyte;
+typedef khronos_float_t GLclampf;
+typedef khronos_int32_t GLfixed;
+typedef khronos_int16_t GLshort;
+typedef khronos_uint16_t GLushort;
+typedef void GLvoid;
+typedef struct __GLsync *GLsync;
+typedef khronos_int64_t GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef unsigned int GLenum;
+typedef unsigned int GLuint;
+typedef char GLchar;
+typedef khronos_float_t GLfloat;
+typedef khronos_ssize_t GLsizeiptr;
+typedef khronos_intptr_t GLintptr;
+typedef unsigned int GLbitfield;
+typedef int GLint;
+typedef unsigned char GLboolean;
+typedef int GLsizei;
+typedef khronos_uint8_t GLubyte;
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_FALSE 0
+#define GL_TRUE 1
+#define GL_POINTS 0x0000
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_STRIP 0x0003
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_ZERO 0
+#define GL_ONE 1
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_FUNC_ADD 0x8006
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STATIC_DRAW 0x88E4
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_CULL_FACE 0x0B44
+#define GL_BLEND 0x0BE2
+#define GL_DITHER 0x0BD0
+#define GL_STENCIL_TEST 0x0B90
+#define GL_DEPTH_TEST 0x0B71
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_NO_ERROR 0
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+#define GL_LINE_WIDTH 0x0B21
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#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_VIEWPORT 0x0BA2
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_ALPHA_BITS 0x0D55
+#define GL_DEPTH_BITS 0x0D56
+#define GL_STENCIL_BITS 0x0D57
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_FIXED 0x140C
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_DELETE_STATUS 0x8B80
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_NEVER 0x0200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+#define GL_INVERT 0x150A
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+#define GL_NEAREST 0x2600
+#define GL_LINEAR 0x2601
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TEXTURE 0x1702
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#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_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_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_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_REPEAT 0x2901
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGB565 0x8D62
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_NONE 0
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
+typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
+typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);
+typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
+typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);
+typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
+typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
+typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void);
+typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
+typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
+typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode);
+typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
+typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
+typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture);
+typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width);
+typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);
+typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert);
+typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length);
+typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
+typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+#if GL_GLES_PROTOTYPES
+GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
+GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
+GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
+GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
+GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
+GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d);
+GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
+GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
+GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
+GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
+GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
+GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
+GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
+GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
+GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
+GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f);
+GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
+GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
+GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
+GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glFinish (void);
+GL_APICALL void GL_APIENTRY glFlush (void);
+GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
+GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
+GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
+GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
+GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures);
+GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL GLenum GL_APIENTRY glGetError (void);
+GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data);
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data);
+GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name);
+GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
+GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
+GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
+GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
+GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
+GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
+GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
+GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
+GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
+GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
+GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);
+GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length);
+GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0);
+GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0);
+GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
+GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
+GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
+GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
+GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
+GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_ES_VERSION_2_0 */
+
+#ifndef GL_ES_VERSION_3_0
+#define GL_ES_VERSION_3_0 1
+typedef khronos_uint16_t GLhalf;
+#define GL_READ_BUFFER 0x0C02
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_COLOR 0x1800
+#define GL_DEPTH 0x1801
+#define GL_STENCIL 0x1802
+#define GL_RED 0x1903
+#define GL_RGB8 0x8051
+#define GL_RGBA8 0x8058
+#define GL_RGB10_A2 0x8059
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#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_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_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#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_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#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_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_ATTACHMENT16 0x8CF0
+#define GL_COLOR_ATTACHMENT17 0x8CF1
+#define GL_COLOR_ATTACHMENT18 0x8CF2
+#define GL_COLOR_ATTACHMENT19 0x8CF3
+#define GL_COLOR_ATTACHMENT20 0x8CF4
+#define GL_COLOR_ATTACHMENT21 0x8CF5
+#define GL_COLOR_ATTACHMENT22 0x8CF6
+#define GL_COLOR_ATTACHMENT23 0x8CF7
+#define GL_COLOR_ATTACHMENT24 0x8CF8
+#define GL_COLOR_ATTACHMENT25 0x8CF9
+#define GL_COLOR_ATTACHMENT26 0x8CFA
+#define GL_COLOR_ATTACHMENT27 0x8CFB
+#define GL_COLOR_ATTACHMENT28 0x8CFC
+#define GL_COLOR_ATTACHMENT29 0x8CFD
+#define GL_COLOR_ATTACHMENT30 0x8CFE
+#define GL_COLOR_ATTACHMENT31 0x8CFF
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_HALF_FLOAT 0x140B
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_RG8 0x822B
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_COPY_READ_BUFFER_BINDING 0x8F36
+#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_RGB10_A2UI 0x906F
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+typedef void (GL_APIENTRYP PFNGLREADBUFFERPROC) (GLenum src);
+typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);
+typedef void (GL_APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (GL_APIENTRYP PFNGLISQUERYPROC) (GLuint id);
+typedef void (GL_APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
+typedef void (GL_APIENTRYP PFNGLENDQUERYPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params);
+typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params);
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
+typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (GL_APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode);
+typedef void (GL_APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);
+typedef void (GL_APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params);
+typedef GLint (GL_APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
+typedef void (GL_APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+typedef GLuint (GL_APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+typedef void (GL_APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);
+typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (GL_APIENTRYP PFNGLISSYNCPROC) (GLsync sync);
+typedef void (GL_APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);
+typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data);
+typedef void (GL_APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);
+typedef void (GL_APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);
+typedef GLboolean (GL_APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler);
+typedef void (GL_APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor);
+typedef void (GL_APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);
+typedef void (GL_APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids);
+typedef void (GL_APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids);
+typedef GLboolean (GL_APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);
+typedef void (GL_APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void);
+typedef void (GL_APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
+typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+typedef void (GL_APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params);
+#if GL_GLES_PROTOTYPES
+GL_APICALL void GL_APIENTRY glReadBuffer (GLenum src);
+GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
+GL_APICALL 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);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint *ids);
+GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids);
+GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id);
+GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glEndQuery (GLenum target);
+GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params);
+GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target);
+GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params);
+GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs);
+GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GL_APICALL void *GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length);
+GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array);
+GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
+GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
+GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array);
+GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data);
+GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode);
+GL_APICALL void GL_APIENTRY glEndTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);
+GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);
+GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v);
+GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v);
+GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params);
+GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0);
+GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1);
+GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value);
+GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value);
+GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GL_APICALL const GLubyte *GL_APIENTRY glGetStringi (GLenum name, GLuint index);
+GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);
+GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName);
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);
+GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags);
+GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync);
+GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync);
+GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64 *data);
+GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values);
+GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params);
+GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);
+GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);
+GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler);
+GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler);
+GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor);
+GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids);
+GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids);
+GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id);
+GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
+GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params);
+#endif
+#endif /* GL_ES_VERSION_3_0 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/include/GLES3/gl31.h b/gfx/angle/checkout/include/GLES3/gl31.h
new file mode 100644
index 0000000000..502d6feec8
--- /dev/null
+++ b/gfx/angle/checkout/include/GLES3/gl31.h
@@ -0,0 +1,1507 @@
+#ifndef __gles2_gl31_h_
+#define __gles2_gl31_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright 2013-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: MIT
+**
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** https://github.com/KhronosGroup/OpenGL-Registry
+*/
+
+#include <GLES3/gl3platform.h>
+
+#ifndef GL_APIENTRYP
+#define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+#ifndef GL_GLES_PROTOTYPES
+#define GL_GLES_PROTOTYPES 1
+#endif
+
+/* Generated on date 20191013 */
+
+/* Generated C header for:
+ * API: gles2
+ * Profile: common
+ * Versions considered: 2\.[0-9]|3\.[01]
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef GL_ES_VERSION_2_0
+#define GL_ES_VERSION_2_0 1
+#include <KHR/khrplatform.h>
+typedef khronos_int8_t GLbyte;
+typedef khronos_float_t GLclampf;
+typedef khronos_int32_t GLfixed;
+typedef khronos_int16_t GLshort;
+typedef khronos_uint16_t GLushort;
+typedef void GLvoid;
+typedef struct __GLsync *GLsync;
+typedef khronos_int64_t GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef unsigned int GLenum;
+typedef unsigned int GLuint;
+typedef char GLchar;
+typedef khronos_float_t GLfloat;
+typedef khronos_ssize_t GLsizeiptr;
+typedef khronos_intptr_t GLintptr;
+typedef unsigned int GLbitfield;
+typedef int GLint;
+typedef unsigned char GLboolean;
+typedef int GLsizei;
+typedef khronos_uint8_t GLubyte;
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_FALSE 0
+#define GL_TRUE 1
+#define GL_POINTS 0x0000
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_STRIP 0x0003
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_ZERO 0
+#define GL_ONE 1
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_FUNC_ADD 0x8006
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STATIC_DRAW 0x88E4
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_CULL_FACE 0x0B44
+#define GL_BLEND 0x0BE2
+#define GL_DITHER 0x0BD0
+#define GL_STENCIL_TEST 0x0B90
+#define GL_DEPTH_TEST 0x0B71
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_NO_ERROR 0
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+#define GL_LINE_WIDTH 0x0B21
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#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_VIEWPORT 0x0BA2
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_ALPHA_BITS 0x0D55
+#define GL_DEPTH_BITS 0x0D56
+#define GL_STENCIL_BITS 0x0D57
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_FIXED 0x140C
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_DELETE_STATUS 0x8B80
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_NEVER 0x0200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+#define GL_INVERT 0x150A
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+#define GL_NEAREST 0x2600
+#define GL_LINEAR 0x2601
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TEXTURE 0x1702
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#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_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_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_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_REPEAT 0x2901
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGB565 0x8D62
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_NONE 0
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
+typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
+typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);
+typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
+typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);
+typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
+typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
+typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void);
+typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
+typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
+typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode);
+typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
+typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
+typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture);
+typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width);
+typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);
+typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert);
+typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
+typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
+typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+#if GL_GLES_PROTOTYPES
+GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
+GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
+GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
+GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
+GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
+GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d);
+GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
+GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
+GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
+GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
+GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
+GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
+GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
+GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
+GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
+GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f);
+GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
+GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
+GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
+GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glFinish (void);
+GL_APICALL void GL_APIENTRY glFlush (void);
+GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
+GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
+GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
+GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
+GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures);
+GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL GLenum GL_APIENTRY glGetError (void);
+GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data);
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data);
+GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name);
+GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
+GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
+GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
+GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
+GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
+GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
+GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
+GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
+GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
+GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
+GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);
+GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
+GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0);
+GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0);
+GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
+GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
+GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
+GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
+GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
+GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_ES_VERSION_2_0 */
+
+#ifndef GL_ES_VERSION_3_0
+#define GL_ES_VERSION_3_0 1
+typedef khronos_uint16_t GLhalf;
+#define GL_READ_BUFFER 0x0C02
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_COLOR 0x1800
+#define GL_DEPTH 0x1801
+#define GL_STENCIL 0x1802
+#define GL_RED 0x1903
+#define GL_RGB8 0x8051
+#define GL_RGBA8 0x8058
+#define GL_RGB10_A2 0x8059
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#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_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_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#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_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#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_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_ATTACHMENT16 0x8CF0
+#define GL_COLOR_ATTACHMENT17 0x8CF1
+#define GL_COLOR_ATTACHMENT18 0x8CF2
+#define GL_COLOR_ATTACHMENT19 0x8CF3
+#define GL_COLOR_ATTACHMENT20 0x8CF4
+#define GL_COLOR_ATTACHMENT21 0x8CF5
+#define GL_COLOR_ATTACHMENT22 0x8CF6
+#define GL_COLOR_ATTACHMENT23 0x8CF7
+#define GL_COLOR_ATTACHMENT24 0x8CF8
+#define GL_COLOR_ATTACHMENT25 0x8CF9
+#define GL_COLOR_ATTACHMENT26 0x8CFA
+#define GL_COLOR_ATTACHMENT27 0x8CFB
+#define GL_COLOR_ATTACHMENT28 0x8CFC
+#define GL_COLOR_ATTACHMENT29 0x8CFD
+#define GL_COLOR_ATTACHMENT30 0x8CFE
+#define GL_COLOR_ATTACHMENT31 0x8CFF
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_HALF_FLOAT 0x140B
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_RG8 0x822B
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_COPY_READ_BUFFER_BINDING 0x8F36
+#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_RGB10_A2UI 0x906F
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+typedef void (GL_APIENTRYP PFNGLREADBUFFERPROC) (GLenum src);
+typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);
+typedef void (GL_APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (GL_APIENTRYP PFNGLISQUERYPROC) (GLuint id);
+typedef void (GL_APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
+typedef void (GL_APIENTRYP PFNGLENDQUERYPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params);
+typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params);
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
+typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (GL_APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode);
+typedef void (GL_APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);
+typedef void (GL_APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params);
+typedef GLint (GL_APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
+typedef void (GL_APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+typedef GLuint (GL_APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+typedef void (GL_APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);
+typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (GL_APIENTRYP PFNGLISSYNCPROC) (GLsync sync);
+typedef void (GL_APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);
+typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data);
+typedef void (GL_APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);
+typedef void (GL_APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);
+typedef GLboolean (GL_APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler);
+typedef void (GL_APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor);
+typedef void (GL_APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);
+typedef void (GL_APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids);
+typedef void (GL_APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids);
+typedef GLboolean (GL_APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);
+typedef void (GL_APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void);
+typedef void (GL_APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
+typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+typedef void (GL_APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
+#if GL_GLES_PROTOTYPES
+GL_APICALL void GL_APIENTRY glReadBuffer (GLenum src);
+GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
+GL_APICALL 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);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint *ids);
+GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids);
+GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id);
+GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glEndQuery (GLenum target);
+GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params);
+GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target);
+GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params);
+GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs);
+GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GL_APICALL void *GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length);
+GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array);
+GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
+GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
+GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array);
+GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data);
+GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode);
+GL_APICALL void GL_APIENTRY glEndTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);
+GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);
+GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v);
+GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v);
+GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params);
+GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0);
+GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1);
+GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value);
+GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value);
+GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GL_APICALL const GLubyte *GL_APIENTRY glGetStringi (GLenum name, GLuint index);
+GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);
+GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName);
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);
+GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags);
+GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync);
+GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync);
+GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64 *data);
+GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params);
+GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);
+GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);
+GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler);
+GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler);
+GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor);
+GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids);
+GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids);
+GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id);
+GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
+GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
+#endif
+#endif /* GL_ES_VERSION_3_0 */
+
+#ifndef GL_ES_VERSION_3_1
+#define GL_ES_VERSION_3_1 1
+#define GL_COMPUTE_SHADER 0x91B9
+#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
+#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
+#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
+#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
+#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
+#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
+#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
+#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
+#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267
+#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
+#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
+#define GL_COMPUTE_SHADER_BIT 0x00000020
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+#define GL_MAX_UNIFORM_LOCATIONS 0x826E
+#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310
+#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311
+#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313
+#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314
+#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315
+#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
+#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+#define GL_UNIFORM 0x92E1
+#define GL_UNIFORM_BLOCK 0x92E2
+#define GL_PROGRAM_INPUT 0x92E3
+#define GL_PROGRAM_OUTPUT 0x92E4
+#define GL_BUFFER_VARIABLE 0x92E5
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
+#define GL_ACTIVE_RESOURCES 0x92F5
+#define GL_MAX_NAME_LENGTH 0x92F6
+#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
+#define GL_NAME_LENGTH 0x92F9
+#define GL_TYPE 0x92FA
+#define GL_ARRAY_SIZE 0x92FB
+#define GL_OFFSET 0x92FC
+#define GL_BLOCK_INDEX 0x92FD
+#define GL_ARRAY_STRIDE 0x92FE
+#define GL_MATRIX_STRIDE 0x92FF
+#define GL_IS_ROW_MAJOR 0x9300
+#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define GL_BUFFER_BINDING 0x9302
+#define GL_BUFFER_DATA_SIZE 0x9303
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#define GL_ACTIVE_VARIABLES 0x9305
+#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306
+#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
+#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
+#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C
+#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
+#define GL_LOCATION 0x930E
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
+#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
+#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
+#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6
+#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
+#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
+#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
+#define GL_IMAGE_BINDING_NAME 0x8F3A
+#define GL_IMAGE_BINDING_LEVEL 0x8F3B
+#define GL_IMAGE_BINDING_LAYERED 0x8F3C
+#define GL_IMAGE_BINDING_LAYER 0x8F3D
+#define GL_IMAGE_BINDING_ACCESS 0x8F3E
+#define GL_IMAGE_BINDING_FORMAT 0x906E
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#define GL_UNIFORM_BARRIER_BIT 0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define GL_COMMAND_BARRIER_BIT 0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
+#define GL_IMAGE_2D 0x904D
+#define GL_IMAGE_3D 0x904E
+#define GL_IMAGE_CUBE 0x9050
+#define GL_IMAGE_2D_ARRAY 0x9053
+#define GL_INT_IMAGE_2D 0x9058
+#define GL_INT_IMAGE_3D 0x9059
+#define GL_INT_IMAGE_CUBE 0x905B
+#define GL_INT_IMAGE_2D_ARRAY 0x905E
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
+#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
+#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define GL_READ_ONLY 0x88B8
+#define GL_WRITE_ONLY 0x88B9
+#define GL_READ_WRITE 0x88BA
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
+#define GL_SHADER_STORAGE_BUFFER_START 0x90D4
+#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
+#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
+#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
+#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
+#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
+#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
+#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
+#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA
+#define GL_STENCIL_INDEX 0x1901
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_TEXTURE_WIDTH 0x1000
+#define GL_TEXTURE_HEIGHT 0x1001
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define GL_TEXTURE_RED_SIZE 0x805C
+#define GL_TEXTURE_GREEN_SIZE 0x805D
+#define GL_TEXTURE_BLUE_SIZE 0x805E
+#define GL_TEXTURE_ALPHA_SIZE 0x805F
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_VERTEX_ATTRIB_BINDING 0x82D4
+#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
+#define GL_VERTEX_BINDING_DIVISOR 0x82D6
+#define GL_VERTEX_BINDING_OFFSET 0x82D7
+#define GL_VERTEX_BINDING_STRIDE 0x82D8
+#define GL_VERTEX_BINDING_BUFFER 0x8F4F
+#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9
+#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA
+#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5
+typedef void (GL_APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+typedef void (GL_APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect);
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params);
+typedef GLuint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings);
+typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines);
+typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines);
+typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
+typedef void (GL_APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GL_APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val);
+typedef void (GL_APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask);
+typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC) (GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex);
+typedef void (GL_APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor);
+#if GL_GLES_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+GL_APICALL void GL_APIENTRY glDispatchComputeIndirect (GLintptr indirect);
+GL_APICALL void GL_APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect);
+GL_APICALL void GL_APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect);
+GL_APICALL void GL_APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params);
+GL_APICALL GLuint GL_APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name);
+GL_APICALL void GL_APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program);
+GL_APICALL void GL_APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program);
+GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings);
+GL_APICALL void GL_APIENTRY glBindProgramPipeline (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines);
+GL_APICALL void GL_APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines);
+GL_APICALL GLboolean GL_APIENTRY glIsProgramPipeline (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0);
+GL_APICALL void GL_APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1);
+GL_APICALL void GL_APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GL_APICALL void GL_APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GL_APICALL void GL_APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0);
+GL_APICALL void GL_APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1);
+GL_APICALL void GL_APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void GL_APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void GL_APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0);
+GL_APICALL void GL_APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GL_APICALL void GL_APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GL_APICALL void GL_APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GL_APICALL void GL_APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glValidateProgramPipeline (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+GL_APICALL void GL_APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data);
+GL_APICALL void GL_APIENTRY glMemoryBarrier (GLbitfield barriers);
+GL_APICALL void GL_APIENTRY glMemoryBarrierByRegion (GLbitfield barriers);
+GL_APICALL void GL_APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+GL_APICALL void GL_APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val);
+GL_APICALL void GL_APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask);
+GL_APICALL void GL_APIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+GL_APICALL void GL_APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+GL_APICALL void GL_APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+GL_APICALL void GL_APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex);
+GL_APICALL void GL_APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor);
+#endif
+#endif /* GL_ES_VERSION_3_1 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/include/GLES3/gl32.h b/gfx/angle/checkout/include/GLES3/gl32.h
new file mode 100644
index 0000000000..ae56b0e95f
--- /dev/null
+++ b/gfx/angle/checkout/include/GLES3/gl32.h
@@ -0,0 +1,1808 @@
+#ifndef __gles2_gl32_h_
+#define __gles2_gl32_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright 2013-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: MIT
+**
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** https://github.com/KhronosGroup/OpenGL-Registry
+*/
+
+#include <GLES3/gl3platform.h>
+
+#ifndef GL_APIENTRYP
+#define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+#ifndef GL_GLES_PROTOTYPES
+#define GL_GLES_PROTOTYPES 1
+#endif
+
+/* Generated on date 20191013 */
+
+/* Generated C header for:
+ * API: gles2
+ * Profile: common
+ * Versions considered: 2\.[0-9]|3\.[012]
+ * Versions emitted: .*
+ * Default extensions included: None
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef GL_ES_VERSION_2_0
+#define GL_ES_VERSION_2_0 1
+#include <KHR/khrplatform.h>
+typedef khronos_int8_t GLbyte;
+typedef khronos_float_t GLclampf;
+typedef khronos_int32_t GLfixed;
+typedef khronos_int16_t GLshort;
+typedef khronos_uint16_t GLushort;
+typedef void GLvoid;
+typedef struct __GLsync *GLsync;
+typedef khronos_int64_t GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef unsigned int GLenum;
+typedef unsigned int GLuint;
+typedef char GLchar;
+typedef khronos_float_t GLfloat;
+typedef khronos_ssize_t GLsizeiptr;
+typedef khronos_intptr_t GLintptr;
+typedef unsigned int GLbitfield;
+typedef int GLint;
+typedef unsigned char GLboolean;
+typedef int GLsizei;
+typedef khronos_uint8_t GLubyte;
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_FALSE 0
+#define GL_TRUE 1
+#define GL_POINTS 0x0000
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_STRIP 0x0003
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_ZERO 0
+#define GL_ONE 1
+#define GL_SRC_COLOR 0x0300
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DST_ALPHA 0x0304
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_DST_COLOR 0x0306
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_FUNC_ADD 0x8006
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STATIC_DRAW 0x88E4
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_FRONT 0x0404
+#define GL_BACK 0x0405
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_CULL_FACE 0x0B44
+#define GL_BLEND 0x0BE2
+#define GL_DITHER 0x0BD0
+#define GL_STENCIL_TEST 0x0B90
+#define GL_DEPTH_TEST 0x0B71
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_NO_ERROR 0
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVALID_OPERATION 0x0502
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_CW 0x0900
+#define GL_CCW 0x0901
+#define GL_LINE_WIDTH 0x0B21
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_FRONT_FACE 0x0B46
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#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_VIEWPORT 0x0BA2
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_RED_BITS 0x0D52
+#define GL_GREEN_BITS 0x0D53
+#define GL_BLUE_BITS 0x0D54
+#define GL_ALPHA_BITS 0x0D55
+#define GL_DEPTH_BITS 0x0D56
+#define GL_STENCIL_BITS 0x0D57
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_BYTE 0x1400
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_SHORT 0x1402
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_INT 0x1404
+#define GL_UNSIGNED_INT 0x1405
+#define GL_FLOAT 0x1406
+#define GL_FIXED 0x140C
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_ALPHA 0x1906
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_LUMINANCE 0x1909
+#define GL_LUMINANCE_ALPHA 0x190A
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_DELETE_STATUS 0x8B80
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_NEVER 0x0200
+#define GL_LESS 0x0201
+#define GL_EQUAL 0x0202
+#define GL_LEQUAL 0x0203
+#define GL_GREATER 0x0204
+#define GL_NOTEQUAL 0x0205
+#define GL_GEQUAL 0x0206
+#define GL_ALWAYS 0x0207
+#define GL_KEEP 0x1E00
+#define GL_REPLACE 0x1E01
+#define GL_INCR 0x1E02
+#define GL_DECR 0x1E03
+#define GL_INVERT 0x150A
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+#define GL_VERSION 0x1F02
+#define GL_EXTENSIONS 0x1F03
+#define GL_NEAREST 0x2600
+#define GL_LINEAR 0x2601
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TEXTURE 0x1702
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#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_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_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_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_REPEAT 0x2901
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGB565 0x8D62
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_NONE 0
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
+typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
+typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);
+typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
+typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func);
+typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);
+typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
+typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap);
+typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
+typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void);
+typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
+typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
+typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode);
+typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
+typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
+typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
+typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture);
+typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width);
+typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units);
+typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert);
+typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
+typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
+typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass);
+typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+#if GL_GLES_PROTOTYPES
+GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture);
+GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
+GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
+GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
+GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
+GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target);
+GL_APICALL void GL_APIENTRY glClear (GLbitfield mask);
+GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d);
+GL_APICALL void GL_APIENTRY glClearStencil (GLint s);
+GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
+GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL GLuint GL_APIENTRY glCreateProgram (void);
+GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type);
+GL_APICALL void GL_APIENTRY glCullFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
+GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
+GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
+GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader);
+GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
+GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func);
+GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag);
+GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f);
+GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
+GL_APICALL void GL_APIENTRY glDisable (GLenum cap);
+GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
+GL_APICALL void GL_APIENTRY glEnable (GLenum cap);
+GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index);
+GL_APICALL void GL_APIENTRY glFinish (void);
+GL_APICALL void GL_APIENTRY glFlush (void);
+GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode);
+GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
+GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target);
+GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
+GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
+GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures);
+GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL GLenum GL_APIENTRY glGetError (void);
+GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data);
+GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data);
+GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name);
+GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
+GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
+GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode);
+GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
+GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
+GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program);
+GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader);
+GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture);
+GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width);
+GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
+GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void);
+GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);
+GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length);
+GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
+GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
+GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0);
+GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0);
+GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
+GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
+GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
+GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUseProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program);
+GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
+GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
+GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
+GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
+GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_ES_VERSION_2_0 */
+
+#ifndef GL_ES_VERSION_3_0
+#define GL_ES_VERSION_3_0 1
+typedef khronos_uint16_t GLhalf;
+#define GL_READ_BUFFER 0x0C02
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_COLOR 0x1800
+#define GL_DEPTH 0x1801
+#define GL_STENCIL 0x1802
+#define GL_RED 0x1903
+#define GL_RGB8 0x8051
+#define GL_RGBA8 0x8058
+#define GL_RGB10_A2 0x8059
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#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_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_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#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_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#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_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_ATTACHMENT16 0x8CF0
+#define GL_COLOR_ATTACHMENT17 0x8CF1
+#define GL_COLOR_ATTACHMENT18 0x8CF2
+#define GL_COLOR_ATTACHMENT19 0x8CF3
+#define GL_COLOR_ATTACHMENT20 0x8CF4
+#define GL_COLOR_ATTACHMENT21 0x8CF5
+#define GL_COLOR_ATTACHMENT22 0x8CF6
+#define GL_COLOR_ATTACHMENT23 0x8CF7
+#define GL_COLOR_ATTACHMENT24 0x8CF8
+#define GL_COLOR_ATTACHMENT25 0x8CF9
+#define GL_COLOR_ATTACHMENT26 0x8CFA
+#define GL_COLOR_ATTACHMENT27 0x8CFB
+#define GL_COLOR_ATTACHMENT28 0x8CFC
+#define GL_COLOR_ATTACHMENT29 0x8CFD
+#define GL_COLOR_ATTACHMENT30 0x8CFE
+#define GL_COLOR_ATTACHMENT31 0x8CFF
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_HALF_FLOAT 0x140B
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_RG8 0x822B
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_COPY_READ_BUFFER_BINDING 0x8F36
+#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_RGB10_A2UI 0x906F
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+typedef void (GL_APIENTRYP PFNGLREADBUFFERPROC) (GLenum src);
+typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data);
+typedef void (GL_APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);
+typedef void (GL_APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (GL_APIENTRYP PFNGLISQUERYPROC) (GLuint id);
+typedef void (GL_APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
+typedef void (GL_APIENTRYP PFNGLENDQUERYPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params);
+typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params);
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
+typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (GL_APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode);
+typedef void (GL_APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GL_APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);
+typedef void (GL_APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params);
+typedef GLint (GL_APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GL_APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
+typedef void (GL_APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (GL_APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+typedef GLuint (GL_APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+typedef void (GL_APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);
+typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (GL_APIENTRYP PFNGLISSYNCPROC) (GLsync sync);
+typedef void (GL_APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);
+typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data);
+typedef void (GL_APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params);
+typedef void (GL_APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);
+typedef void (GL_APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);
+typedef GLboolean (GL_APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler);
+typedef void (GL_APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor);
+typedef void (GL_APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);
+typedef void (GL_APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids);
+typedef void (GL_APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids);
+typedef GLboolean (GL_APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);
+typedef void (GL_APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void);
+typedef void (GL_APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
+typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+typedef void (GL_APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
+#if GL_GLES_PROTOTYPES
+GL_APICALL void GL_APIENTRY glReadBuffer (GLenum src);
+GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);
+GL_APICALL 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);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint *ids);
+GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids);
+GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id);
+GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glEndQuery (GLenum target);
+GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params);
+GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target);
+GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params);
+GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs);
+GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GL_APICALL void *GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length);
+GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array);
+GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
+GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
+GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array);
+GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data);
+GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode);
+GL_APICALL void GL_APIENTRY glEndTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);
+GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode);
+GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v);
+GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v);
+GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params);
+GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name);
+GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0);
+GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1);
+GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value);
+GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value);
+GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GL_APICALL const GLubyte *GL_APIENTRY glGetStringi (GLenum name, GLuint index);
+GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices);
+GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName);
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);
+GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags);
+GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync);
+GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync);
+GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64 *data);
+GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data);
+GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params);
+GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);
+GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);
+GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler);
+GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler);
+GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param);
+GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor);
+GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids);
+GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids);
+GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id);
+GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void);
+GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length);
+GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
+#endif
+#endif /* GL_ES_VERSION_3_0 */
+
+#ifndef GL_ES_VERSION_3_1
+#define GL_ES_VERSION_3_1 1
+#define GL_COMPUTE_SHADER 0x91B9
+#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
+#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
+#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
+#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
+#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
+#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
+#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
+#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
+#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267
+#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
+#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
+#define GL_COMPUTE_SHADER_BIT 0x00000020
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+#define GL_MAX_UNIFORM_LOCATIONS 0x826E
+#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310
+#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311
+#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313
+#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314
+#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315
+#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
+#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+#define GL_UNIFORM 0x92E1
+#define GL_UNIFORM_BLOCK 0x92E2
+#define GL_PROGRAM_INPUT 0x92E3
+#define GL_PROGRAM_OUTPUT 0x92E4
+#define GL_BUFFER_VARIABLE 0x92E5
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
+#define GL_ACTIVE_RESOURCES 0x92F5
+#define GL_MAX_NAME_LENGTH 0x92F6
+#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
+#define GL_NAME_LENGTH 0x92F9
+#define GL_TYPE 0x92FA
+#define GL_ARRAY_SIZE 0x92FB
+#define GL_OFFSET 0x92FC
+#define GL_BLOCK_INDEX 0x92FD
+#define GL_ARRAY_STRIDE 0x92FE
+#define GL_MATRIX_STRIDE 0x92FF
+#define GL_IS_ROW_MAJOR 0x9300
+#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define GL_BUFFER_BINDING 0x9302
+#define GL_BUFFER_DATA_SIZE 0x9303
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#define GL_ACTIVE_VARIABLES 0x9305
+#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306
+#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
+#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
+#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C
+#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
+#define GL_LOCATION 0x930E
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
+#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
+#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
+#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6
+#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
+#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
+#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
+#define GL_IMAGE_BINDING_NAME 0x8F3A
+#define GL_IMAGE_BINDING_LEVEL 0x8F3B
+#define GL_IMAGE_BINDING_LAYERED 0x8F3C
+#define GL_IMAGE_BINDING_LAYER 0x8F3D
+#define GL_IMAGE_BINDING_ACCESS 0x8F3E
+#define GL_IMAGE_BINDING_FORMAT 0x906E
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#define GL_UNIFORM_BARRIER_BIT 0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define GL_COMMAND_BARRIER_BIT 0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
+#define GL_IMAGE_2D 0x904D
+#define GL_IMAGE_3D 0x904E
+#define GL_IMAGE_CUBE 0x9050
+#define GL_IMAGE_2D_ARRAY 0x9053
+#define GL_INT_IMAGE_2D 0x9058
+#define GL_INT_IMAGE_3D 0x9059
+#define GL_INT_IMAGE_CUBE 0x905B
+#define GL_INT_IMAGE_2D_ARRAY 0x905E
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
+#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
+#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define GL_READ_ONLY 0x88B8
+#define GL_WRITE_ONLY 0x88B9
+#define GL_READ_WRITE 0x88BA
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
+#define GL_SHADER_STORAGE_BUFFER_START 0x90D4
+#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
+#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
+#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
+#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
+#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
+#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
+#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
+#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA
+#define GL_STENCIL_INDEX 0x1901
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_TEXTURE_WIDTH 0x1000
+#define GL_TEXTURE_HEIGHT 0x1001
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define GL_TEXTURE_RED_SIZE 0x805C
+#define GL_TEXTURE_GREEN_SIZE 0x805D
+#define GL_TEXTURE_BLUE_SIZE 0x805E
+#define GL_TEXTURE_ALPHA_SIZE 0x805F
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_VERTEX_ATTRIB_BINDING 0x82D4
+#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
+#define GL_VERTEX_BINDING_DIVISOR 0x82D6
+#define GL_VERTEX_BINDING_OFFSET 0x82D7
+#define GL_VERTEX_BINDING_STRIDE 0x82D8
+#define GL_VERTEX_BINDING_BUFFER 0x8F4F
+#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9
+#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA
+#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5
+typedef void (GL_APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+typedef void (GL_APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect);
+typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params);
+typedef GLuint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name);
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings);
+typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines);
+typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines);
+typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (GL_APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+typedef void (GL_APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);
+typedef void (GL_APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
+typedef void (GL_APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (GL_APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val);
+typedef void (GL_APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask);
+typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC) (GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex);
+typedef void (GL_APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor);
+#if GL_GLES_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+GL_APICALL void GL_APIENTRY glDispatchComputeIndirect (GLintptr indirect);
+GL_APICALL void GL_APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect);
+GL_APICALL void GL_APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect);
+GL_APICALL void GL_APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params);
+GL_APICALL GLuint GL_APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name);
+GL_APICALL void GL_APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
+GL_APICALL void GL_APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
+GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name);
+GL_APICALL void GL_APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program);
+GL_APICALL void GL_APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program);
+GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings);
+GL_APICALL void GL_APIENTRY glBindProgramPipeline (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines);
+GL_APICALL void GL_APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines);
+GL_APICALL GLboolean GL_APIENTRY glIsProgramPipeline (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0);
+GL_APICALL void GL_APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1);
+GL_APICALL void GL_APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GL_APICALL void GL_APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GL_APICALL void GL_APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0);
+GL_APICALL void GL_APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1);
+GL_APICALL void GL_APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void GL_APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void GL_APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0);
+GL_APICALL void GL_APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GL_APICALL void GL_APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GL_APICALL void GL_APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GL_APICALL void GL_APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glValidateProgramPipeline (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GL_APICALL void GL_APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
+GL_APICALL void GL_APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data);
+GL_APICALL void GL_APIENTRY glMemoryBarrier (GLbitfield barriers);
+GL_APICALL void GL_APIENTRY glMemoryBarrierByRegion (GLbitfield barriers);
+GL_APICALL void GL_APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+GL_APICALL void GL_APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val);
+GL_APICALL void GL_APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask);
+GL_APICALL void GL_APIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params);
+GL_APICALL void GL_APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+GL_APICALL void GL_APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+GL_APICALL void GL_APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+GL_APICALL void GL_APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex);
+GL_APICALL void GL_APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor);
+#endif
+#endif /* GL_ES_VERSION_3_1 */
+
+#ifndef GL_ES_VERSION_3_2
+#define GL_ES_VERSION_3_2 1
+typedef void (GL_APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
+#define GL_MULTISAMPLE_LINE_WIDTH_RANGE 0x9381
+#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY 0x9382
+#define GL_MULTIPLY 0x9294
+#define GL_SCREEN 0x9295
+#define GL_OVERLAY 0x9296
+#define GL_DARKEN 0x9297
+#define GL_LIGHTEN 0x9298
+#define GL_COLORDODGE 0x9299
+#define GL_COLORBURN 0x929A
+#define GL_HARDLIGHT 0x929B
+#define GL_SOFTLIGHT 0x929C
+#define GL_DIFFERENCE 0x929E
+#define GL_EXCLUSION 0x92A0
+#define GL_HSL_HUE 0x92AD
+#define GL_HSL_SATURATION 0x92AE
+#define GL_HSL_COLOR 0x92AF
+#define GL_HSL_LUMINOSITY 0x92B0
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define GL_DEBUG_SOURCE_API 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define GL_DEBUG_SOURCE_OTHER 0x824B
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define GL_DEBUG_TYPE_OTHER 0x8251
+#define GL_DEBUG_TYPE_MARKER 0x8268
+#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define GL_BUFFER 0x82E0
+#define GL_SHADER 0x82E1
+#define GL_PROGRAM 0x82E2
+#define GL_VERTEX_ARRAY 0x8074
+#define GL_QUERY 0x82E3
+#define GL_PROGRAM_PIPELINE 0x82E4
+#define GL_SAMPLER 0x82E6
+#define GL_MAX_LABEL_LENGTH 0x82E8
+#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define GL_DEBUG_SEVERITY_HIGH 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define GL_DEBUG_SEVERITY_LOW 0x9148
+#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define GL_STACK_OVERFLOW 0x0503
+#define GL_STACK_UNDERFLOW 0x0504
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define GL_LAYER_PROVOKING_VERTEX 0x825E
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#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_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_UNDEFINED_VERTEX 0x8260
+#define GL_PRIMITIVES_GENERATED 0x8C87
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312
+#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309
+#define GL_PRIMITIVE_BOUNDING_BOX 0x92BE
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_LOSE_CONTEXT_ON_RESET 0x8252
+#define GL_GUILTY_CONTEXT_RESET 0x8253
+#define GL_INNOCENT_CONTEXT_RESET 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET 0x8255
+#define GL_RESET_NOTIFICATION_STRATEGY 0x8256
+#define GL_NO_RESET_NOTIFICATION 0x8261
+#define GL_CONTEXT_LOST 0x0507
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+#define GL_PATCHES 0x000E
+#define GL_PATCH_VERTICES 0x8E72
+#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define GL_TESS_GEN_MODE 0x8E76
+#define GL_TESS_GEN_SPACING 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define GL_TESS_GEN_POINT_MODE 0x8E79
+#define GL_ISOLINES 0x8E7A
+#define GL_QUADS 0x0007
+#define GL_FRACTIONAL_ODD 0x8E7B
+#define GL_FRACTIONAL_EVEN 0x8E7C
+#define GL_MAX_PATCH_VERTICES 0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221
+#define GL_IS_PER_PATCH 0x92E7
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define GL_TEXTURE_BORDER_COLOR 0x1004
+#define GL_CLAMP_TO_BORDER 0x812D
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_TEXTURE_BUFFER_BINDING 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+#define GL_IMAGE_BUFFER 0x9051
+#define GL_INT_IMAGE_BUFFER 0x905C
+#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
+#define GL_TEXTURE_BUFFER_OFFSET 0x919D
+#define GL_TEXTURE_BUFFER_SIZE 0x919E
+#define GL_COMPRESSED_RGBA_ASTC_4x4 0x93B0
+#define GL_COMPRESSED_RGBA_ASTC_5x4 0x93B1
+#define GL_COMPRESSED_RGBA_ASTC_5x5 0x93B2
+#define GL_COMPRESSED_RGBA_ASTC_6x5 0x93B3
+#define GL_COMPRESSED_RGBA_ASTC_6x6 0x93B4
+#define GL_COMPRESSED_RGBA_ASTC_8x5 0x93B5
+#define GL_COMPRESSED_RGBA_ASTC_8x6 0x93B6
+#define GL_COMPRESSED_RGBA_ASTC_8x8 0x93B7
+#define GL_COMPRESSED_RGBA_ASTC_10x5 0x93B8
+#define GL_COMPRESSED_RGBA_ASTC_10x6 0x93B9
+#define GL_COMPRESSED_RGBA_ASTC_10x8 0x93BA
+#define GL_COMPRESSED_RGBA_ASTC_10x10 0x93BB
+#define GL_COMPRESSED_RGBA_ASTC_12x10 0x93BC
+#define GL_COMPRESSED_RGBA_ASTC_12x12 0x93BD
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4 0x93D0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4 0x93D1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5 0x93D2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5 0x93D3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6 0x93D4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5 0x93D5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6 0x93D6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8 0x93D7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5 0x93D8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6 0x93D9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8 0x93DA
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10 0x93DB
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10 0x93DC
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12 0x93DD
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+typedef void (GL_APIENTRYP PFNGLBLENDBARRIERPROC) (void);
+typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (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);
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
+typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);
+typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void);
+typedef void (GL_APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETPOINTERVPROC) (GLenum pname, void **params);
+typedef void (GL_APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode);
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (GL_APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSPROC) (void);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value);
+typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+#if GL_GLES_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlendBarrier (void);
+GL_APICALL 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);
+GL_APICALL void GL_APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GL_APICALL void GL_APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+GL_APICALL void GL_APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam);
+GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+GL_APICALL void GL_APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message);
+GL_APICALL void GL_APIENTRY glPopDebugGroup (void);
+GL_APICALL void GL_APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+GL_APICALL void GL_APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
+GL_APICALL void GL_APIENTRY glGetPointerv (GLenum pname, void **params);
+GL_APICALL void GL_APIENTRY glEnablei (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glDisablei (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glBlendEquationi (GLuint buf, GLenum mode);
+GL_APICALL void GL_APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void GL_APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst);
+GL_APICALL void GL_APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GL_APICALL void GL_APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GL_APICALL GLboolean GL_APIENTRY glIsEnabledi (GLenum target, GLuint index);
+GL_APICALL void GL_APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
+GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
+GL_APICALL void GL_APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level);
+GL_APICALL void GL_APIENTRY glPrimitiveBoundingBox (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW);
+GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatus (void);
+GL_APICALL void GL_APIENTRY glReadnPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+GL_APICALL void GL_APIENTRY glGetnUniformfv (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+GL_APICALL void GL_APIENTRY glGetnUniformiv (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+GL_APICALL void GL_APIENTRY glGetnUniformuiv (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+GL_APICALL void GL_APIENTRY glMinSampleShading (GLfloat value);
+GL_APICALL void GL_APIENTRY glPatchParameteri (GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param);
+GL_APICALL void GL_APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params);
+GL_APICALL void GL_APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer);
+GL_APICALL void GL_APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GL_APICALL void GL_APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+#endif
+#endif /* GL_ES_VERSION_3_2 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/include/GLES3/gl3platform.h b/gfx/angle/checkout/include/GLES3/gl3platform.h
new file mode 100644
index 0000000000..8699212de6
--- /dev/null
+++ b/gfx/angle/checkout/include/GLES3/gl3platform.h
@@ -0,0 +1,27 @@
+#ifndef __gl3platform_h_
+#define __gl3platform_h_
+
+/*
+** Copyright 2017-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: Apache-2.0
+*/
+
+/* Platform-specific types and definitions for OpenGL ES 3.X gl3.h
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * Please contribute modifications back to Khronos as pull requests on the
+ * public github repository:
+ * https://github.com/KhronosGroup/OpenGL-Registry
+ */
+
+#include <KHR/khrplatform.h>
+
+#ifndef GL_APICALL
+#define GL_APICALL KHRONOS_APICALL
+#endif
+
+#ifndef GL_APIENTRY
+#define GL_APIENTRY KHRONOS_APIENTRY
+#endif
+
+#endif /* __gl3platform_h_ */
diff --git a/gfx/angle/checkout/include/GLSLANG/ShaderLang.h b/gfx/angle/checkout/include/GLSLANG/ShaderLang.h
new file mode 100644
index 0000000000..d55e7ebce3
--- /dev/null
+++ b/gfx/angle/checkout/include/GLSLANG/ShaderLang.h
@@ -0,0 +1,1001 @@
+//
+// 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 GLSLANG_SHADERLANG_H_
+#define GLSLANG_SHADERLANG_H_
+
+#include <stddef.h>
+
+#include "KHR/khrplatform.h"
+
+#include <array>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+//
+// This is the platform independent interface between an OGL driver
+// and the shading language compiler.
+//
+
+// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
+#include "ShaderVars.h"
+
+// Version number for shader translation API.
+// It is incremented every time the API changes.
+#define ANGLE_SH_VERSION 308
+
+enum ShShaderSpec
+{
+ SH_GLES2_SPEC,
+ SH_WEBGL_SPEC,
+
+ SH_GLES3_SPEC,
+ SH_WEBGL2_SPEC,
+
+ SH_GLES3_1_SPEC,
+ SH_WEBGL3_SPEC,
+
+ SH_GLES3_2_SPEC,
+
+ SH_GL_CORE_SPEC,
+ SH_GL_COMPATIBILITY_SPEC,
+};
+
+enum ShShaderOutput
+{
+ // ESSL output only supported in some configurations.
+ SH_ESSL_OUTPUT = 0x8B45,
+
+ // GLSL output only supported in some configurations.
+ SH_GLSL_COMPATIBILITY_OUTPUT = 0x8B46,
+ // Note: GL introduced core profiles in 1.5.
+ SH_GLSL_130_OUTPUT = 0x8B47,
+ SH_GLSL_140_OUTPUT = 0x8B80,
+ SH_GLSL_150_CORE_OUTPUT = 0x8B81,
+ SH_GLSL_330_CORE_OUTPUT = 0x8B82,
+ SH_GLSL_400_CORE_OUTPUT = 0x8B83,
+ SH_GLSL_410_CORE_OUTPUT = 0x8B84,
+ SH_GLSL_420_CORE_OUTPUT = 0x8B85,
+ SH_GLSL_430_CORE_OUTPUT = 0x8B86,
+ SH_GLSL_440_CORE_OUTPUT = 0x8B87,
+ SH_GLSL_450_CORE_OUTPUT = 0x8B88,
+
+ // Prefer using these to specify HLSL output type:
+ SH_HLSL_3_0_OUTPUT = 0x8B48, // D3D 9
+ SH_HLSL_4_1_OUTPUT = 0x8B49, // D3D 11
+ SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A, // D3D 11 feature level 9_3
+
+ // Output SPIR-V for the Vulkan backend.
+ SH_SPIRV_VULKAN_OUTPUT = 0x8B4B,
+
+ // Output SPIR-V to be cross compiled to Metal.
+ SH_SPIRV_METAL_OUTPUT = 0x8B4C,
+
+ // Output for MSL
+ SH_MSL_METAL_OUTPUT = 0x8B4D,
+};
+
+// For ANGLE_shader_pixel_local_storage.
+// Instructs the compiler which pixel local storage configuration to generate code for.
+enum class ShPixelLocalStorageType
+{
+ NotSupported,
+ ImageStoreR32PackedFormats,
+ ImageStoreNativeFormats,
+ FramebufferFetch
+};
+
+// For ANGLE_shader_pixel_local_storage_coherent.
+// Instructs the compiler which fragment synchronization method to use, if any.
+enum class ShFragmentSynchronizationType
+{
+ NotSupported, // Fragments cannot be ordered or synchronized.
+
+ Automatic, // Fragments are automatically raster-ordered and synchronized.
+
+ FragmentShaderInterlock_NV_GL,
+ FragmentShaderOrdering_INTEL_GL,
+ FragmentShaderInterlock_ARB_GL, // Also compiles to SPV_EXT_fragment_shader_interlock.
+
+ RasterizerOrderViews_D3D,
+
+ RasterOrderGroups_Metal,
+
+ InvalidEnum,
+ EnumCount = InvalidEnum,
+};
+
+// Compile options.
+struct ShCompileOptionsMetal
+{
+ // Direct-to-metal backend constants:
+
+ // Binding index for driver uniforms:
+ int driverUniformsBindingIndex;
+ // Binding index for default uniforms:
+ int defaultUniformsBindingIndex;
+ // Binding index for UBO's argument buffer
+ int UBOArgumentBufferBindingIndex;
+};
+
+struct ShCompileOptionsPLS
+{
+ ShPixelLocalStorageType type = ShPixelLocalStorageType::NotSupported;
+ // For ANGLE_shader_pixel_local_storage_coherent.
+ ShFragmentSynchronizationType fragmentSynchronizationType =
+ ShFragmentSynchronizationType::NotSupported;
+};
+
+struct ShCompileOptions
+{
+ ShCompileOptions();
+ ShCompileOptions(const ShCompileOptions &other);
+ ShCompileOptions &operator=(const ShCompileOptions &other);
+
+ // Translates intermediate tree to glsl, hlsl, msl, or SPIR-V binary. Can be queried by
+ // calling sh::GetObjectCode().
+ uint64_t objectCode : 1;
+
+ // Extracts attributes, uniforms, and varyings. Can be queried by calling ShGetVariableInfo().
+ uint64_t variables : 1;
+
+ // Tracks the source path for shaders. Can be queried with getSourcePath().
+ uint64_t sourcePath : 1;
+
+ // Whether the internal representation of the AST should be output.
+ uint64_t intermediateTree : 1;
+
+ // If requested, validates the AST after every transformation. Useful for debugging.
+ uint64_t validateAST : 1;
+
+ // Validates loop and indexing in the shader to ensure that they do not exceed the minimum
+ // functionality mandated in GLSL 1.0 spec, Appendix A, Section 4 and 5. There is no need to
+ // specify this parameter when compiling for WebGL - it is implied.
+ uint64_t validateLoopIndexing : 1;
+
+ // Emits #line directives in HLSL.
+ uint64_t lineDirectives : 1;
+
+ // Due to spec difference between GLSL 4.1 or lower and ESSL3, some platforms (for example, Mac
+ // OSX core profile) require a variable's "invariant"/"centroid" qualifiers to match between
+ // vertex and fragment shader. A simple solution to allow such shaders to link is to omit the
+ // two qualifiers. AMD driver in Linux requires invariant qualifier to match between vertex and
+ // fragment shaders, while ESSL3 disallows invariant qualifier in fragment shader and GLSL >=
+ // 4.2 doesn't require invariant qualifier to match between shaders. Remove invariant qualifier
+ // from vertex shader to workaround AMD driver bug.
+ // Note that the two flags take effect on ESSL3 input shaders translated to GLSL 4.1 or lower
+ // and to GLSL 4.2 or newer on Linux AMD.
+ // TODO(zmo): This is not a good long-term solution. Simply dropping these qualifiers may break
+ // some developers' content. A more complex workaround of dynamically generating, compiling, and
+ // re-linking shaders that use these qualifiers should be implemented.
+ uint64_t removeInvariantAndCentroidForESSL3 : 1;
+
+ // This flag works around bug in Intel Mac drivers related to abs(i) where i is an integer.
+ uint64_t emulateAbsIntFunction : 1;
+
+ // Enforce the GLSL 1.017 Appendix A section 7 packing restrictions. This flag only enforces
+ // (and can only enforce) the packing restrictions for uniform variables in both vertex and
+ // fragment shaders. ShCheckVariablesWithinPackingLimits() lets embedders enforce the packing
+ // restrictions for varying variables during program link time.
+ uint64_t enforcePackingRestrictions : 1;
+
+ // This flag ensures all indirect (expression-based) array indexing is clamped to the bounds of
+ // the array. This ensures, for example, that you cannot read off the end of a uniform, whether
+ // an array vec234, or mat234 type.
+ uint64_t clampIndirectArrayBounds : 1;
+
+ // This flag limits the complexity of an expression.
+ uint64_t limitExpressionComplexity : 1;
+
+ // This flag limits the depth of the call stack.
+ uint64_t limitCallStackDepth : 1;
+
+ // This flag initializes gl_Position to vec4(0,0,0,0) at the beginning of the vertex shader's
+ // main(), and has no effect in the fragment shader. It is intended as a workaround for drivers
+ // which incorrectly fail to link programs if gl_Position is not written.
+ uint64_t initGLPosition : 1;
+
+ // This flag initializes gl_PointSize to 0.0f at the beginning of the vertex shader's
+ // main(), and has no effect in the fragment shader. It is intended to assist in working around
+ // bugs on some drivers when this is left written and then POINTS are drawn.
+ uint64_t initGLPointSize : 1;
+
+ // This flag replaces
+ // "a && b" with "a ? b : false",
+ // "a || b" with "a ? true : b".
+ // This is to work around a MacOSX driver bug that |b| is executed independent of |a|'s value.
+ uint64_t unfoldShortCircuit : 1;
+
+ // This flag initializes output variables to 0 at the beginning of main(). It is to avoid
+ // undefined behaviors.
+ uint64_t initOutputVariables : 1;
+
+ // This flag scalarizes vec/ivec/bvec/mat constructor args. It is intended as a workaround for
+ // Linux/Mac driver bugs.
+ uint64_t scalarizeVecAndMatConstructorArgs : 1;
+
+ // This flag overwrites a struct name with a unique prefix. It is intended as a workaround for
+ // drivers that do not handle struct scopes correctly, including all Mac drivers and Linux AMD.
+ uint64_t regenerateStructNames : 1;
+
+ // This flag works around bugs in Mac drivers related to do-while by transforming them into an
+ // other construct.
+ uint64_t rewriteDoWhileLoops : 1;
+
+ // This flag works around a bug in the HLSL compiler optimizer that folds certain constant pow
+ // expressions incorrectly. Only applies to the HLSL back-end. It works by expanding the integer
+ // pow expressions into a series of multiplies.
+ uint64_t expandSelectHLSLIntegerPowExpressions : 1;
+
+ // Flatten "#pragma STDGL invariant(all)" into the declarations of varying variables and
+ // built-in GLSL variables. This compiler option is enabled automatically when needed.
+ uint64_t flattenPragmaSTDGLInvariantAll : 1;
+
+ // Some drivers do not take into account the base level of the texture in the results of the
+ // HLSL GetDimensions builtin. This flag instructs the compiler to manually add the base level
+ // offsetting.
+ uint64_t HLSLGetDimensionsIgnoresBaseLevel : 1;
+
+ // This flag works around an issue in translating GLSL function texelFetchOffset on INTEL
+ // drivers. It works by translating texelFetchOffset into texelFetch.
+ uint64_t rewriteTexelFetchOffsetToTexelFetch : 1;
+
+ // This flag works around condition bug of for and while loops in Intel Mac OSX drivers.
+ // Condition calculation is not correct. Rewrite it from "CONDITION" to "CONDITION && true".
+ uint64_t addAndTrueToLoopCondition : 1;
+
+ // This flag works around a bug in evaluating unary minus operator on integer on some INTEL
+ // drivers. It works by translating -(int) into ~(int) + 1.
+ uint64_t rewriteIntegerUnaryMinusOperator : 1;
+
+ // This flag works around a bug in evaluating isnan() on some INTEL D3D and Mac OSX drivers. It
+ // works by using an expression to emulate this function.
+ uint64_t emulateIsnanFloatFunction : 1;
+
+ // This flag will use all uniforms of unused std140 and shared uniform blocks at the beginning
+ // of the vertex/fragment shader's main(). It is intended as a workaround for Mac drivers with
+ // shader version 4.10. In those drivers, they will treat unused std140 and shared uniform
+ // blocks' members as inactive. However, WebGL2.0 based on OpenGL ES3.0.4 requires all members
+ // of a named uniform block declared with a shared or std140 layout qualifier to be considered
+ // active. The uniform block itself is also considered active.
+ uint64_t useUnusedStandardSharedBlocks : 1;
+
+ // This flag works around a bug in unary minus operator on float numbers on Intel Mac OSX 10.11
+ // drivers. It works by translating -float into 0.0 - float.
+ uint64_t rewriteFloatUnaryMinusOperator : 1;
+
+ // This flag works around a bug in evaluating atan(y, x) on some NVIDIA OpenGL drivers. It
+ // works by using an expression to emulate this function.
+ uint64_t emulateAtan2FloatFunction : 1;
+
+ // Set to initialize uninitialized local and global temporary variables. Should only be used
+ // with GLSL output. In HLSL output variables are initialized regardless of if this flag is set.
+ uint64_t initializeUninitializedLocals : 1;
+
+ // The flag modifies the shader in the following way:
+ //
+ // Every occurrence of gl_InstanceID is replaced by the global temporary variable InstanceID.
+ // Every occurrence of gl_ViewID_OVR is replaced by the varying variable ViewID_OVR.
+ // At the beginning of the body of main() in a vertex shader the following initializers are
+ // added:
+ // ViewID_OVR = uint(gl_InstanceID) % num_views;
+ // InstanceID = gl_InstanceID / num_views;
+ // ViewID_OVR is added as a varying variable to both the vertex and fragment shaders.
+ uint64_t initializeBuiltinsForInstancedMultiview : 1;
+
+ // With the flag enabled the GLSL/ESSL vertex shader is modified to include code for viewport
+ // selection in the following way:
+ // - Code to enable the extension ARB_shader_viewport_layer_array/NV_viewport_array2 is
+ // included.
+ // - Code to select the viewport index or layer is inserted at the beginning of main after
+ // ViewID_OVR's initialization.
+ // - A declaration of the uniform multiviewBaseViewLayerIndex.
+ // Note: The initializeBuiltinsForInstancedMultiview flag also has to be enabled to have the
+ // temporary variable ViewID_OVR declared and initialized.
+ uint64_t selectViewInNvGLSLVertexShader : 1;
+
+ // If the flag is enabled, gl_PointSize is clamped to the maximum point size specified in
+ // ShBuiltInResources in vertex shaders.
+ uint64_t clampPointSize : 1;
+
+ // This flag indicates whether advanced blend equation should be emulated. Currently only
+ // implemented for the Vulkan backend.
+ uint64_t addAdvancedBlendEquationsEmulation : 1;
+
+ // Don't use loops to initialize uninitialized variables. Only has an effect if some kind of
+ // variable initialization is turned on.
+ uint64_t dontUseLoopsToInitializeVariables : 1;
+
+ // Don't use D3D constant register zero when allocating space for uniforms. This is targeted to
+ // work around a bug in NVIDIA D3D driver version 388.59 where in very specific cases the driver
+ // would not handle constant register zero correctly. Only has an effect on HLSL translation.
+ uint64_t skipD3DConstantRegisterZero : 1;
+
+ // Clamp gl_FragDepth to the range [0.0, 1.0] in case it is statically used.
+ uint64_t clampFragDepth : 1;
+
+ // Rewrite expressions like "v.x = z = expression;". Works around a bug in NVIDIA OpenGL drivers
+ // prior to version 397.31.
+ uint64_t rewriteRepeatedAssignToSwizzled : 1;
+
+ // Rewrite gl_DrawID as a uniform int
+ uint64_t emulateGLDrawID : 1;
+
+ // This flag initializes shared variables to 0. It is to avoid ompute shaders being able to
+ // read undefined values that could be coming from another webpage/application.
+ uint64_t initSharedVariables : 1;
+
+ // Forces the value returned from an atomic operations to be always be resolved. This is
+ // targeted to workaround a bug in NVIDIA D3D driver where the return value from
+ // RWByteAddressBuffer.InterlockedAdd does not get resolved when used in the .yzw components of
+ // a RWByteAddressBuffer.Store operation. Only has an effect on HLSL translation.
+ // http://anglebug.com/3246
+ uint64_t forceAtomicValueResolution : 1;
+
+ // Rewrite gl_BaseVertex and gl_BaseInstance as uniform int
+ uint64_t emulateGLBaseVertexBaseInstance : 1;
+
+ // Emulate seamful cube map sampling for OpenGL ES2.0. Currently only applies to the Vulkan
+ // backend, as is done after samplers are moved out of structs. Can likely be made to work on
+ // the other backends as well.
+ uint64_t emulateSeamfulCubeMapSampling : 1;
+
+ // This flag controls how to translate WEBGL_video_texture sampling function.
+ uint64_t takeVideoTextureAsExternalOES : 1;
+
+ // This flag works around a inconsistent behavior in Mac AMD driver where gl_VertexID doesn't
+ // include base vertex value. It replaces gl_VertexID with (gl_VertexID + angle_BaseVertex) when
+ // angle_BaseVertex is available.
+ uint64_t addBaseVertexToVertexID : 1;
+
+ // This works around the dynamic lvalue indexing of swizzled vectors on various platforms.
+ uint64_t removeDynamicIndexingOfSwizzledVector : 1;
+
+ // This flag works around a slow fxc compile performance issue with dynamic uniform indexing.
+ uint64_t allowTranslateUniformBlockToStructuredBuffer : 1;
+
+ // This flag allows us to add a decoration for layout(yuv) in shaders.
+ uint64_t addVulkanYUVLayoutQualifier : 1;
+
+ // This flag allows disabling ARB_texture_rectangle on a per-compile basis. This is necessary
+ // for WebGL contexts becuase ARB_texture_rectangle may be necessary for the WebGL
+ // implementation internally but shouldn't be exposed to WebGL user code.
+ uint64_t disableARBTextureRectangle : 1;
+
+ // This flag works around a driver bug by rewriting uses of row-major matrices as column-major
+ // in ESSL 3.00 and greater shaders.
+ uint64_t rewriteRowMajorMatrices : 1;
+
+ // Drop any explicit precision qualifiers from shader.
+ uint64_t ignorePrecisionQualifiers : 1;
+
+ // Ask compiler to generate code for depth correction to conform to the Vulkan clip space. If
+ // VK_EXT_depth_clip_control is supported, this code is not generated, saving a uniform look up.
+ uint64_t addVulkanDepthCorrection : 1;
+
+ uint64_t forceShaderPrecisionHighpToMediump : 1;
+
+ // Allow compiler to use specialization constant to do pre-rotation and y flip.
+ uint64_t useSpecializationConstant : 1;
+
+ // Ask compiler to generate Vulkan transform feedback emulation support code.
+ uint64_t addVulkanXfbEmulationSupportCode : 1;
+
+ // Ask compiler to generate Vulkan transform feedback support code when using the
+ // VK_EXT_transform_feedback extension.
+ uint64_t addVulkanXfbExtensionSupportCode : 1;
+
+ // This flag initializes fragment shader's output variables to zero at the beginning of the
+ // fragment shader's main(). It is intended as a workaround for drivers which get context lost
+ // if gl_FragColor is not written.
+ uint64_t initFragmentOutputVariables : 1;
+
+ // Transitory flag to select between producing SPIR-V directly vs using glslang. Ignored in
+ // non-assert-enabled builds to avoid increasing ANGLE's binary size.
+ uint64_t generateSpirvThroughGlslang : 1;
+
+ // Insert explicit casts for float/double/unsigned/signed int on macOS 10.15 with Intel driver
+ uint64_t addExplicitBoolCasts : 1;
+
+ // Add round() after applying dither. This works around a Qualcomm quirk where values can get
+ // ceil()ed instead.
+ uint64_t roundOutputAfterDithering : 1;
+
+ // Even when the dividend and divisor have the same value some platforms do not return 1.0f.
+ // Need to emit different division code for such platforms.
+ uint64_t precisionSafeDivision : 1;
+
+ // anglebug.com/7527: packUnorm4x8 fails on Pixel 4 if it is not passed a highp vec4.
+ // TODO(anglebug.com/7527): This workaround is currently only applied for pixel local storage.
+ // We may want to apply it generally.
+ uint64_t passHighpToPackUnormSnormBuiltins : 1;
+
+ ShCompileOptionsMetal metal;
+ ShCompileOptionsPLS pls;
+};
+
+// The 64 bits hash function. The first parameter is the input string; the
+// second parameter is the string length.
+using ShHashFunction64 = khronos_uint64_t (*)(const char *, size_t);
+
+//
+// Implementation dependent built-in resources (constants and extensions).
+// The names for these resources has been obtained by stripping gl_/GL_.
+//
+struct ShBuiltInResources
+{
+ ShBuiltInResources();
+ ShBuiltInResources(const ShBuiltInResources &other);
+ ShBuiltInResources &operator=(const ShBuiltInResources &other);
+
+ // Constants.
+ int MaxVertexAttribs;
+ int MaxVertexUniformVectors;
+ int MaxVaryingVectors;
+ int MaxVertexTextureImageUnits;
+ int MaxCombinedTextureImageUnits;
+ int MaxTextureImageUnits;
+ int MaxFragmentUniformVectors;
+ int MaxDrawBuffers;
+
+ // Extensions.
+ // Set to 1 to enable the extension, else 0.
+ int OES_standard_derivatives;
+ int OES_EGL_image_external;
+ int OES_EGL_image_external_essl3;
+ int NV_EGL_stream_consumer_external;
+ int ARB_texture_rectangle;
+ int EXT_blend_func_extended;
+ int EXT_draw_buffers;
+ int EXT_frag_depth;
+ int EXT_shader_texture_lod;
+ int EXT_shader_framebuffer_fetch;
+ int EXT_shader_framebuffer_fetch_non_coherent;
+ int NV_shader_framebuffer_fetch;
+ int NV_shader_noperspective_interpolation;
+ int ARM_shader_framebuffer_fetch;
+ int OVR_multiview;
+ int OVR_multiview2;
+ int EXT_multisampled_render_to_texture;
+ int EXT_multisampled_render_to_texture2;
+ int EXT_YUV_target;
+ int EXT_geometry_shader;
+ int OES_geometry_shader;
+ int OES_shader_io_blocks;
+ int EXT_shader_io_blocks;
+ int EXT_gpu_shader5;
+ int EXT_shader_non_constant_global_initializers;
+ int OES_texture_storage_multisample_2d_array;
+ int OES_texture_3D;
+ int ANGLE_shader_pixel_local_storage;
+ int ANGLE_texture_multisample;
+ int ANGLE_multi_draw;
+ // TODO(angleproject:3402) remove after chromium side removal to pass compilation
+ int ANGLE_base_vertex_base_instance;
+ int WEBGL_video_texture;
+ int APPLE_clip_distance;
+ int OES_texture_cube_map_array;
+ int EXT_texture_cube_map_array;
+ int EXT_shadow_samplers;
+ int OES_shader_multisample_interpolation;
+ int OES_shader_image_atomic;
+ int EXT_tessellation_shader;
+ int OES_texture_buffer;
+ int EXT_texture_buffer;
+ int OES_sample_variables;
+ int EXT_clip_cull_distance;
+ int EXT_primitive_bounding_box;
+ int OES_primitive_bounding_box;
+ int ANGLE_base_vertex_base_instance_shader_builtin;
+ int ANDROID_extension_pack_es31a;
+ int KHR_blend_equation_advanced;
+
+ // Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives
+ // with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate
+ // EXT_draw_buffers by using it in combination with GLES3.0 glDrawBuffers
+ // function. This applies to Tegra K1 devices.
+ int NV_draw_buffers;
+
+ // Set to 1 if highp precision is supported in the ESSL 1.00 version of the
+ // fragment language. Does not affect versions of the language where highp
+ // support is mandatory.
+ // Default is 0.
+ int FragmentPrecisionHigh;
+
+ // GLSL ES 3.0 constants.
+ int MaxVertexOutputVectors;
+ int MaxFragmentInputVectors;
+ int MinProgramTexelOffset;
+ int MaxProgramTexelOffset;
+
+ // Extension constants.
+
+ // Value of GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT for OpenGL ES output context.
+ // Value of GL_MAX_DUAL_SOURCE_DRAW_BUFFERS for OpenGL output context.
+ // GLES SL version 100 gl_MaxDualSourceDrawBuffersEXT value for EXT_blend_func_extended.
+ int MaxDualSourceDrawBuffers;
+
+ // Value of GL_MAX_VIEWS_OVR.
+ int MaxViewsOVR;
+
+ // Name Hashing.
+ // Set a 64 bit hash function to enable user-defined name hashing.
+ // Default is NULL.
+ ShHashFunction64 HashFunction;
+
+ // The maximum complexity an expression can be when limitExpressionComplexity is turned on.
+ int MaxExpressionComplexity;
+
+ // The maximum depth a call stack can be.
+ int MaxCallStackDepth;
+
+ // The maximum number of parameters a function can have when limitExpressionComplexity is turned
+ // on.
+ int MaxFunctionParameters;
+
+ // GLES 3.1 constants
+
+ // texture gather offset constraints.
+ int MinProgramTextureGatherOffset;
+ int MaxProgramTextureGatherOffset;
+
+ // maximum number of available image units
+ int MaxImageUnits;
+
+ // OES_sample_variables constant
+ // maximum number of available samples
+ int MaxSamples;
+
+ // maximum number of image uniforms in a vertex shader
+ int MaxVertexImageUniforms;
+
+ // maximum number of image uniforms in a fragment shader
+ int MaxFragmentImageUniforms;
+
+ // maximum number of image uniforms in a compute shader
+ int MaxComputeImageUniforms;
+
+ // maximum total number of image uniforms in a program
+ int MaxCombinedImageUniforms;
+
+ // maximum number of uniform locations
+ int MaxUniformLocations;
+
+ // maximum number of ssbos and images in a shader
+ int MaxCombinedShaderOutputResources;
+
+ // maximum number of groups in each dimension
+ std::array<int, 3> MaxComputeWorkGroupCount;
+ // maximum number of threads per work group in each dimension
+ std::array<int, 3> MaxComputeWorkGroupSize;
+
+ // maximum number of total uniform components
+ int MaxComputeUniformComponents;
+
+ // maximum number of texture image units in a compute shader
+ int MaxComputeTextureImageUnits;
+
+ // maximum number of atomic counters in a compute shader
+ int MaxComputeAtomicCounters;
+
+ // maximum number of atomic counter buffers in a compute shader
+ int MaxComputeAtomicCounterBuffers;
+
+ // maximum number of atomic counters in a vertex shader
+ int MaxVertexAtomicCounters;
+
+ // maximum number of atomic counters in a fragment shader
+ int MaxFragmentAtomicCounters;
+
+ // maximum number of atomic counters in a program
+ int MaxCombinedAtomicCounters;
+
+ // maximum binding for an atomic counter
+ int MaxAtomicCounterBindings;
+
+ // maximum number of atomic counter buffers in a vertex shader
+ int MaxVertexAtomicCounterBuffers;
+
+ // maximum number of atomic counter buffers in a fragment shader
+ int MaxFragmentAtomicCounterBuffers;
+
+ // maximum number of atomic counter buffers in a program
+ int MaxCombinedAtomicCounterBuffers;
+
+ // maximum number of buffer object storage in machine units
+ int MaxAtomicCounterBufferSize;
+
+ // maximum number of uniform block bindings
+ int MaxUniformBufferBindings;
+
+ // maximum number of shader storage buffer bindings
+ int MaxShaderStorageBufferBindings;
+
+ // maximum point size (higher limit from ALIASED_POINT_SIZE_RANGE)
+ float MaxPointSize;
+
+ // EXT_geometry_shader constants
+ int MaxGeometryUniformComponents;
+ int MaxGeometryUniformBlocks;
+ int MaxGeometryInputComponents;
+ int MaxGeometryOutputComponents;
+ int MaxGeometryOutputVertices;
+ int MaxGeometryTotalOutputComponents;
+ int MaxGeometryTextureImageUnits;
+ int MaxGeometryAtomicCounterBuffers;
+ int MaxGeometryAtomicCounters;
+ int MaxGeometryShaderStorageBlocks;
+ int MaxGeometryShaderInvocations;
+ int MaxGeometryImageUniforms;
+
+ // EXT_tessellation_shader constants
+ int MaxTessControlInputComponents;
+ int MaxTessControlOutputComponents;
+ int MaxTessControlTextureImageUnits;
+ int MaxTessControlUniformComponents;
+ int MaxTessControlTotalOutputComponents;
+ int MaxTessControlImageUniforms;
+ int MaxTessControlAtomicCounters;
+ int MaxTessControlAtomicCounterBuffers;
+
+ int MaxTessPatchComponents;
+ int MaxPatchVertices;
+ int MaxTessGenLevel;
+
+ int MaxTessEvaluationInputComponents;
+ int MaxTessEvaluationOutputComponents;
+ int MaxTessEvaluationTextureImageUnits;
+ int MaxTessEvaluationUniformComponents;
+ int MaxTessEvaluationImageUniforms;
+ int MaxTessEvaluationAtomicCounters;
+ int MaxTessEvaluationAtomicCounterBuffers;
+
+ // Subpixel bits used in rasterization.
+ int SubPixelBits;
+
+ // APPLE_clip_distance/EXT_clip_cull_distance constant
+ int MaxClipDistances;
+ int MaxCullDistances;
+ int MaxCombinedClipAndCullDistances;
+
+ // ANGLE_shader_pixel_local_storage.
+ int MaxPixelLocalStoragePlanes;
+ int MaxColorAttachmentsWithActivePixelLocalStorage;
+ int MaxCombinedDrawBuffersAndPixelLocalStoragePlanes;
+};
+
+//
+// ShHandle held by but opaque to the driver. It is allocated,
+// managed, and de-allocated by the compiler. Its contents
+// are defined by and used by the compiler.
+//
+// If handle creation fails, 0 will be returned.
+//
+using ShHandle = void *;
+
+namespace sh
+{
+using BinaryBlob = std::vector<uint32_t>;
+
+//
+// Driver must call this first, once, before doing any other compiler operations.
+// If the function succeeds, the return value is true, else false.
+//
+bool Initialize();
+//
+// Driver should call this at shutdown.
+// If the function succeeds, the return value is true, else false.
+//
+bool Finalize();
+
+//
+// Initialize built-in resources with minimum expected values.
+// Parameters:
+// resources: The object to initialize. Will be comparable with memcmp.
+//
+void InitBuiltInResources(ShBuiltInResources *resources);
+
+//
+// Returns a copy of the current ShBuiltInResources stored in the compiler.
+// Parameters:
+// handle: Specifies the handle of the compiler to be used.
+ShBuiltInResources GetBuiltInResources(const ShHandle handle);
+
+//
+// Returns the a concatenated list of the items in ShBuiltInResources as a null-terminated string.
+// This function must be updated whenever ShBuiltInResources is changed.
+// Parameters:
+// handle: Specifies the handle of the compiler to be used.
+const std::string &GetBuiltInResourcesString(const ShHandle handle);
+
+//
+// Driver calls these to create and destroy compiler objects.
+//
+// Returns the handle of constructed compiler, null if the requested compiler is not supported.
+// Parameters:
+// type: Specifies the type of shader - GL_FRAGMENT_SHADER or GL_VERTEX_SHADER.
+// spec: Specifies the language spec the compiler must conform to - SH_GLES2_SPEC or SH_WEBGL_SPEC.
+// output: Specifies the output code type - for example SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
+// SH_HLSL_3_0_OUTPUT or SH_HLSL_4_1_OUTPUT. Note: Each output type may only
+// be supported in some configurations.
+// resources: Specifies the built-in resources.
+ShHandle ConstructCompiler(sh::GLenum type,
+ ShShaderSpec spec,
+ ShShaderOutput output,
+ const ShBuiltInResources *resources);
+void Destruct(ShHandle handle);
+
+//
+// Compiles the given shader source.
+// If the function succeeds, the return value is true, else false.
+// Parameters:
+// handle: Specifies the handle of compiler to be used.
+// shaderStrings: Specifies an array of pointers to null-terminated strings containing the shader
+// source code.
+// numStrings: Specifies the number of elements in shaderStrings array.
+// compileOptions: A mask of compile options defined above.
+bool Compile(const ShHandle handle,
+ const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions);
+
+// Clears the results from the previous compilation.
+void ClearResults(const ShHandle handle);
+
+// Return the version of the shader language.
+int GetShaderVersion(const ShHandle handle);
+
+// Return the currently set language output type.
+ShShaderOutput GetShaderOutputType(const ShHandle handle);
+
+// Returns null-terminated information log for a compiled shader.
+// Parameters:
+// handle: Specifies the compiler
+const std::string &GetInfoLog(const ShHandle handle);
+
+// Returns null-terminated object code for a compiled shader. Only valid for output types that
+// generate human-readable code (GLSL, ESSL or HLSL).
+// Parameters:
+// handle: Specifies the compiler
+const std::string &GetObjectCode(const ShHandle handle);
+
+// Returns object binary blob for a compiled shader. Only valid for output types that
+// generate binary blob (SPIR-V).
+// Parameters:
+// handle: Specifies the compiler
+const BinaryBlob &GetObjectBinaryBlob(const ShHandle handle);
+
+// Returns a (original_name, hash) map containing all the user defined names in the shader,
+// including variable names, function names, struct names, and struct field names.
+// Parameters:
+// handle: Specifies the compiler
+const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle);
+
+// Shader variable inspection.
+// Returns a pointer to a list of variables of the designated type.
+// (See ShaderVars.h for type definitions, included above)
+// Returns NULL on failure.
+// Parameters:
+// handle: Specifies the compiler
+const std::vector<sh::ShaderVariable> *GetUniforms(const ShHandle handle);
+const std::vector<sh::ShaderVariable> *GetVaryings(const ShHandle handle);
+const std::vector<sh::ShaderVariable> *GetInputVaryings(const ShHandle handle);
+const std::vector<sh::ShaderVariable> *GetOutputVaryings(const ShHandle handle);
+const std::vector<sh::ShaderVariable> *GetAttributes(const ShHandle handle);
+const std::vector<sh::ShaderVariable> *GetOutputVariables(const ShHandle handle);
+const std::vector<sh::InterfaceBlock> *GetInterfaceBlocks(const ShHandle handle);
+const std::vector<sh::InterfaceBlock> *GetUniformBlocks(const ShHandle handle);
+const std::vector<sh::InterfaceBlock> *GetShaderStorageBlocks(const ShHandle handle);
+sh::WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle);
+// Returns the number of views specified through the num_views layout qualifier. If num_views is
+// not set, the function returns -1.
+int GetVertexShaderNumViews(const ShHandle handle);
+// Returns true if the shader has specified the |sample| qualifier, implying that per-sample shading
+// should be enabled
+bool EnablesPerSampleShading(const ShHandle handle);
+
+// Returns specialization constant usage bits
+uint32_t GetShaderSpecConstUsageBits(const ShHandle handle);
+
+// Returns true if the passed in variables pack in maxVectors followingthe packing rules from the
+// GLSL 1.017 spec, Appendix A, section 7.
+// Returns false otherwise. Also look at the enforcePackingRestrictions flag above.
+// Parameters:
+// maxVectors: the available rows of registers.
+// variables: an array of variables.
+bool CheckVariablesWithinPackingLimits(int maxVectors,
+ const std::vector<sh::ShaderVariable> &variables);
+
+// Gives the compiler-assigned register for a shader storage block.
+// The method writes the value to the output variable "indexOut".
+// Returns true if it found a valid shader storage block, false otherwise.
+// Parameters:
+// handle: Specifies the compiler
+// shaderStorageBlockName: Specifies the shader storage block
+// indexOut: output variable that stores the assigned register
+bool GetShaderStorageBlockRegister(const ShHandle handle,
+ const std::string &shaderStorageBlockName,
+ unsigned int *indexOut);
+
+// Gives the compiler-assigned register for a uniform block.
+// The method writes the value to the output variable "indexOut".
+// Returns true if it found a valid uniform block, false otherwise.
+// Parameters:
+// handle: Specifies the compiler
+// uniformBlockName: Specifies the uniform block
+// indexOut: output variable that stores the assigned register
+bool GetUniformBlockRegister(const ShHandle handle,
+ const std::string &uniformBlockName,
+ unsigned int *indexOut);
+
+bool ShouldUniformBlockUseStructuredBuffer(const ShHandle handle,
+ const std::string &uniformBlockName);
+const std::set<std::string> *GetSlowCompilingUniformBlockSet(const ShHandle handle);
+
+// Gives a map from uniform names to compiler-assigned registers in the default uniform block.
+// Note that the map contains also registers of samplers that have been extracted from structs.
+const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle);
+
+// Sampler, image and atomic counters share registers(t type and u type),
+// GetReadonlyImage2DRegisterIndex and GetImage2DRegisterIndex return the first index into
+// a range of reserved registers for image2D/iimage2D/uimage2D variables.
+// Parameters: handle: Specifies the compiler
+unsigned int GetReadonlyImage2DRegisterIndex(const ShHandle handle);
+unsigned int GetImage2DRegisterIndex(const ShHandle handle);
+
+// The method records these used function names related with image2D/iimage2D/uimage2D, these
+// functions will be dynamically generated.
+// Parameters:
+// handle: Specifies the compiler
+const std::set<std::string> *GetUsedImage2DFunctionNames(const ShHandle handle);
+
+bool HasDiscardInFragmentShader(const ShHandle handle);
+bool HasValidGeometryShaderInputPrimitiveType(const ShHandle handle);
+bool HasValidGeometryShaderOutputPrimitiveType(const ShHandle handle);
+bool HasValidGeometryShaderMaxVertices(const ShHandle handle);
+bool HasValidTessGenMode(const ShHandle handle);
+bool HasValidTessGenSpacing(const ShHandle handle);
+bool HasValidTessGenVertexOrder(const ShHandle handle);
+bool HasValidTessGenPointMode(const ShHandle handle);
+GLenum GetGeometryShaderInputPrimitiveType(const ShHandle handle);
+GLenum GetGeometryShaderOutputPrimitiveType(const ShHandle handle);
+int GetGeometryShaderInvocations(const ShHandle handle);
+int GetGeometryShaderMaxVertices(const ShHandle handle);
+unsigned int GetShaderSharedMemorySize(const ShHandle handle);
+int GetTessControlShaderVertices(const ShHandle handle);
+GLenum GetTessGenMode(const ShHandle handle);
+GLenum GetTessGenSpacing(const ShHandle handle);
+GLenum GetTessGenVertexOrder(const ShHandle handle);
+GLenum GetTessGenPointMode(const ShHandle handle);
+
+// Returns the blend equation list supported in the fragment shader. This is a bitset of
+// gl::BlendEquationType, and can only include bits from KHR_blend_equation_advanced.
+uint32_t GetAdvancedBlendEquations(const ShHandle handle);
+
+//
+// Helper function to identify specs that are based on the WebGL spec.
+//
+inline bool IsWebGLBasedSpec(ShShaderSpec spec)
+{
+ return (spec == SH_WEBGL_SPEC || spec == SH_WEBGL2_SPEC || spec == SH_WEBGL3_SPEC);
+}
+
+//
+// Helper function to identify DesktopGL specs
+//
+inline bool IsDesktopGLSpec(ShShaderSpec spec)
+{
+ return spec == SH_GL_CORE_SPEC || spec == SH_GL_COMPATIBILITY_SPEC;
+}
+
+// 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.
+extern const char kUserDefinedNamePrefix[];
+
+namespace vk
+{
+
+// Specialization constant ids
+enum class SpecializationConstantId : uint32_t
+{
+ SurfaceRotation = 0,
+ Dither = 1,
+
+ InvalidEnum = 2,
+ EnumCount = InvalidEnum,
+};
+
+enum class SpecConstUsage : uint32_t
+{
+ Rotation = 0,
+ Dither = 1,
+
+ InvalidEnum = 2,
+ EnumCount = InvalidEnum,
+};
+
+enum ColorAttachmentDitherControl
+{
+ // See comments in ContextVk::updateDither and EmulateDithering.cpp
+ kDitherControlNoDither = 0,
+ kDitherControlDither4444 = 1,
+ kDitherControlDither5551 = 2,
+ kDitherControlDither565 = 3,
+};
+
+// Interface block name containing the aggregate default uniforms
+extern const char kDefaultUniformsNameVS[];
+extern const char kDefaultUniformsNameTCS[];
+extern const char kDefaultUniformsNameTES[];
+extern const char kDefaultUniformsNameGS[];
+extern const char kDefaultUniformsNameFS[];
+extern const char kDefaultUniformsNameCS[];
+
+// Interface block and variable names containing driver uniforms
+extern const char kDriverUniformsBlockName[];
+extern const char kDriverUniformsVarName[];
+
+// Packing information for driver uniform's misc field:
+// - 1 bit for whether surface rotation results in swapped axes
+// - 5 bits for advanced blend equation
+// - 6 bits for sample count
+// - 8 bits for enabled clip planes
+// - 1 bit for whether depth should be transformed to Vulkan clip space
+// - 11 bits unused
+constexpr uint32_t kDriverUniformsMiscSwapXYMask = 0x1;
+constexpr uint32_t kDriverUniformsMiscAdvancedBlendEquationOffset = 1;
+constexpr uint32_t kDriverUniformsMiscAdvancedBlendEquationMask = 0x1F;
+constexpr uint32_t kDriverUniformsMiscSampleCountOffset = 6;
+constexpr uint32_t kDriverUniformsMiscSampleCountMask = 0x3F;
+constexpr uint32_t kDriverUniformsMiscEnabledClipPlanesOffset = 12;
+constexpr uint32_t kDriverUniformsMiscEnabledClipPlanesMask = 0xFF;
+constexpr uint32_t kDriverUniformsMiscTransformDepthOffset = 20;
+constexpr uint32_t kDriverUniformsMiscTransformDepthMask = 0x1;
+
+// Interface block array name used for atomic counter emulation
+extern const char kAtomicCountersBlockName[];
+
+// Transform feedback emulation support
+extern const char kXfbEmulationGetOffsetsFunctionName[];
+extern const char kXfbEmulationCaptureFunctionName[];
+extern const char kXfbEmulationBufferBlockName[];
+extern const char kXfbEmulationBufferName[];
+extern const char kXfbEmulationBufferFieldName[];
+
+// Transform feedback extension support
+extern const char kXfbExtensionPositionOutName[];
+
+// Pre-rotation support
+extern const char kTransformPositionFunctionName[];
+
+// EXT_shader_framebuffer_fetch and EXT_shader_framebuffer_fetch_non_coherent
+extern const char kInputAttachmentName[];
+
+} // namespace vk
+
+namespace mtl
+{
+// Specialization constant to enable GL_SAMPLE_COVERAGE_VALUE emulation.
+extern const char kCoverageMaskEnabledConstName[];
+
+// Specialization constant to emulate rasterizer discard.
+extern const char kRasterizerDiscardEnabledConstName[];
+
+// Specialization constant to enable depth write in fragment shaders.
+extern const char kDepthWriteEnabledConstName[];
+} // namespace mtl
+
+// For backends that use glslang (the Vulkan shader compiler), i.e. Vulkan and Metal, call these to
+// initialize and finalize glslang itself. This can be called independently from Initialize() and
+// Finalize().
+void InitializeGlslang();
+void FinalizeGlslang();
+
+} // namespace sh
+
+#endif // GLSLANG_SHADERLANG_H_
diff --git a/gfx/angle/checkout/include/GLSLANG/ShaderVars.h b/gfx/angle/checkout/include/GLSLANG/ShaderVars.h
new file mode 100644
index 0000000000..4b76d33af2
--- /dev/null
+++ b/gfx/angle/checkout/include/GLSLANG/ShaderVars.h
@@ -0,0 +1,331 @@
+//
+// 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.
+//
+// ShaderVars.h:
+// Types to represent GL variables (varyings, uniforms, etc)
+//
+
+#ifndef GLSLANG_SHADERVARS_H_
+#define GLSLANG_SHADERVARS_H_
+
+#include <algorithm>
+#include <array>
+#include <string>
+#include <vector>
+
+namespace sh
+{
+// GLenum alias
+typedef unsigned int GLenum;
+
+// Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec
+enum InterpolationType
+{
+ INTERPOLATION_SMOOTH,
+ INTERPOLATION_CENTROID,
+ INTERPOLATION_SAMPLE,
+ INTERPOLATION_FLAT,
+ INTERPOLATION_NOPERSPECTIVE
+};
+
+const char *InterpolationTypeToString(InterpolationType type);
+
+// Validate link & SSO consistency of interpolation qualifiers
+bool InterpolationTypesMatch(InterpolationType a, InterpolationType b);
+
+// Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec
+enum BlockLayoutType
+{
+ BLOCKLAYOUT_STANDARD,
+ BLOCKLAYOUT_STD140 = BLOCKLAYOUT_STANDARD,
+ BLOCKLAYOUT_STD430, // Shader storage block layout qualifier
+ BLOCKLAYOUT_PACKED,
+ BLOCKLAYOUT_SHARED
+};
+
+const char *BlockLayoutTypeToString(BlockLayoutType type);
+
+// Interface Blocks, see section 4.3.9 of the ESSL 3.10 spec
+enum class BlockType
+{
+ BLOCK_UNIFORM,
+ BLOCK_BUFFER,
+};
+
+const char *BlockTypeToString(BlockType type);
+
+// Base class for all variables defined in shaders, including Varyings, Uniforms, etc
+// Note: we must override the copy constructor and assignment operator so we can
+// work around excessive GCC binary bloating:
+// See https://code.google.com/p/angleproject/issues/detail?id=697
+struct ShaderVariable
+{
+ ShaderVariable();
+ ShaderVariable(GLenum typeIn);
+ ShaderVariable(GLenum typeIn, unsigned int arraySizeIn);
+ ~ShaderVariable();
+ ShaderVariable(const ShaderVariable &other);
+ ShaderVariable &operator=(const ShaderVariable &other);
+ bool operator==(const ShaderVariable &other) const;
+ bool operator!=(const ShaderVariable &other) const { return !operator==(other); }
+
+ bool isArrayOfArrays() const { return arraySizes.size() >= 2u; }
+ bool isArray() const { return !arraySizes.empty(); }
+ unsigned int getArraySizeProduct() const;
+ // Return the inner array size product.
+ // For example, if there's a variable declared as size 3 array of size 4 array of size 5 array
+ // of int:
+ // int a[3][4][5];
+ // then getInnerArraySizeProduct of a would be 4*5.
+ unsigned int getInnerArraySizeProduct() const;
+
+ // Array size 0 means not an array when passed to or returned from these functions.
+ // Note that setArraySize() is deprecated and should not be used inside ANGLE.
+ unsigned int getOutermostArraySize() const { return isArray() ? arraySizes.back() : 0; }
+ void setArraySize(unsigned int size);
+
+ // Turn this ShaderVariable from an array into a specific element in that array. Will update
+ // flattenedOffsetInParentArrays.
+ void indexIntoArray(unsigned int arrayIndex);
+
+ // Get the nth nested array size from the top. Caller is responsible for range checking
+ // arrayNestingIndex.
+ unsigned int getNestedArraySize(unsigned int arrayNestingIndex) const;
+
+ // This function should only be used with variables that are of a basic type or an array of a
+ // basic type. Shader interface variables that are enumerated according to rules in GLES 3.1
+ // spec section 7.3.1.1 page 77 are fine. For those variables the return value should match the
+ // ARRAY_SIZE value that can be queried through the API.
+ unsigned int getBasicTypeElementCount() const;
+
+ unsigned int getExternalSize() const;
+
+ bool isStruct() const { return !fields.empty(); }
+ const std::string &getStructName() const { return structOrBlockName; }
+ void setStructName(const std::string &newName) { structOrBlockName = newName; }
+
+ // All of the shader's variables are described using nested data
+ // structures. This is needed in order to disambiguate similar looking
+ // types, such as two structs containing the same fields, but in
+ // different orders. "findInfoByMappedName" provides an easy query for
+ // users to dive into the data structure and fetch the unique variable
+ // instance corresponding to a dereferencing chain of the top-level
+ // variable.
+ // Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable
+ // that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]'
+ // in |originalName|, based on the assumption that |this| defines 'a'.
+ // If no match is found, return false.
+ bool findInfoByMappedName(const std::string &mappedFullName,
+ const ShaderVariable **leafVar,
+ std::string *originalFullName) const;
+
+ // Find the child field which matches 'fullName' == var.name + "." + field.name.
+ // Return nullptr if not found.
+ const sh::ShaderVariable *findField(const std::string &fullName, uint32_t *fieldIndexOut) const;
+
+ bool isBuiltIn() const;
+ bool isEmulatedBuiltIn() const;
+
+ // Offset of this variable in parent arrays. In case the parent is an array of arrays, the
+ // offset is outerArrayElement * innerArraySize + innerArrayElement.
+ // For example, if there's a variable declared as size 3 array of size 4 array of int:
+ // int a[3][4];
+ // then the flattenedOffsetInParentArrays of a[2] would be 2.
+ // and flattenedOffsetInParentArrays of a[2][1] would be 2*4 + 1 = 9.
+ int parentArrayIndex() const
+ {
+ return hasParentArrayIndex() ? flattenedOffsetInParentArrays : 0;
+ }
+
+ int getFlattenedOffsetInParentArrays() const { return flattenedOffsetInParentArrays; }
+ void setParentArrayIndex(int indexIn) { flattenedOffsetInParentArrays = indexIn; }
+
+ bool hasParentArrayIndex() const { return flattenedOffsetInParentArrays != -1; }
+
+ void resetEffectiveLocation();
+ void updateEffectiveLocation(const sh::ShaderVariable &parent);
+
+ // Decide whether two uniforms are the same at shader link time,
+ // assuming they are from consecutive shader stages.
+ // GLSL ES Spec 3.00.3, section 4.3.5.
+ // GLSL ES Spec 3.10.4, section 4.4.5
+ bool isSameUniformAtLinkTime(const ShaderVariable &other) const;
+
+ // InterfaceBlockField
+ // Decide whether two InterfaceBlock fields are the same at shader
+ // link time, assuming they are from consecutive shader stages.
+ // See GLSL ES Spec 3.00.3, sec 4.3.7.
+ bool isSameInterfaceBlockFieldAtLinkTime(const ShaderVariable &other) const;
+
+ // Decide whether two varyings are the same at shader link time,
+ // assuming they are from consecutive shader stages.
+ // Invariance needs to match only in ESSL1. Relevant spec sections:
+ // GLSL ES 3.00.4, sections 4.6.1 and 4.3.9.
+ // GLSL ES 1.00.17, section 4.6.4.
+ bool isSameVaryingAtLinkTime(const ShaderVariable &other, int shaderVersion) const;
+ // Deprecated version of isSameVaryingAtLinkTime, which assumes ESSL1.
+ bool isSameVaryingAtLinkTime(const ShaderVariable &other) const;
+
+ // Shader I/O blocks may match by block name or instance, based on whether both stages have an
+ // instance name or not.
+ bool isSameNameAtLinkTime(const ShaderVariable &other) const;
+
+ // NOTE: When adding new members, the following functions also need to be updated:
+ // gl::WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
+ // gl::LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
+
+ GLenum type;
+ GLenum precision;
+ std::string name;
+ std::string mappedName;
+
+ // Used to make an array type. Outermost array size is stored at the end of the vector.
+ std::vector<unsigned int> arraySizes;
+
+ // Static use means that the variable is accessed somewhere in the shader source.
+ bool staticUse;
+ // A variable is active unless the compiler determined that it is not accessed by the shader.
+ // All active variables are statically used, but not all statically used variables are
+ // necessarily active. GLES 3.0.5 section 2.12.6. GLES 3.1 section 7.3.1.
+ bool active;
+ std::vector<ShaderVariable> fields;
+ // structOrBlockName is used for:
+ // - varyings of struct type, in which case it contains the struct name.
+ // - shader I/O blocks, in which case it contains the block name.
+ std::string structOrBlockName;
+ std::string mappedStructOrBlockName;
+
+ // Only applies to interface block fields. Kept here for simplicity.
+ bool isRowMajorLayout;
+
+ // VariableWithLocation
+ int location;
+
+ // The location of inputs or outputs without location layout quailifer will be updated to '-1'.
+ // GLES Spec 3.1, Section 7.3. PROGRAM OBJECTS
+ // Not all active variables are assigned valid locations;
+ // the following variables will have an effective location of -1:
+ bool hasImplicitLocation;
+
+ // Uniform
+ int binding;
+ GLenum imageUnitFormat;
+ int offset;
+ bool rasterOrdered;
+ bool readonly;
+ bool writeonly;
+
+ // From EXT_shader_framebuffer_fetch / KHR_blend_equation_advanced
+ bool isFragmentInOut;
+
+ // OutputVariable
+ // From EXT_blend_func_extended.
+ int index;
+
+ // From EXT_YUV_target
+ bool yuv;
+
+ // Varying
+ InterpolationType interpolation;
+ bool isInvariant;
+ bool isShaderIOBlock;
+ bool isPatch;
+
+ // If the variable is a sampler that has ever been statically used with texelFetch
+ bool texelFetchStaticUse;
+
+ protected:
+ bool isSameVariableAtLinkTime(const ShaderVariable &other,
+ bool matchPrecision,
+ bool matchName) const;
+
+ // NOTE: When adding new members, the following functions also need to be updated:
+ // gl::WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
+ // gl::LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
+
+ int flattenedOffsetInParentArrays;
+};
+
+// TODO: anglebug.com/3899
+// For backwards compatibility for other codebases (e.g., chromium/src/gpu/command_buffer/service)
+using Uniform = ShaderVariable;
+using Attribute = ShaderVariable;
+using OutputVariable = ShaderVariable;
+using InterfaceBlockField = ShaderVariable;
+using Varying = ShaderVariable;
+
+struct InterfaceBlock
+{
+ InterfaceBlock();
+ ~InterfaceBlock();
+ InterfaceBlock(const InterfaceBlock &other);
+ InterfaceBlock &operator=(const InterfaceBlock &other);
+
+ // Fields from blocks with non-empty instance names are prefixed with the block name.
+ std::string fieldPrefix() const;
+ std::string fieldMappedPrefix() const;
+
+ // Decide whether two interface blocks are the same at shader link time.
+ bool isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const;
+
+ bool isBuiltIn() const;
+
+ bool isArray() const { return arraySize > 0; }
+ unsigned int elementCount() const { return std::max(1u, arraySize); }
+
+ std::string name;
+ std::string mappedName;
+ std::string instanceName;
+ unsigned int arraySize;
+ BlockLayoutType layout;
+
+ // Deprecated. Matrix packing should only be queried from individual fields of the block.
+ // TODO(oetuaho): Remove this once it is no longer used in Chromium.
+ bool isRowMajorLayout;
+
+ int binding;
+ bool staticUse;
+ bool active;
+ BlockType blockType;
+ std::vector<ShaderVariable> fields;
+};
+
+struct WorkGroupSize
+{
+ // Must have a trivial default constructor since it is used in YYSTYPE.
+ inline WorkGroupSize() = default;
+ inline explicit constexpr WorkGroupSize(int initialSize);
+
+ void fill(int fillValue);
+ void setLocalSize(int localSizeX, int localSizeY, int localSizeZ);
+
+ int &operator[](size_t index);
+ int operator[](size_t index) const;
+ size_t size() const;
+
+ // Checks whether two work group size declarations match.
+ // Two work group size declarations are the same if the explicitly specified elements are the
+ // same or if one of them is specified as one and the other one is not specified
+ bool isWorkGroupSizeMatching(const WorkGroupSize &right) const;
+
+ // Checks whether any of the values are set.
+ bool isAnyValueSet() const;
+
+ // Checks whether all of the values are set.
+ bool isDeclared() const;
+
+ // Checks whether either all of the values are set, or none of them are.
+ bool isLocalSizeValid() const;
+
+ int localSizeQualifiers[3];
+};
+
+inline constexpr WorkGroupSize::WorkGroupSize(int initialSize)
+ : localSizeQualifiers{initialSize, initialSize, initialSize}
+{}
+
+} // namespace sh
+
+#endif // GLSLANG_SHADERVARS_H_
diff --git a/gfx/angle/checkout/include/GLX/glxext.h b/gfx/angle/checkout/include/GLX/glxext.h
new file mode 100644
index 0000000000..b918317fb9
--- /dev/null
+++ b/gfx/angle/checkout/include/GLX/glxext.h
@@ -0,0 +1,954 @@
+#ifndef __glx_glxext_h_
+#define __glx_glxext_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright 2013-2020 The Khronos Group Inc.
+** SPDX-License-Identifier: MIT
+**
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** https://github.com/KhronosGroup/OpenGL-Registry
+*/
+
+#define GLX_GLXEXT_VERSION 20220530
+
+/* Generated C header for:
+ * API: glx
+ * Versions considered: .*
+ * Versions emitted: 1\.[3-9]
+ * Default extensions included: glx
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef GLX_VERSION_1_3
+#define GLX_VERSION_1_3 1
+typedef XID GLXContextID;
+typedef struct __GLXFBConfigRec *GLXFBConfig;
+typedef XID GLXWindow;
+typedef XID GLXPbuffer;
+#define GLX_WINDOW_BIT 0x00000001
+#define GLX_PIXMAP_BIT 0x00000002
+#define GLX_PBUFFER_BIT 0x00000004
+#define GLX_RGBA_BIT 0x00000001
+#define GLX_COLOR_INDEX_BIT 0x00000002
+#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
+#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
+#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
+#define GLX_AUX_BUFFERS_BIT 0x00000010
+#define GLX_DEPTH_BUFFER_BIT 0x00000020
+#define GLX_STENCIL_BUFFER_BIT 0x00000040
+#define GLX_ACCUM_BUFFER_BIT 0x00000080
+#define GLX_CONFIG_CAVEAT 0x20
+#define GLX_X_VISUAL_TYPE 0x22
+#define GLX_TRANSPARENT_TYPE 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE 0x24
+#define GLX_TRANSPARENT_RED_VALUE 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
+#define GLX_DONT_CARE 0xFFFFFFFF
+#define GLX_NONE 0x8000
+#define GLX_SLOW_CONFIG 0x8001
+#define GLX_TRUE_COLOR 0x8002
+#define GLX_DIRECT_COLOR 0x8003
+#define GLX_PSEUDO_COLOR 0x8004
+#define GLX_STATIC_COLOR 0x8005
+#define GLX_GRAY_SCALE 0x8006
+#define GLX_STATIC_GRAY 0x8007
+#define GLX_TRANSPARENT_RGB 0x8008
+#define GLX_TRANSPARENT_INDEX 0x8009
+#define GLX_VISUAL_ID 0x800B
+#define GLX_SCREEN 0x800C
+#define GLX_NON_CONFORMANT_CONFIG 0x800D
+#define GLX_DRAWABLE_TYPE 0x8010
+#define GLX_RENDER_TYPE 0x8011
+#define GLX_X_RENDERABLE 0x8012
+#define GLX_FBCONFIG_ID 0x8013
+#define GLX_RGBA_TYPE 0x8014
+#define GLX_COLOR_INDEX_TYPE 0x8015
+#define GLX_MAX_PBUFFER_WIDTH 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT 0x8017
+#define GLX_MAX_PBUFFER_PIXELS 0x8018
+#define GLX_PRESERVED_CONTENTS 0x801B
+#define GLX_LARGEST_PBUFFER 0x801C
+#define GLX_WIDTH 0x801D
+#define GLX_HEIGHT 0x801E
+#define GLX_EVENT_MASK 0x801F
+#define GLX_DAMAGED 0x8020
+#define GLX_SAVED 0x8021
+#define GLX_WINDOW 0x8022
+#define GLX_PBUFFER 0x8023
+#define GLX_PBUFFER_HEIGHT 0x8040
+#define GLX_PBUFFER_WIDTH 0x8041
+typedef GLXFBConfig *( *PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements);
+typedef GLXFBConfig *( *PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
+typedef int ( *PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value);
+typedef XVisualInfo *( *PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
+typedef GLXWindow ( *PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
+typedef void ( *PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win);
+typedef GLXPixmap ( *PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
+typedef void ( *PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap);
+typedef GLXPbuffer ( *PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list);
+typedef void ( *PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf);
+typedef void ( *PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
+typedef GLXContext ( *PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+typedef Bool ( *PFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef GLXDrawable ( *PFNGLXGETCURRENTREADDRAWABLEPROC) (void);
+typedef int ( *PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value);
+typedef void ( *PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask);
+typedef void ( *PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
+#ifdef GLX_GLXEXT_PROTOTYPES
+GLXFBConfig *glXGetFBConfigs (Display *dpy, int screen, int *nelements);
+GLXFBConfig *glXChooseFBConfig (Display *dpy, int screen, const int *attrib_list, int *nelements);
+int glXGetFBConfigAttrib (Display *dpy, GLXFBConfig config, int attribute, int *value);
+XVisualInfo *glXGetVisualFromFBConfig (Display *dpy, GLXFBConfig config);
+GLXWindow glXCreateWindow (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
+void glXDestroyWindow (Display *dpy, GLXWindow win);
+GLXPixmap glXCreatePixmap (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
+void glXDestroyPixmap (Display *dpy, GLXPixmap pixmap);
+GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int *attrib_list);
+void glXDestroyPbuffer (Display *dpy, GLXPbuffer pbuf);
+void glXQueryDrawable (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
+GLXContext glXCreateNewContext (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+Bool glXMakeContextCurrent (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+GLXDrawable glXGetCurrentReadDrawable (void);
+int glXQueryContext (Display *dpy, GLXContext ctx, int attribute, int *value);
+void glXSelectEvent (Display *dpy, GLXDrawable draw, unsigned long event_mask);
+void glXGetSelectedEvent (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
+#endif
+#endif /* GLX_VERSION_1_3 */
+
+#ifndef GLX_VERSION_1_4
+#define GLX_VERSION_1_4 1
+typedef void ( *__GLXextFuncPtr)(void);
+#define GLX_SAMPLE_BUFFERS 100000
+#define GLX_SAMPLES 100001
+typedef __GLXextFuncPtr ( *PFNGLXGETPROCADDRESSPROC) (const GLubyte *procName);
+#ifdef GLX_GLXEXT_PROTOTYPES
+__GLXextFuncPtr glXGetProcAddress (const GLubyte *procName);
+#endif
+#endif /* GLX_VERSION_1_4 */
+
+#ifndef GLX_ARB_context_flush_control
+#define GLX_ARB_context_flush_control 1
+#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
+#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
+#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
+#endif /* GLX_ARB_context_flush_control */
+
+#ifndef GLX_ARB_create_context
+#define GLX_ARB_create_context 1
+#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define GLX_CONTEXT_FLAGS_ARB 0x2094
+typedef GLXContext ( *PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
+#ifdef GLX_GLXEXT_PROTOTYPES
+GLXContext glXCreateContextAttribsARB (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
+#endif
+#endif /* GLX_ARB_create_context */
+
+#ifndef GLX_ARB_create_context_no_error
+#define GLX_ARB_create_context_no_error 1
+#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3
+#endif /* GLX_ARB_create_context_no_error */
+
+#ifndef GLX_ARB_create_context_profile
+#define GLX_ARB_create_context_profile 1
+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
+#endif /* GLX_ARB_create_context_profile */
+
+#ifndef GLX_ARB_create_context_robustness
+#define GLX_ARB_create_context_robustness 1
+#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
+#endif /* GLX_ARB_create_context_robustness */
+
+#ifndef GLX_ARB_fbconfig_float
+#define GLX_ARB_fbconfig_float 1
+#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9
+#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004
+#endif /* GLX_ARB_fbconfig_float */
+
+#ifndef GLX_ARB_framebuffer_sRGB
+#define GLX_ARB_framebuffer_sRGB 1
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
+#endif /* GLX_ARB_framebuffer_sRGB */
+
+#ifndef GLX_ARB_get_proc_address
+#define GLX_ARB_get_proc_address 1
+typedef __GLXextFuncPtr ( *PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName);
+#ifdef GLX_GLXEXT_PROTOTYPES
+__GLXextFuncPtr glXGetProcAddressARB (const GLubyte *procName);
+#endif
+#endif /* GLX_ARB_get_proc_address */
+
+#ifndef GLX_ARB_multisample
+#define GLX_ARB_multisample 1
+#define GLX_SAMPLE_BUFFERS_ARB 100000
+#define GLX_SAMPLES_ARB 100001
+#endif /* GLX_ARB_multisample */
+
+#ifndef GLX_ARB_robustness_application_isolation
+#define GLX_ARB_robustness_application_isolation 1
+#define GLX_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+#endif /* GLX_ARB_robustness_application_isolation */
+
+#ifndef GLX_ARB_robustness_share_group_isolation
+#define GLX_ARB_robustness_share_group_isolation 1
+#endif /* GLX_ARB_robustness_share_group_isolation */
+
+#ifndef GLX_ARB_vertex_buffer_object
+#define GLX_ARB_vertex_buffer_object 1
+#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095
+#endif /* GLX_ARB_vertex_buffer_object */
+
+#ifndef GLX_3DFX_multisample
+#define GLX_3DFX_multisample 1
+#define GLX_SAMPLE_BUFFERS_3DFX 0x8050
+#define GLX_SAMPLES_3DFX 0x8051
+#endif /* GLX_3DFX_multisample */
+
+#ifndef GLX_AMD_gpu_association
+#define GLX_AMD_gpu_association 1
+#define GLX_GPU_VENDOR_AMD 0x1F00
+#define GLX_GPU_RENDERER_STRING_AMD 0x1F01
+#define GLX_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define GLX_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define GLX_GPU_RAM_AMD 0x21A3
+#define GLX_GPU_CLOCK_AMD 0x21A4
+#define GLX_GPU_NUM_PIPES_AMD 0x21A5
+#define GLX_GPU_NUM_SIMD_AMD 0x21A6
+#define GLX_GPU_NUM_RB_AMD 0x21A7
+#define GLX_GPU_NUM_SPI_AMD 0x21A8
+typedef unsigned int ( *PFNGLXGETGPUIDSAMDPROC) (unsigned int maxCount, unsigned int *ids);
+typedef int ( *PFNGLXGETGPUINFOAMDPROC) (unsigned int id, int property, GLenum dataType, unsigned int size, void *data);
+typedef unsigned int ( *PFNGLXGETCONTEXTGPUIDAMDPROC) (GLXContext ctx);
+typedef GLXContext ( *PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC) (unsigned int id, GLXContext share_list);
+typedef GLXContext ( *PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (unsigned int id, GLXContext share_context, const int *attribList);
+typedef Bool ( *PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC) (GLXContext ctx);
+typedef Bool ( *PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (GLXContext ctx);
+typedef GLXContext ( *PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
+typedef void ( *PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC) (GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#ifdef GLX_GLXEXT_PROTOTYPES
+unsigned int glXGetGPUIDsAMD (unsigned int maxCount, unsigned int *ids);
+int glXGetGPUInfoAMD (unsigned int id, int property, GLenum dataType, unsigned int size, void *data);
+unsigned int glXGetContextGPUIDAMD (GLXContext ctx);
+GLXContext glXCreateAssociatedContextAMD (unsigned int id, GLXContext share_list);
+GLXContext glXCreateAssociatedContextAttribsAMD (unsigned int id, GLXContext share_context, const int *attribList);
+Bool glXDeleteAssociatedContextAMD (GLXContext ctx);
+Bool glXMakeAssociatedContextCurrentAMD (GLXContext ctx);
+GLXContext glXGetCurrentAssociatedContextAMD (void);
+void glXBlitContextFramebufferAMD (GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+#endif /* GLX_AMD_gpu_association */
+
+#ifndef GLX_EXT_buffer_age
+#define GLX_EXT_buffer_age 1
+#define GLX_BACK_BUFFER_AGE_EXT 0x20F4
+#endif /* GLX_EXT_buffer_age */
+
+#ifndef GLX_EXT_context_priority
+#define GLX_EXT_context_priority 1
+#define GLX_CONTEXT_PRIORITY_LEVEL_EXT 0x3100
+#define GLX_CONTEXT_PRIORITY_HIGH_EXT 0x3101
+#define GLX_CONTEXT_PRIORITY_MEDIUM_EXT 0x3102
+#define GLX_CONTEXT_PRIORITY_LOW_EXT 0x3103
+#endif /* GLX_EXT_context_priority */
+
+#ifndef GLX_EXT_create_context_es2_profile
+#define GLX_EXT_create_context_es2_profile 1
+#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+#endif /* GLX_EXT_create_context_es2_profile */
+
+#ifndef GLX_EXT_create_context_es_profile
+#define GLX_EXT_create_context_es_profile 1
+#define GLX_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+#endif /* GLX_EXT_create_context_es_profile */
+
+#ifndef GLX_EXT_fbconfig_packed_float
+#define GLX_EXT_fbconfig_packed_float 1
+#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1
+#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008
+#endif /* GLX_EXT_fbconfig_packed_float */
+
+#ifndef GLX_EXT_framebuffer_sRGB
+#define GLX_EXT_framebuffer_sRGB 1
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2
+#endif /* GLX_EXT_framebuffer_sRGB */
+
+#ifndef GLX_EXT_get_drawable_type
+#define GLX_EXT_get_drawable_type 1
+#endif /* GLX_EXT_get_drawable_type */
+
+#ifndef GLX_EXT_import_context
+#define GLX_EXT_import_context 1
+#define GLX_SHARE_CONTEXT_EXT 0x800A
+#define GLX_VISUAL_ID_EXT 0x800B
+#define GLX_SCREEN_EXT 0x800C
+typedef Display *( *PFNGLXGETCURRENTDISPLAYEXTPROC) (void);
+typedef int ( *PFNGLXQUERYCONTEXTINFOEXTPROC) (Display *dpy, GLXContext context, int attribute, int *value);
+typedef GLXContextID ( *PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context);
+typedef GLXContext ( *PFNGLXIMPORTCONTEXTEXTPROC) (Display *dpy, GLXContextID contextID);
+typedef void ( *PFNGLXFREECONTEXTEXTPROC) (Display *dpy, GLXContext context);
+#ifdef GLX_GLXEXT_PROTOTYPES
+Display *glXGetCurrentDisplayEXT (void);
+int glXQueryContextInfoEXT (Display *dpy, GLXContext context, int attribute, int *value);
+GLXContextID glXGetContextIDEXT (const GLXContext context);
+GLXContext glXImportContextEXT (Display *dpy, GLXContextID contextID);
+void glXFreeContextEXT (Display *dpy, GLXContext context);
+#endif
+#endif /* GLX_EXT_import_context */
+
+#ifndef GLX_EXT_libglvnd
+#define GLX_EXT_libglvnd 1
+#define GLX_VENDOR_NAMES_EXT 0x20F6
+#endif /* GLX_EXT_libglvnd */
+
+#ifndef GLX_EXT_no_config_context
+#define GLX_EXT_no_config_context 1
+#endif /* GLX_EXT_no_config_context */
+
+#ifndef GLX_EXT_stereo_tree
+#define GLX_EXT_stereo_tree 1
+typedef struct {
+ int type;
+ unsigned long serial;
+ Bool send_event;
+ Display *display;
+ int extension;
+ int evtype;
+ GLXDrawable window;
+ Bool stereo_tree;
+} GLXStereoNotifyEventEXT;
+#define GLX_STEREO_TREE_EXT 0x20F5
+#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001
+#define GLX_STEREO_NOTIFY_EXT 0x00000000
+#endif /* GLX_EXT_stereo_tree */
+
+#ifndef GLX_EXT_swap_control
+#define GLX_EXT_swap_control 1
+#define GLX_SWAP_INTERVAL_EXT 0x20F1
+#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
+typedef void ( *PFNGLXSWAPINTERVALEXTPROC) (Display *dpy, GLXDrawable drawable, int interval);
+#ifdef GLX_GLXEXT_PROTOTYPES
+void glXSwapIntervalEXT (Display *dpy, GLXDrawable drawable, int interval);
+#endif
+#endif /* GLX_EXT_swap_control */
+
+#ifndef GLX_EXT_swap_control_tear
+#define GLX_EXT_swap_control_tear 1
+#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
+#endif /* GLX_EXT_swap_control_tear */
+
+#ifndef GLX_EXT_texture_from_pixmap
+#define GLX_EXT_texture_from_pixmap 1
+#define GLX_TEXTURE_1D_BIT_EXT 0x00000001
+#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
+#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
+#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
+#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
+#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
+#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
+#define GLX_Y_INVERTED_EXT 0x20D4
+#define GLX_TEXTURE_FORMAT_EXT 0x20D5
+#define GLX_TEXTURE_TARGET_EXT 0x20D6
+#define GLX_MIPMAP_TEXTURE_EXT 0x20D7
+#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
+#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
+#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
+#define GLX_TEXTURE_1D_EXT 0x20DB
+#define GLX_TEXTURE_2D_EXT 0x20DC
+#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD
+#define GLX_FRONT_LEFT_EXT 0x20DE
+#define GLX_FRONT_RIGHT_EXT 0x20DF
+#define GLX_BACK_LEFT_EXT 0x20E0
+#define GLX_BACK_RIGHT_EXT 0x20E1
+#define GLX_FRONT_EXT 0x20DE
+#define GLX_BACK_EXT 0x20E0
+#define GLX_AUX0_EXT 0x20E2
+#define GLX_AUX1_EXT 0x20E3
+#define GLX_AUX2_EXT 0x20E4
+#define GLX_AUX3_EXT 0x20E5
+#define GLX_AUX4_EXT 0x20E6
+#define GLX_AUX5_EXT 0x20E7
+#define GLX_AUX6_EXT 0x20E8
+#define GLX_AUX7_EXT 0x20E9
+#define GLX_AUX8_EXT 0x20EA
+#define GLX_AUX9_EXT 0x20EB
+typedef void ( *PFNGLXBINDTEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list);
+typedef void ( *PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer);
+#ifdef GLX_GLXEXT_PROTOTYPES
+void glXBindTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list);
+void glXReleaseTexImageEXT (Display *dpy, GLXDrawable drawable, int buffer);
+#endif
+#endif /* GLX_EXT_texture_from_pixmap */
+
+#ifndef GLX_EXT_visual_info
+#define GLX_EXT_visual_info 1
+#define GLX_X_VISUAL_TYPE_EXT 0x22
+#define GLX_TRANSPARENT_TYPE_EXT 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24
+#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28
+#define GLX_NONE_EXT 0x8000
+#define GLX_TRUE_COLOR_EXT 0x8002
+#define GLX_DIRECT_COLOR_EXT 0x8003
+#define GLX_PSEUDO_COLOR_EXT 0x8004
+#define GLX_STATIC_COLOR_EXT 0x8005
+#define GLX_GRAY_SCALE_EXT 0x8006
+#define GLX_STATIC_GRAY_EXT 0x8007
+#define GLX_TRANSPARENT_RGB_EXT 0x8008
+#define GLX_TRANSPARENT_INDEX_EXT 0x8009
+#endif /* GLX_EXT_visual_info */
+
+#ifndef GLX_EXT_visual_rating
+#define GLX_EXT_visual_rating 1
+#define GLX_VISUAL_CAVEAT_EXT 0x20
+#define GLX_SLOW_VISUAL_EXT 0x8001
+#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
+#endif /* GLX_EXT_visual_rating */
+
+#ifndef GLX_INTEL_swap_event
+#define GLX_INTEL_swap_event 1
+#define GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000
+#define GLX_EXCHANGE_COMPLETE_INTEL 0x8180
+#define GLX_COPY_COMPLETE_INTEL 0x8181
+#define GLX_FLIP_COMPLETE_INTEL 0x8182
+#endif /* GLX_INTEL_swap_event */
+
+#ifndef GLX_MESA_agp_offset
+#define GLX_MESA_agp_offset 1
+typedef unsigned int ( *PFNGLXGETAGPOFFSETMESAPROC) (const void *pointer);
+#ifdef GLX_GLXEXT_PROTOTYPES
+unsigned int glXGetAGPOffsetMESA (const void *pointer);
+#endif
+#endif /* GLX_MESA_agp_offset */
+
+#ifndef GLX_MESA_copy_sub_buffer
+#define GLX_MESA_copy_sub_buffer 1
+typedef void ( *PFNGLXCOPYSUBBUFFERMESAPROC) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
+#ifdef GLX_GLXEXT_PROTOTYPES
+void glXCopySubBufferMESA (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
+#endif
+#endif /* GLX_MESA_copy_sub_buffer */
+
+#ifndef GLX_MESA_pixmap_colormap
+#define GLX_MESA_pixmap_colormap 1
+typedef GLXPixmap ( *PFNGLXCREATEGLXPIXMAPMESAPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
+#ifdef GLX_GLXEXT_PROTOTYPES
+GLXPixmap glXCreateGLXPixmapMESA (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
+#endif
+#endif /* GLX_MESA_pixmap_colormap */
+
+#ifndef GLX_MESA_query_renderer
+#define GLX_MESA_query_renderer 1
+#define GLX_RENDERER_VENDOR_ID_MESA 0x8183
+#define GLX_RENDERER_DEVICE_ID_MESA 0x8184
+#define GLX_RENDERER_VERSION_MESA 0x8185
+#define GLX_RENDERER_ACCELERATED_MESA 0x8186
+#define GLX_RENDERER_VIDEO_MEMORY_MESA 0x8187
+#define GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA 0x8188
+#define GLX_RENDERER_PREFERRED_PROFILE_MESA 0x8189
+#define GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA 0x818A
+#define GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA 0x818B
+#define GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA 0x818C
+#define GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA 0x818D
+typedef Bool ( *PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) (int attribute, unsigned int *value);
+typedef const char *( *PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) (int attribute);
+typedef Bool ( *PFNGLXQUERYRENDERERINTEGERMESAPROC) (Display *dpy, int screen, int renderer, int attribute, unsigned int *value);
+typedef const char *( *PFNGLXQUERYRENDERERSTRINGMESAPROC) (Display *dpy, int screen, int renderer, int attribute);
+#ifdef GLX_GLXEXT_PROTOTYPES
+Bool glXQueryCurrentRendererIntegerMESA (int attribute, unsigned int *value);
+const char *glXQueryCurrentRendererStringMESA (int attribute);
+Bool glXQueryRendererIntegerMESA (Display *dpy, int screen, int renderer, int attribute, unsigned int *value);
+const char *glXQueryRendererStringMESA (Display *dpy, int screen, int renderer, int attribute);
+#endif
+#endif /* GLX_MESA_query_renderer */
+
+#ifndef GLX_MESA_release_buffers
+#define GLX_MESA_release_buffers 1
+typedef Bool ( *PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable);
+#ifdef GLX_GLXEXT_PROTOTYPES
+Bool glXReleaseBuffersMESA (Display *dpy, GLXDrawable drawable);
+#endif
+#endif /* GLX_MESA_release_buffers */
+
+#ifndef GLX_MESA_set_3dfx_mode
+#define GLX_MESA_set_3dfx_mode 1
+#define GLX_3DFX_WINDOW_MODE_MESA 0x1
+#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2
+typedef GLboolean ( *PFNGLXSET3DFXMODEMESAPROC) (GLint mode);
+#ifdef GLX_GLXEXT_PROTOTYPES
+GLboolean glXSet3DfxModeMESA (GLint mode);
+#endif
+#endif /* GLX_MESA_set_3dfx_mode */
+
+#ifndef GLX_MESA_swap_control
+#define GLX_MESA_swap_control 1
+typedef int ( *PFNGLXGETSWAPINTERVALMESAPROC) (void);
+typedef int ( *PFNGLXSWAPINTERVALMESAPROC) (unsigned int interval);
+#ifdef GLX_GLXEXT_PROTOTYPES
+int glXGetSwapIntervalMESA (void);
+int glXSwapIntervalMESA (unsigned int interval);
+#endif
+#endif /* GLX_MESA_swap_control */
+
+#ifndef GLX_NV_copy_buffer
+#define GLX_NV_copy_buffer 1
+typedef void ( *PFNGLXCOPYBUFFERSUBDATANVPROC) (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void ( *PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC) (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#ifdef GLX_GLXEXT_PROTOTYPES
+void glXCopyBufferSubDataNV (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+void glXNamedCopyBufferSubDataNV (Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#endif
+#endif /* GLX_NV_copy_buffer */
+
+#ifndef GLX_NV_copy_image
+#define GLX_NV_copy_image 1
+typedef void ( *PFNGLXCOPYIMAGESUBDATANVPROC) (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#ifdef GLX_GLXEXT_PROTOTYPES
+void glXCopyImageSubDataNV (Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+#endif /* GLX_NV_copy_image */
+
+#ifndef GLX_NV_delay_before_swap
+#define GLX_NV_delay_before_swap 1
+typedef Bool ( *PFNGLXDELAYBEFORESWAPNVPROC) (Display *dpy, GLXDrawable drawable, GLfloat seconds);
+#ifdef GLX_GLXEXT_PROTOTYPES
+Bool glXDelayBeforeSwapNV (Display *dpy, GLXDrawable drawable, GLfloat seconds);
+#endif
+#endif /* GLX_NV_delay_before_swap */
+
+#ifndef GLX_NV_float_buffer
+#define GLX_NV_float_buffer 1
+#define GLX_FLOAT_COMPONENTS_NV 0x20B0
+#endif /* GLX_NV_float_buffer */
+
+#ifndef GLX_NV_multigpu_context
+#define GLX_NV_multigpu_context 1
+#define GLX_CONTEXT_MULTIGPU_ATTRIB_NV 0x20AA
+#define GLX_CONTEXT_MULTIGPU_ATTRIB_SINGLE_NV 0x20AB
+#define GLX_CONTEXT_MULTIGPU_ATTRIB_AFR_NV 0x20AC
+#define GLX_CONTEXT_MULTIGPU_ATTRIB_MULTICAST_NV 0x20AD
+#define GLX_CONTEXT_MULTIGPU_ATTRIB_MULTI_DISPLAY_MULTICAST_NV 0x20AE
+#endif /* GLX_NV_multigpu_context */
+
+#ifndef GLX_NV_multisample_coverage
+#define GLX_NV_multisample_coverage 1
+#define GLX_COVERAGE_SAMPLES_NV 100001
+#define GLX_COLOR_SAMPLES_NV 0x20B3
+#endif /* GLX_NV_multisample_coverage */
+
+#ifndef GLX_NV_present_video
+#define GLX_NV_present_video 1
+#define GLX_NUM_VIDEO_SLOTS_NV 0x20F0
+typedef unsigned int *( *PFNGLXENUMERATEVIDEODEVICESNVPROC) (Display *dpy, int screen, int *nelements);
+typedef int ( *PFNGLXBINDVIDEODEVICENVPROC) (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list);
+#ifdef GLX_GLXEXT_PROTOTYPES
+unsigned int *glXEnumerateVideoDevicesNV (Display *dpy, int screen, int *nelements);
+int glXBindVideoDeviceNV (Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list);
+#endif
+#endif /* GLX_NV_present_video */
+
+#ifndef GLX_NV_robustness_video_memory_purge
+#define GLX_NV_robustness_video_memory_purge 1
+#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
+#endif /* GLX_NV_robustness_video_memory_purge */
+
+#ifndef GLX_NV_swap_group
+#define GLX_NV_swap_group 1
+typedef Bool ( *PFNGLXJOINSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint group);
+typedef Bool ( *PFNGLXBINDSWAPBARRIERNVPROC) (Display *dpy, GLuint group, GLuint barrier);
+typedef Bool ( *PFNGLXQUERYSWAPGROUPNVPROC) (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier);
+typedef Bool ( *PFNGLXQUERYMAXSWAPGROUPSNVPROC) (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers);
+typedef Bool ( *PFNGLXQUERYFRAMECOUNTNVPROC) (Display *dpy, int screen, GLuint *count);
+typedef Bool ( *PFNGLXRESETFRAMECOUNTNVPROC) (Display *dpy, int screen);
+#ifdef GLX_GLXEXT_PROTOTYPES
+Bool glXJoinSwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint group);
+Bool glXBindSwapBarrierNV (Display *dpy, GLuint group, GLuint barrier);
+Bool glXQuerySwapGroupNV (Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier);
+Bool glXQueryMaxSwapGroupsNV (Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers);
+Bool glXQueryFrameCountNV (Display *dpy, int screen, GLuint *count);
+Bool glXResetFrameCountNV (Display *dpy, int screen);
+#endif
+#endif /* GLX_NV_swap_group */
+
+#ifndef GLX_NV_video_capture
+#define GLX_NV_video_capture 1
+typedef XID GLXVideoCaptureDeviceNV;
+#define GLX_DEVICE_ID_NV 0x20CD
+#define GLX_UNIQUE_ID_NV 0x20CE
+#define GLX_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+typedef int ( *PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
+typedef GLXVideoCaptureDeviceNV *( *PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) (Display *dpy, int screen, int *nelements);
+typedef void ( *PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device);
+typedef int ( *PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value);
+typedef void ( *PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) (Display *dpy, GLXVideoCaptureDeviceNV device);
+#ifdef GLX_GLXEXT_PROTOTYPES
+int glXBindVideoCaptureDeviceNV (Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
+GLXVideoCaptureDeviceNV *glXEnumerateVideoCaptureDevicesNV (Display *dpy, int screen, int *nelements);
+void glXLockVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device);
+int glXQueryVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value);
+void glXReleaseVideoCaptureDeviceNV (Display *dpy, GLXVideoCaptureDeviceNV device);
+#endif
+#endif /* GLX_NV_video_capture */
+
+#ifndef GLX_NV_video_out
+#define GLX_NV_video_out 1
+typedef unsigned int GLXVideoDeviceNV;
+#define GLX_VIDEO_OUT_COLOR_NV 0x20C3
+#define GLX_VIDEO_OUT_ALPHA_NV 0x20C4
+#define GLX_VIDEO_OUT_DEPTH_NV 0x20C5
+#define GLX_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define GLX_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define GLX_VIDEO_OUT_FRAME_NV 0x20C8
+#define GLX_VIDEO_OUT_FIELD_1_NV 0x20C9
+#define GLX_VIDEO_OUT_FIELD_2_NV 0x20CA
+#define GLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV 0x20CB
+#define GLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV 0x20CC
+typedef int ( *PFNGLXGETVIDEODEVICENVPROC) (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice);
+typedef int ( *PFNGLXRELEASEVIDEODEVICENVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice);
+typedef int ( *PFNGLXBINDVIDEOIMAGENVPROC) (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
+typedef int ( *PFNGLXRELEASEVIDEOIMAGENVPROC) (Display *dpy, GLXPbuffer pbuf);
+typedef int ( *PFNGLXSENDPBUFFERTOVIDEONVPROC) (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock);
+typedef int ( *PFNGLXGETVIDEOINFONVPROC) (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#ifdef GLX_GLXEXT_PROTOTYPES
+int glXGetVideoDeviceNV (Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice);
+int glXReleaseVideoDeviceNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice);
+int glXBindVideoImageNV (Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
+int glXReleaseVideoImageNV (Display *dpy, GLXPbuffer pbuf);
+int glXSendPbufferToVideoNV (Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock);
+int glXGetVideoInfoNV (Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif
+#endif /* GLX_NV_video_out */
+
+#ifndef GLX_OML_swap_method
+#define GLX_OML_swap_method 1
+#define GLX_SWAP_METHOD_OML 0x8060
+#define GLX_SWAP_EXCHANGE_OML 0x8061
+#define GLX_SWAP_COPY_OML 0x8062
+#define GLX_SWAP_UNDEFINED_OML 0x8063
+#endif /* GLX_OML_swap_method */
+
+#ifndef GLX_OML_sync_control
+#define GLX_OML_sync_control 1
+#ifndef GLEXT_64_TYPES_DEFINED
+/* This code block is duplicated in glext.h, so must be protected */
+#define GLEXT_64_TYPES_DEFINED
+/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
+/* (as used in the GLX_OML_sync_control extension). */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+#elif defined(__sun__) || defined(__digital__)
+#include <inttypes.h>
+#if defined(__STDC__)
+#if defined(__arch64__) || defined(_LP64)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif /* __arch64__ */
+#endif /* __STDC__ */
+#elif defined( __VMS ) || defined(__sgi)
+#include <inttypes.h>
+#elif defined(__SCO__) || defined(__USLC__)
+#include <stdint.h>
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(_WIN32) && defined(__GNUC__)
+#include <stdint.h>
+#elif defined(_WIN32)
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+/* Fallback if nothing above works */
+#include <inttypes.h>
+#endif
+#endif
+typedef Bool ( *PFNGLXGETSYNCVALUESOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc);
+typedef Bool ( *PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator);
+typedef int64_t ( *PFNGLXSWAPBUFFERSMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
+typedef Bool ( *PFNGLXWAITFORMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
+typedef Bool ( *PFNGLXWAITFORSBCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc);
+#ifdef GLX_GLXEXT_PROTOTYPES
+Bool glXGetSyncValuesOML (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc);
+Bool glXGetMscRateOML (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator);
+int64_t glXSwapBuffersMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
+Bool glXWaitForMscOML (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
+Bool glXWaitForSbcOML (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc);
+#endif
+#endif /* GLX_OML_sync_control */
+
+#ifndef GLX_SGIS_blended_overlay
+#define GLX_SGIS_blended_overlay 1
+#define GLX_BLENDED_RGBA_SGIS 0x8025
+#endif /* GLX_SGIS_blended_overlay */
+
+#ifndef GLX_SGIS_multisample
+#define GLX_SGIS_multisample 1
+#define GLX_SAMPLE_BUFFERS_SGIS 100000
+#define GLX_SAMPLES_SGIS 100001
+#endif /* GLX_SGIS_multisample */
+
+#ifndef GLX_SGIS_shared_multisample
+#define GLX_SGIS_shared_multisample 1
+#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026
+#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027
+#endif /* GLX_SGIS_shared_multisample */
+
+#ifndef GLX_SGIX_dmbuffer
+#define GLX_SGIX_dmbuffer 1
+typedef XID GLXPbufferSGIX;
+#ifdef _DM_BUFFER_H_
+#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024
+typedef Bool ( *PFNGLXASSOCIATEDMPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer);
+#ifdef GLX_GLXEXT_PROTOTYPES
+Bool glXAssociateDMPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer);
+#endif
+#endif /* _DM_BUFFER_H_ */
+#endif /* GLX_SGIX_dmbuffer */
+
+#ifndef GLX_SGIX_fbconfig
+#define GLX_SGIX_fbconfig 1
+typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
+#define GLX_WINDOW_BIT_SGIX 0x00000001
+#define GLX_PIXMAP_BIT_SGIX 0x00000002
+#define GLX_RGBA_BIT_SGIX 0x00000001
+#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002
+#define GLX_DRAWABLE_TYPE_SGIX 0x8010
+#define GLX_RENDER_TYPE_SGIX 0x8011
+#define GLX_X_RENDERABLE_SGIX 0x8012
+#define GLX_FBCONFIG_ID_SGIX 0x8013
+#define GLX_RGBA_TYPE_SGIX 0x8014
+#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015
+typedef int ( *PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value);
+typedef GLXFBConfigSGIX *( *PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements);
+typedef GLXPixmap ( *PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap);
+typedef GLXContext ( *PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct);
+typedef XVisualInfo *( *PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config);
+typedef GLXFBConfigSGIX ( *PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display *dpy, XVisualInfo *vis);
+#ifdef GLX_GLXEXT_PROTOTYPES
+int glXGetFBConfigAttribSGIX (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value);
+GLXFBConfigSGIX *glXChooseFBConfigSGIX (Display *dpy, int screen, int *attrib_list, int *nelements);
+GLXPixmap glXCreateGLXPixmapWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap);
+GLXContext glXCreateContextWithConfigSGIX (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct);
+XVisualInfo *glXGetVisualFromFBConfigSGIX (Display *dpy, GLXFBConfigSGIX config);
+GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX (Display *dpy, XVisualInfo *vis);
+#endif
+#endif /* GLX_SGIX_fbconfig */
+
+#ifndef GLX_SGIX_hyperpipe
+#define GLX_SGIX_hyperpipe 1
+typedef struct {
+ char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ int networkId;
+} GLXHyperpipeNetworkSGIX;
+typedef struct {
+ char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ int channel;
+ unsigned int participationType;
+ int timeSlice;
+} GLXHyperpipeConfigSGIX;
+typedef struct {
+ char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ int srcXOrigin, srcYOrigin, srcWidth, srcHeight;
+ int destXOrigin, destYOrigin, destWidth, destHeight;
+} GLXPipeRect;
+typedef struct {
+ char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ int XOrigin, YOrigin, maxHeight, maxWidth;
+} GLXPipeRectLimits;
+#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80
+#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91
+#define GLX_BAD_HYPERPIPE_SGIX 92
+#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001
+#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002
+#define GLX_PIPE_RECT_SGIX 0x00000001
+#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002
+#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003
+#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004
+#define GLX_HYPERPIPE_ID_SGIX 0x8030
+typedef GLXHyperpipeNetworkSGIX *( *PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes);
+typedef int ( *PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId);
+typedef GLXHyperpipeConfigSGIX *( *PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes);
+typedef int ( *PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId);
+typedef int ( *PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId);
+typedef int ( *PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList);
+typedef int ( *PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList);
+typedef int ( *PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList);
+#ifdef GLX_GLXEXT_PROTOTYPES
+GLXHyperpipeNetworkSGIX *glXQueryHyperpipeNetworkSGIX (Display *dpy, int *npipes);
+int glXHyperpipeConfigSGIX (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId);
+GLXHyperpipeConfigSGIX *glXQueryHyperpipeConfigSGIX (Display *dpy, int hpId, int *npipes);
+int glXDestroyHyperpipeConfigSGIX (Display *dpy, int hpId);
+int glXBindHyperpipeSGIX (Display *dpy, int hpId);
+int glXQueryHyperpipeBestAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList);
+int glXHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *attribList);
+int glXQueryHyperpipeAttribSGIX (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList);
+#endif
+#endif /* GLX_SGIX_hyperpipe */
+
+#ifndef GLX_SGIX_pbuffer
+#define GLX_SGIX_pbuffer 1
+#define GLX_PBUFFER_BIT_SGIX 0x00000004
+#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000
+#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002
+#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008
+#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010
+#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020
+#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040
+#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080
+#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100
+#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017
+#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018
+#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019
+#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A
+#define GLX_PRESERVED_CONTENTS_SGIX 0x801B
+#define GLX_LARGEST_PBUFFER_SGIX 0x801C
+#define GLX_WIDTH_SGIX 0x801D
+#define GLX_HEIGHT_SGIX 0x801E
+#define GLX_EVENT_MASK_SGIX 0x801F
+#define GLX_DAMAGED_SGIX 0x8020
+#define GLX_SAVED_SGIX 0x8021
+#define GLX_WINDOW_SGIX 0x8022
+#define GLX_PBUFFER_SGIX 0x8023
+typedef GLXPbufferSGIX ( *PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
+typedef void ( *PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf);
+typedef void ( *PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value);
+typedef void ( *PFNGLXSELECTEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long mask);
+typedef void ( *PFNGLXGETSELECTEDEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long *mask);
+#ifdef GLX_GLXEXT_PROTOTYPES
+GLXPbufferSGIX glXCreateGLXPbufferSGIX (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
+void glXDestroyGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf);
+void glXQueryGLXPbufferSGIX (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value);
+void glXSelectEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long mask);
+void glXGetSelectedEventSGIX (Display *dpy, GLXDrawable drawable, unsigned long *mask);
+#endif
+#endif /* GLX_SGIX_pbuffer */
+
+#ifndef GLX_SGIX_swap_barrier
+#define GLX_SGIX_swap_barrier 1
+typedef void ( *PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier);
+typedef Bool ( *PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max);
+#ifdef GLX_GLXEXT_PROTOTYPES
+void glXBindSwapBarrierSGIX (Display *dpy, GLXDrawable drawable, int barrier);
+Bool glXQueryMaxSwapBarriersSGIX (Display *dpy, int screen, int *max);
+#endif
+#endif /* GLX_SGIX_swap_barrier */
+
+#ifndef GLX_SGIX_swap_group
+#define GLX_SGIX_swap_group 1
+typedef void ( *PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member);
+#ifdef GLX_GLXEXT_PROTOTYPES
+void glXJoinSwapGroupSGIX (Display *dpy, GLXDrawable drawable, GLXDrawable member);
+#endif
+#endif /* GLX_SGIX_swap_group */
+
+#ifndef GLX_SGIX_video_resize
+#define GLX_SGIX_video_resize 1
+#define GLX_SYNC_FRAME_SGIX 0x00000000
+#define GLX_SYNC_SWAP_SGIX 0x00000001
+typedef int ( *PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display *display, int screen, int channel, Window window);
+typedef int ( *PFNGLXCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int x, int y, int w, int h);
+typedef int ( *PFNGLXQUERYCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh);
+typedef int ( *PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display *display, int screen, int channel, int *x, int *y, int *w, int *h);
+typedef int ( *PFNGLXCHANNELRECTSYNCSGIXPROC) (Display *display, int screen, int channel, GLenum synctype);
+#ifdef GLX_GLXEXT_PROTOTYPES
+int glXBindChannelToWindowSGIX (Display *display, int screen, int channel, Window window);
+int glXChannelRectSGIX (Display *display, int screen, int channel, int x, int y, int w, int h);
+int glXQueryChannelRectSGIX (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh);
+int glXQueryChannelDeltasSGIX (Display *display, int screen, int channel, int *x, int *y, int *w, int *h);
+int glXChannelRectSyncSGIX (Display *display, int screen, int channel, GLenum synctype);
+#endif
+#endif /* GLX_SGIX_video_resize */
+
+#ifndef GLX_SGIX_video_source
+#define GLX_SGIX_video_source 1
+typedef XID GLXVideoSourceSGIX;
+#ifdef _VL_H
+typedef GLXVideoSourceSGIX ( *PFNGLXCREATEGLXVIDEOSOURCESGIXPROC) (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode);
+typedef void ( *PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC) (Display *dpy, GLXVideoSourceSGIX glxvideosource);
+#ifdef GLX_GLXEXT_PROTOTYPES
+GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode);
+void glXDestroyGLXVideoSourceSGIX (Display *dpy, GLXVideoSourceSGIX glxvideosource);
+#endif
+#endif /* _VL_H */
+#endif /* GLX_SGIX_video_source */
+
+#ifndef GLX_SGIX_visual_select_group
+#define GLX_SGIX_visual_select_group 1
+#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028
+#endif /* GLX_SGIX_visual_select_group */
+
+#ifndef GLX_SGI_cushion
+#define GLX_SGI_cushion 1
+typedef void ( *PFNGLXCUSHIONSGIPROC) (Display *dpy, Window window, float cushion);
+#ifdef GLX_GLXEXT_PROTOTYPES
+void glXCushionSGI (Display *dpy, Window window, float cushion);
+#endif
+#endif /* GLX_SGI_cushion */
+
+#ifndef GLX_SGI_make_current_read
+#define GLX_SGI_make_current_read 1
+typedef Bool ( *PFNGLXMAKECURRENTREADSGIPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef GLXDrawable ( *PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void);
+#ifdef GLX_GLXEXT_PROTOTYPES
+Bool glXMakeCurrentReadSGI (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+GLXDrawable glXGetCurrentReadDrawableSGI (void);
+#endif
+#endif /* GLX_SGI_make_current_read */
+
+#ifndef GLX_SGI_swap_control
+#define GLX_SGI_swap_control 1
+typedef int ( *PFNGLXSWAPINTERVALSGIPROC) (int interval);
+#ifdef GLX_GLXEXT_PROTOTYPES
+int glXSwapIntervalSGI (int interval);
+#endif
+#endif /* GLX_SGI_swap_control */
+
+#ifndef GLX_SGI_video_sync
+#define GLX_SGI_video_sync 1
+typedef int ( *PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int *count);
+typedef int ( *PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int *count);
+#ifdef GLX_GLXEXT_PROTOTYPES
+int glXGetVideoSyncSGI (unsigned int *count);
+int glXWaitVideoSyncSGI (int divisor, int remainder, unsigned int *count);
+#endif
+#endif /* GLX_SGI_video_sync */
+
+#ifndef GLX_SUN_get_transparent_index
+#define GLX_SUN_get_transparent_index 1
+typedef Status ( *PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display *dpy, Window overlay, Window underlay, unsigned long *pTransparentIndex);
+#ifdef GLX_GLXEXT_PROTOTYPES
+Status glXGetTransparentIndexSUN (Display *dpy, Window overlay, Window underlay, unsigned long *pTransparentIndex);
+#endif
+#endif /* GLX_SUN_get_transparent_index */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/include/KHR/khrplatform.h b/gfx/angle/checkout/include/KHR/khrplatform.h
new file mode 100644
index 0000000000..dd22d92701
--- /dev/null
+++ b/gfx/angle/checkout/include/KHR/khrplatform.h
@@ -0,0 +1,290 @@
+#ifndef __khrplatform_h_
+#define __khrplatform_h_
+
+/*
+** Copyright (c) 2008-2018 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Khronos platform-specific types and definitions.
+ *
+ * The master copy of khrplatform.h is maintained in the Khronos EGL
+ * Registry repository at https://github.com/KhronosGroup/EGL-Registry
+ * The last semantic modification to khrplatform.h was at commit ID:
+ * 67a3e0864c2d75ea5287b9f3d2eb74a745936692
+ *
+ * Adopters may modify this file to suit their platform. Adopters are
+ * encouraged to submit platform specific modifications to the Khronos
+ * group so that they can be included in future versions of this file.
+ * Please submit changes by filing pull requests or issues on
+ * the EGL Registry repository linked above.
+ *
+ *
+ * See the Implementer's Guidelines for information about where this file
+ * should be located on your system and for more details of its use:
+ * http://www.khronos.org/registry/implementers_guide.pdf
+ *
+ * This file should be included as
+ * #include <KHR/khrplatform.h>
+ * by Khronos client API header files that use its types and defines.
+ *
+ * The types in khrplatform.h should only be used to define API-specific types.
+ *
+ * Types defined in khrplatform.h:
+ * khronos_int8_t signed 8 bit
+ * khronos_uint8_t unsigned 8 bit
+ * khronos_int16_t signed 16 bit
+ * khronos_uint16_t unsigned 16 bit
+ * khronos_int32_t signed 32 bit
+ * khronos_uint32_t unsigned 32 bit
+ * khronos_int64_t signed 64 bit
+ * khronos_uint64_t unsigned 64 bit
+ * khronos_intptr_t signed same number of bits as a pointer
+ * khronos_uintptr_t unsigned same number of bits as a pointer
+ * khronos_ssize_t signed size
+ * khronos_usize_t unsigned size
+ * khronos_float_t signed 32 bit floating point
+ * khronos_time_ns_t unsigned 64 bit time in nanoseconds
+ * khronos_utime_nanoseconds_t unsigned time interval or absolute time in
+ * nanoseconds
+ * khronos_stime_nanoseconds_t signed time interval in nanoseconds
+ * khronos_boolean_enum_t enumerated boolean type. This should
+ * only be used as a base type when a client API's boolean type is
+ * an enum. Client APIs which use an integer or other type for
+ * booleans cannot use this as the base type for their boolean.
+ *
+ * Tokens defined in khrplatform.h:
+ *
+ * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
+ *
+ * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
+ * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
+ *
+ * Calling convention macros defined in this file:
+ * KHRONOS_APICALL
+ * KHRONOS_APIENTRY
+ * KHRONOS_APIATTRIBUTES
+ *
+ * These may be used in function prototypes as:
+ *
+ * KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
+ * int arg1,
+ * int arg2) KHRONOS_APIATTRIBUTES;
+ */
+
+#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
+# define KHRONOS_STATIC 1
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APICALL
+ *-------------------------------------------------------------------------
+ * This precedes the return type of the function in the function prototype.
+ */
+#if defined(KHRONOS_STATIC)
+ /* If the preprocessor constant KHRONOS_STATIC is defined, make the
+ * header compatible with static linking. */
+# define KHRONOS_APICALL
+#elif defined(_WIN32)
+# define KHRONOS_APICALL __declspec(dllimport)
+#elif defined (__SYMBIAN32__)
+# define KHRONOS_APICALL IMPORT_C
+#elif defined(__ANDROID__)
+# define KHRONOS_APICALL __attribute__((visibility("default")))
+#else
+# define KHRONOS_APICALL
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIENTRY
+ *-------------------------------------------------------------------------
+ * This follows the return type of the function and precedes the function
+ * name in the function prototype.
+ */
+#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
+ /* Win32 but not WinCE */
+# define KHRONOS_APIENTRY __stdcall
+#else
+# define KHRONOS_APIENTRY
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIATTRIBUTES
+ *-------------------------------------------------------------------------
+ * This follows the closing parenthesis of the function prototype arguments.
+ */
+#if defined (__ARMCC_2__)
+#define KHRONOS_APIATTRIBUTES __softfp
+#else
+#define KHRONOS_APIATTRIBUTES
+#endif
+
+/*-------------------------------------------------------------------------
+ * basic type definitions
+ *-----------------------------------------------------------------------*/
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
+
+
+/*
+ * Using <stdint.h>
+ */
+#include <stdint.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__VMS ) || defined(__sgi)
+
+/*
+ * Using <inttypes.h>
+ */
+#include <inttypes.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
+
+/*
+ * Win32
+ */
+typedef __int32 khronos_int32_t;
+typedef unsigned __int32 khronos_uint32_t;
+typedef __int64 khronos_int64_t;
+typedef unsigned __int64 khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif defined(__sun__) || defined(__digital__)
+
+/*
+ * Sun or Digital
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#if defined(__arch64__) || defined(_LP64)
+typedef long int khronos_int64_t;
+typedef unsigned long int khronos_uint64_t;
+#else
+typedef long long int khronos_int64_t;
+typedef unsigned long long int khronos_uint64_t;
+#endif /* __arch64__ */
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#elif 0
+
+/*
+ * Hypothetical platform with no float or int64 support
+ */
+typedef int khronos_int32_t;
+typedef unsigned int khronos_uint32_t;
+#define KHRONOS_SUPPORT_INT64 0
+#define KHRONOS_SUPPORT_FLOAT 0
+
+#else
+
+/*
+ * Generic fallback
+ */
+#include <stdint.h>
+typedef int32_t khronos_int32_t;
+typedef uint32_t khronos_uint32_t;
+typedef int64_t khronos_int64_t;
+typedef uint64_t khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64 1
+#define KHRONOS_SUPPORT_FLOAT 1
+
+#endif
+
+
+/*
+ * Types that are (so far) the same on all platforms
+ */
+typedef signed char khronos_int8_t;
+typedef unsigned char khronos_uint8_t;
+typedef signed short int khronos_int16_t;
+typedef unsigned short int khronos_uint16_t;
+
+/*
+ * Types that differ between LLP64 and LP64 architectures - in LLP64,
+ * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
+ * to be the only LLP64 architecture in current use.
+ */
+#ifdef _WIN64
+typedef signed long long int khronos_intptr_t;
+typedef unsigned long long int khronos_uintptr_t;
+typedef signed long long int khronos_ssize_t;
+typedef unsigned long long int khronos_usize_t;
+#else
+typedef signed long int khronos_intptr_t;
+typedef unsigned long int khronos_uintptr_t;
+typedef signed long int khronos_ssize_t;
+typedef unsigned long int khronos_usize_t;
+#endif
+
+#if KHRONOS_SUPPORT_FLOAT
+/*
+ * Float type
+ */
+typedef float khronos_float_t;
+#endif
+
+#if KHRONOS_SUPPORT_INT64
+/* Time types
+ *
+ * These types can be used to represent a time interval in nanoseconds or
+ * an absolute Unadjusted System Time. Unadjusted System Time is the number
+ * of nanoseconds since some arbitrary system event (e.g. since the last
+ * time the system booted). The Unadjusted System Time is an unsigned
+ * 64 bit value that wraps back to 0 every 584 years. Time intervals
+ * may be either signed or unsigned.
+ */
+typedef khronos_uint64_t khronos_utime_nanoseconds_t;
+typedef khronos_int64_t khronos_stime_nanoseconds_t;
+#endif
+
+/*
+ * Dummy value used to pad enum types to 32 bits.
+ */
+#ifndef KHRONOS_MAX_ENUM
+#define KHRONOS_MAX_ENUM 0x7FFFFFFF
+#endif
+
+/*
+ * Enumerated boolean type
+ *
+ * Values other than zero should be considered to be true. Therefore
+ * comparisons should not be made against KHRONOS_TRUE.
+ */
+typedef enum {
+ KHRONOS_FALSE = 0,
+ KHRONOS_TRUE = 1,
+ KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
+} khronos_boolean_enum_t;
+
+#endif /* __khrplatform_h_ */
diff --git a/gfx/angle/checkout/include/WGL/wgl.h b/gfx/angle/checkout/include/WGL/wgl.h
new file mode 100644
index 0000000000..0bae52bdda
--- /dev/null
+++ b/gfx/angle/checkout/include/WGL/wgl.h
@@ -0,0 +1,946 @@
+#ifndef __wgl_wgl_h_
+#define __wgl_wgl_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2013-2018 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+/*
+** This header is generated from the Khronos OpenGL / OpenGL ES XML
+** API Registry. The current version of the Registry, generator scripts
+** used to make the header, and the header can be found at
+** https://github.com/KhronosGroup/OpenGL-Registry
+*/
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+/* Generated on date 20181206 */
+
+/* Generated C header for:
+ * API: wgl
+ * Versions considered: .*
+ * Versions emitted: .*
+ * Default extensions included: wgl
+ * Additional extensions included: _nomatch_^
+ * Extensions removed: _nomatch_^
+ */
+
+#ifndef WGL_VERSION_1_0
+#define WGL_VERSION_1_0 1
+#define WGL_FONT_LINES 0
+#define WGL_FONT_POLYGONS 1
+#define WGL_SWAP_MAIN_PLANE 0x00000001
+#define WGL_SWAP_OVERLAY1 0x00000002
+#define WGL_SWAP_OVERLAY2 0x00000004
+#define WGL_SWAP_OVERLAY3 0x00000008
+#define WGL_SWAP_OVERLAY4 0x00000010
+#define WGL_SWAP_OVERLAY5 0x00000020
+#define WGL_SWAP_OVERLAY6 0x00000040
+#define WGL_SWAP_OVERLAY7 0x00000080
+#define WGL_SWAP_OVERLAY8 0x00000100
+#define WGL_SWAP_OVERLAY9 0x00000200
+#define WGL_SWAP_OVERLAY10 0x00000400
+#define WGL_SWAP_OVERLAY11 0x00000800
+#define WGL_SWAP_OVERLAY12 0x00001000
+#define WGL_SWAP_OVERLAY13 0x00002000
+#define WGL_SWAP_OVERLAY14 0x00004000
+#define WGL_SWAP_OVERLAY15 0x00008000
+#define WGL_SWAP_UNDERLAY1 0x00010000
+#define WGL_SWAP_UNDERLAY2 0x00020000
+#define WGL_SWAP_UNDERLAY3 0x00040000
+#define WGL_SWAP_UNDERLAY4 0x00080000
+#define WGL_SWAP_UNDERLAY5 0x00100000
+#define WGL_SWAP_UNDERLAY6 0x00200000
+#define WGL_SWAP_UNDERLAY7 0x00400000
+#define WGL_SWAP_UNDERLAY8 0x00800000
+#define WGL_SWAP_UNDERLAY9 0x01000000
+#define WGL_SWAP_UNDERLAY10 0x02000000
+#define WGL_SWAP_UNDERLAY11 0x04000000
+#define WGL_SWAP_UNDERLAY12 0x08000000
+#define WGL_SWAP_UNDERLAY13 0x10000000
+#define WGL_SWAP_UNDERLAY14 0x20000000
+#define WGL_SWAP_UNDERLAY15 0x40000000
+typedef int (WINAPI * PFNCHOOSEPIXELFORMATPROC) (HDC hDc, const PIXELFORMATDESCRIPTOR *pPfd);
+typedef int (WINAPI * PFNDESCRIBEPIXELFORMATPROC) (HDC hdc, int ipfd, UINT cjpfd, const PIXELFORMATDESCRIPTOR *ppfd);
+typedef UINT (WINAPI * PFNGETENHMETAFILEPIXELFORMATPROC) (HENHMETAFILE hemf, const PIXELFORMATDESCRIPTOR *ppfd);
+typedef int (WINAPI * PFNGETPIXELFORMATPROC) (HDC hdc);
+typedef BOOL (WINAPI * PFNSETPIXELFORMATPROC) (HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *ppfd);
+typedef BOOL (WINAPI * PFNSWAPBUFFERSPROC) (HDC hdc);
+typedef BOOL (WINAPI * PFNWGLCOPYCONTEXTPROC) (HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask);
+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTPROC) (HDC hDc);
+typedef HGLRC (WINAPI * PFNWGLCREATELAYERCONTEXTPROC) (HDC hDc, int level);
+typedef BOOL (WINAPI * PFNWGLDELETECONTEXTPROC) (HGLRC oldContext);
+typedef BOOL (WINAPI * PFNWGLDESCRIBELAYERPLANEPROC) (HDC hDc, int pixelFormat, int layerPlane, UINT nBytes, const LAYERPLANEDESCRIPTOR *plpd);
+typedef HGLRC (WINAPI * PFNWGLGETCURRENTCONTEXTPROC) (void);
+typedef HDC (WINAPI * PFNWGLGETCURRENTDCPROC) (void);
+typedef int (WINAPI * PFNWGLGETLAYERPALETTEENTRIESPROC) (HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr);
+typedef PROC (WINAPI * PFNWGLGETPROCADDRESSPROC) (LPCSTR lpszProc);
+typedef BOOL (WINAPI * PFNWGLMAKECURRENTPROC) (HDC hDc, HGLRC newContext);
+typedef BOOL (WINAPI * PFNWGLREALIZELAYERPALETTEPROC) (HDC hdc, int iLayerPlane, BOOL bRealize);
+typedef int (WINAPI * PFNWGLSETLAYERPALETTEENTRIESPROC) (HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr);
+typedef BOOL (WINAPI * PFNWGLSHARELISTSPROC) (HGLRC hrcSrvShare, HGLRC hrcSrvSource);
+typedef BOOL (WINAPI * PFNWGLSWAPLAYERBUFFERSPROC) (HDC hdc, UINT fuFlags);
+typedef BOOL (WINAPI * PFNWGLUSEFONTBITMAPSPROC) (HDC hDC, DWORD first, DWORD count, DWORD listBase);
+typedef BOOL (WINAPI * PFNWGLUSEFONTBITMAPSAPROC) (HDC hDC, DWORD first, DWORD count, DWORD listBase);
+typedef BOOL (WINAPI * PFNWGLUSEFONTBITMAPSWPROC) (HDC hDC, DWORD first, DWORD count, DWORD listBase);
+typedef BOOL (WINAPI * PFNWGLUSEFONTOUTLINESPROC) (HDC hDC, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf);
+typedef BOOL (WINAPI * PFNWGLUSEFONTOUTLINESAPROC) (HDC hDC, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf);
+typedef BOOL (WINAPI * PFNWGLUSEFONTOUTLINESWPROC) (HDC hDC, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf);
+#ifdef WGL_WGLEXT_PROTOTYPES
+int WINAPI ChoosePixelFormat (HDC hDc, const PIXELFORMATDESCRIPTOR *pPfd);
+int WINAPI DescribePixelFormat (HDC hdc, int ipfd, UINT cjpfd, const PIXELFORMATDESCRIPTOR *ppfd);
+UINT WINAPI GetEnhMetaFilePixelFormat (HENHMETAFILE hemf, const PIXELFORMATDESCRIPTOR *ppfd);
+int WINAPI GetPixelFormat (HDC hdc);
+BOOL WINAPI SetPixelFormat (HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *ppfd);
+BOOL WINAPI SwapBuffers (HDC hdc);
+BOOL WINAPI wglCopyContext (HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask);
+HGLRC WINAPI wglCreateContext (HDC hDc);
+HGLRC WINAPI wglCreateLayerContext (HDC hDc, int level);
+BOOL WINAPI wglDeleteContext (HGLRC oldContext);
+BOOL WINAPI wglDescribeLayerPlane (HDC hDc, int pixelFormat, int layerPlane, UINT nBytes, const LAYERPLANEDESCRIPTOR *plpd);
+HGLRC WINAPI wglGetCurrentContext (void);
+HDC WINAPI wglGetCurrentDC (void);
+int WINAPI wglGetLayerPaletteEntries (HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr);
+PROC WINAPI wglGetProcAddress (LPCSTR lpszProc);
+BOOL WINAPI wglMakeCurrent (HDC hDc, HGLRC newContext);
+BOOL WINAPI wglRealizeLayerPalette (HDC hdc, int iLayerPlane, BOOL bRealize);
+int WINAPI wglSetLayerPaletteEntries (HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr);
+BOOL WINAPI wglShareLists (HGLRC hrcSrvShare, HGLRC hrcSrvSource);
+BOOL WINAPI wglSwapLayerBuffers (HDC hdc, UINT fuFlags);
+BOOL WINAPI wglUseFontBitmaps (HDC hDC, DWORD first, DWORD count, DWORD listBase);
+BOOL WINAPI wglUseFontBitmapsA (HDC hDC, DWORD first, DWORD count, DWORD listBase);
+BOOL WINAPI wglUseFontBitmapsW (HDC hDC, DWORD first, DWORD count, DWORD listBase);
+BOOL WINAPI wglUseFontOutlines (HDC hDC, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf);
+BOOL WINAPI wglUseFontOutlinesA (HDC hDC, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf);
+BOOL WINAPI wglUseFontOutlinesW (HDC hDC, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf);
+#endif
+#endif /* WGL_VERSION_1_0 */
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_ARB_buffer_region 1
+#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
+#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
+#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
+#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
+typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
+typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
+typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
+typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+#ifdef WGL_WGLEXT_PROTOTYPES
+HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType);
+VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion);
+BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height);
+BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+#endif
+#endif /* WGL_ARB_buffer_region */
+
+#ifndef WGL_ARB_context_flush_control
+#define WGL_ARB_context_flush_control 1
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
+#endif /* WGL_ARB_context_flush_control */
+
+#ifndef WGL_ARB_create_context
+#define WGL_ARB_create_context 1
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define ERROR_INVALID_VERSION_ARB 0x2095
+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
+#ifdef WGL_WGLEXT_PROTOTYPES
+HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList);
+#endif
+#endif /* WGL_ARB_create_context */
+
+#ifndef WGL_ARB_create_context_no_error
+#define WGL_ARB_create_context_no_error 1
+#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3
+#endif /* WGL_ARB_create_context_no_error */
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_ARB_create_context_profile 1
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define ERROR_INVALID_PROFILE_ARB 0x2096
+#endif /* WGL_ARB_create_context_profile */
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_ARB_create_context_robustness 1
+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
+#endif /* WGL_ARB_create_context_robustness */
+
+#ifndef WGL_ARB_extensions_string
+#define WGL_ARB_extensions_string 1
+typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
+#ifdef WGL_WGLEXT_PROTOTYPES
+const char *WINAPI wglGetExtensionsStringARB (HDC hdc);
+#endif
+#endif /* WGL_ARB_extensions_string */
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_ARB_framebuffer_sRGB 1
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+#endif /* WGL_ARB_framebuffer_sRGB */
+
+#ifndef WGL_ARB_make_current_read
+#define WGL_ARB_make_current_read 1
+#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
+#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+HDC WINAPI wglGetCurrentReadDCARB (void);
+#endif
+#endif /* WGL_ARB_make_current_read */
+
+#ifndef WGL_ARB_multisample
+#define WGL_ARB_multisample 1
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif /* WGL_ARB_multisample */
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_ARB_pbuffer 1
+DECLARE_HANDLE(HPBUFFERARB);
+#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
+#define WGL_PBUFFER_LARGEST_ARB 0x2033
+#define WGL_PBUFFER_WIDTH_ARB 0x2034
+#define WGL_PBUFFER_HEIGHT_ARB 0x2035
+#define WGL_PBUFFER_LOST_ARB 0x2036
+typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
+#ifdef WGL_WGLEXT_PROTOTYPES
+HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer);
+int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC);
+BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer);
+BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
+#endif
+#endif /* WGL_ARB_pbuffer */
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_ARB_pixel_format 1
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
+BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
+BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+#endif /* WGL_ARB_pixel_format */
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_ARB_pixel_format_float 1
+#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
+#endif /* WGL_ARB_pixel_format_float */
+
+#ifndef WGL_ARB_render_texture
+#define WGL_ARB_render_texture 1
+#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
+#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
+#define WGL_TEXTURE_FORMAT_ARB 0x2072
+#define WGL_TEXTURE_TARGET_ARB 0x2073
+#define WGL_MIPMAP_TEXTURE_ARB 0x2074
+#define WGL_TEXTURE_RGB_ARB 0x2075
+#define WGL_TEXTURE_RGBA_ARB 0x2076
+#define WGL_NO_TEXTURE_ARB 0x2077
+#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
+#define WGL_TEXTURE_1D_ARB 0x2079
+#define WGL_TEXTURE_2D_ARB 0x207A
+#define WGL_MIPMAP_LEVEL_ARB 0x207B
+#define WGL_CUBE_MAP_FACE_ARB 0x207C
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
+#define WGL_FRONT_LEFT_ARB 0x2083
+#define WGL_FRONT_RIGHT_ARB 0x2084
+#define WGL_BACK_LEFT_ARB 0x2085
+#define WGL_BACK_RIGHT_ARB 0x2086
+#define WGL_AUX0_ARB 0x2087
+#define WGL_AUX1_ARB 0x2088
+#define WGL_AUX2_ARB 0x2089
+#define WGL_AUX3_ARB 0x208A
+#define WGL_AUX4_ARB 0x208B
+#define WGL_AUX5_ARB 0x208C
+#define WGL_AUX6_ARB 0x208D
+#define WGL_AUX7_ARB 0x208E
+#define WGL_AUX8_ARB 0x208F
+#define WGL_AUX9_ARB 0x2090
+typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
+BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
+BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList);
+#endif
+#endif /* WGL_ARB_render_texture */
+
+#ifndef WGL_ARB_robustness_application_isolation
+#define WGL_ARB_robustness_application_isolation 1
+#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
+#endif /* WGL_ARB_robustness_application_isolation */
+
+#ifndef WGL_ARB_robustness_share_group_isolation
+#define WGL_ARB_robustness_share_group_isolation 1
+#endif /* WGL_ARB_robustness_share_group_isolation */
+
+#ifndef WGL_3DFX_multisample
+#define WGL_3DFX_multisample 1
+#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
+#define WGL_SAMPLES_3DFX 0x2061
+#endif /* WGL_3DFX_multisample */
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_3DL_stereo_control 1
+#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
+#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
+#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
+#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
+typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState);
+#endif
+#endif /* WGL_3DL_stereo_control */
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_AMD_gpu_association 1
+#define WGL_GPU_VENDOR_AMD 0x1F00
+#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
+#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define WGL_GPU_RAM_AMD 0x21A3
+#define WGL_GPU_CLOCK_AMD 0x21A4
+#define WGL_GPU_NUM_PIPES_AMD 0x21A5
+#define WGL_GPU_NUM_SIMD_AMD 0x21A6
+#define WGL_GPU_NUM_RB_AMD 0x21A7
+#define WGL_GPU_NUM_SPI_AMD 0x21A8
+typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
+typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
+typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
+typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
+typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
+typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#ifdef WGL_WGLEXT_PROTOTYPES
+UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids);
+INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data);
+UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc);
+HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id);
+HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList);
+BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc);
+BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc);
+HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
+VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+#endif /* WGL_AMD_gpu_association */
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_ATI_pixel_format_float 1
+#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
+#endif /* WGL_ATI_pixel_format_float */
+
+#ifndef WGL_ATI_render_texture_rectangle
+#define WGL_ATI_render_texture_rectangle 1
+#define WGL_TEXTURE_RECTANGLE_ATI 0x21A5
+#endif /* WGL_ATI_render_texture_rectangle */
+
+#ifndef WGL_EXT_colorspace
+#define WGL_EXT_colorspace 1
+#define WGL_COLORSPACE_EXT 0x309D
+#define WGL_COLORSPACE_SRGB_EXT 0x3089
+#define WGL_COLORSPACE_LINEAR_EXT 0x308A
+#endif /* WGL_EXT_colorspace */
+
+#ifndef WGL_EXT_create_context_es2_profile
+#define WGL_EXT_create_context_es2_profile 1
+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+#endif /* WGL_EXT_create_context_es2_profile */
+
+#ifndef WGL_EXT_create_context_es_profile
+#define WGL_EXT_create_context_es_profile 1
+#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+#endif /* WGL_EXT_create_context_es_profile */
+
+#ifndef WGL_EXT_depth_float
+#define WGL_EXT_depth_float 1
+#define WGL_DEPTH_FLOAT_EXT 0x2040
+#endif /* WGL_EXT_depth_float */
+
+#ifndef WGL_EXT_display_color_table
+#define WGL_EXT_display_color_table 1
+typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
+typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+#ifdef WGL_WGLEXT_PROTOTYPES
+GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id);
+GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length);
+GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id);
+VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id);
+#endif
+#endif /* WGL_EXT_display_color_table */
+
+#ifndef WGL_EXT_extensions_string
+#define WGL_EXT_extensions_string 1
+typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
+#ifdef WGL_WGLEXT_PROTOTYPES
+const char *WINAPI wglGetExtensionsStringEXT (void);
+#endif
+#endif /* WGL_EXT_extensions_string */
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_EXT_framebuffer_sRGB 1
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
+#endif /* WGL_EXT_framebuffer_sRGB */
+
+#ifndef WGL_EXT_make_current_read
+#define WGL_EXT_make_current_read 1
+#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+HDC WINAPI wglGetCurrentReadDCEXT (void);
+#endif
+#endif /* WGL_EXT_make_current_read */
+
+#ifndef WGL_EXT_multisample
+#define WGL_EXT_multisample 1
+#define WGL_SAMPLE_BUFFERS_EXT 0x2041
+#define WGL_SAMPLES_EXT 0x2042
+#endif /* WGL_EXT_multisample */
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_EXT_pbuffer 1
+DECLARE_HANDLE(HPBUFFEREXT);
+#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
+#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
+#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
+#define WGL_PBUFFER_LARGEST_EXT 0x2033
+#define WGL_PBUFFER_WIDTH_EXT 0x2034
+#define WGL_PBUFFER_HEIGHT_EXT 0x2035
+typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
+#ifdef WGL_WGLEXT_PROTOTYPES
+HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer);
+int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC);
+BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer);
+BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
+#endif
+#endif /* WGL_EXT_pbuffer */
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_EXT_pixel_format 1
+#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
+#define WGL_DRAW_TO_WINDOW_EXT 0x2001
+#define WGL_DRAW_TO_BITMAP_EXT 0x2002
+#define WGL_ACCELERATION_EXT 0x2003
+#define WGL_NEED_PALETTE_EXT 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
+#define WGL_SWAP_METHOD_EXT 0x2007
+#define WGL_NUMBER_OVERLAYS_EXT 0x2008
+#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
+#define WGL_TRANSPARENT_EXT 0x200A
+#define WGL_TRANSPARENT_VALUE_EXT 0x200B
+#define WGL_SHARE_DEPTH_EXT 0x200C
+#define WGL_SHARE_STENCIL_EXT 0x200D
+#define WGL_SHARE_ACCUM_EXT 0x200E
+#define WGL_SUPPORT_GDI_EXT 0x200F
+#define WGL_SUPPORT_OPENGL_EXT 0x2010
+#define WGL_DOUBLE_BUFFER_EXT 0x2011
+#define WGL_STEREO_EXT 0x2012
+#define WGL_PIXEL_TYPE_EXT 0x2013
+#define WGL_COLOR_BITS_EXT 0x2014
+#define WGL_RED_BITS_EXT 0x2015
+#define WGL_RED_SHIFT_EXT 0x2016
+#define WGL_GREEN_BITS_EXT 0x2017
+#define WGL_GREEN_SHIFT_EXT 0x2018
+#define WGL_BLUE_BITS_EXT 0x2019
+#define WGL_BLUE_SHIFT_EXT 0x201A
+#define WGL_ALPHA_BITS_EXT 0x201B
+#define WGL_ALPHA_SHIFT_EXT 0x201C
+#define WGL_ACCUM_BITS_EXT 0x201D
+#define WGL_ACCUM_RED_BITS_EXT 0x201E
+#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
+#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
+#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
+#define WGL_DEPTH_BITS_EXT 0x2022
+#define WGL_STENCIL_BITS_EXT 0x2023
+#define WGL_AUX_BUFFERS_EXT 0x2024
+#define WGL_NO_ACCELERATION_EXT 0x2025
+#define WGL_GENERIC_ACCELERATION_EXT 0x2026
+#define WGL_FULL_ACCELERATION_EXT 0x2027
+#define WGL_SWAP_EXCHANGE_EXT 0x2028
+#define WGL_SWAP_COPY_EXT 0x2029
+#define WGL_SWAP_UNDEFINED_EXT 0x202A
+#define WGL_TYPE_RGBA_EXT 0x202B
+#define WGL_TYPE_COLORINDEX_EXT 0x202C
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
+BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
+BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+#endif /* WGL_EXT_pixel_format */
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_EXT_pixel_format_packed_float 1
+#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
+#endif /* WGL_EXT_pixel_format_packed_float */
+
+#ifndef WGL_EXT_swap_control
+#define WGL_EXT_swap_control 1
+typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
+typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglSwapIntervalEXT (int interval);
+int WINAPI wglGetSwapIntervalEXT (void);
+#endif
+#endif /* WGL_EXT_swap_control */
+
+#ifndef WGL_EXT_swap_control_tear
+#define WGL_EXT_swap_control_tear 1
+#endif /* WGL_EXT_swap_control_tear */
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_I3D_digital_video_control 1
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
+#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
+#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
+typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue);
+BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue);
+#endif
+#endif /* WGL_I3D_digital_video_control */
+
+#ifndef WGL_I3D_gamma
+#define WGL_I3D_gamma 1
+#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
+#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue);
+BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue);
+BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
+BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
+#endif
+#endif /* WGL_I3D_gamma */
+
+#ifndef WGL_I3D_genlock
+#define WGL_I3D_genlock 1
+#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
+#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045
+#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046
+#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047
+#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
+#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
+#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
+#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
+#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
+typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
+typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglEnableGenlockI3D (HDC hDC);
+BOOL WINAPI wglDisableGenlockI3D (HDC hDC);
+BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag);
+BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource);
+BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource);
+BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge);
+BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge);
+BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate);
+BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate);
+BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay);
+BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay);
+BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
+#endif
+#endif /* WGL_I3D_genlock */
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_I3D_image_buffer 1
+#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
+#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
+typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
+typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
+typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
+typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
+#ifdef WGL_WGLEXT_PROTOTYPES
+LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags);
+BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress);
+BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
+BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count);
+#endif
+#endif /* WGL_I3D_image_buffer */
+
+#ifndef WGL_I3D_swap_frame_lock
+#define WGL_I3D_swap_frame_lock 1
+typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglEnableFrameLockI3D (void);
+BOOL WINAPI wglDisableFrameLockI3D (void);
+BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag);
+BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag);
+#endif
+#endif /* WGL_I3D_swap_frame_lock */
+
+#ifndef WGL_I3D_swap_frame_usage
+#define WGL_I3D_swap_frame_usage 1
+typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
+typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglGetFrameUsageI3D (float *pUsage);
+BOOL WINAPI wglBeginFrameTrackingI3D (void);
+BOOL WINAPI wglEndFrameTrackingI3D (void);
+BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+#endif
+#endif /* WGL_I3D_swap_frame_usage */
+
+#ifndef WGL_NV_DX_interop
+#define WGL_NV_DX_interop 1
+#define WGL_ACCESS_READ_ONLY_NV 0x00000000
+#define WGL_ACCESS_READ_WRITE_NV 0x00000001
+#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002
+typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle);
+typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice);
+typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
+typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
+typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
+typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle);
+HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice);
+BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice);
+HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
+BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject);
+BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access);
+BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
+BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
+#endif
+#endif /* WGL_NV_DX_interop */
+
+#ifndef WGL_NV_DX_interop2
+#define WGL_NV_DX_interop2 1
+#endif /* WGL_NV_DX_interop2 */
+
+#ifndef WGL_NV_copy_image
+#define WGL_NV_copy_image 1
+typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+#endif /* WGL_NV_copy_image */
+
+#ifndef WGL_NV_delay_before_swap
+#define WGL_NV_delay_before_swap 1
+typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglDelayBeforeSwapNV (HDC hDC, GLfloat seconds);
+#endif
+#endif /* WGL_NV_delay_before_swap */
+
+#ifndef WGL_NV_float_buffer
+#define WGL_NV_float_buffer 1
+#define WGL_FLOAT_COMPONENTS_NV 0x20B0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
+#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
+#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
+#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
+#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
+#endif /* WGL_NV_float_buffer */
+
+#ifndef WGL_NV_gpu_affinity
+#define WGL_NV_gpu_affinity 1
+DECLARE_HANDLE(HGPUNV);
+struct _GPU_DEVICE {
+ DWORD cb;
+ CHAR DeviceName[32];
+ CHAR DeviceString[128];
+ DWORD Flags;
+ RECT rcVirtualScreen;
+};
+typedef struct _GPU_DEVICE *PGPU_DEVICE;
+#define ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
+#define ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
+typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
+typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
+typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu);
+BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList);
+BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+BOOL WINAPI wglDeleteDCNV (HDC hdc);
+#endif
+#endif /* WGL_NV_gpu_affinity */
+
+#ifndef WGL_NV_multisample_coverage
+#define WGL_NV_multisample_coverage 1
+#define WGL_COVERAGE_SAMPLES_NV 0x2042
+#define WGL_COLOR_SAMPLES_NV 0x20B9
+#endif /* WGL_NV_multisample_coverage */
+
+#ifndef WGL_NV_present_video
+#define WGL_NV_present_video 1
+DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
+#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
+typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
+typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
+typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
+#ifdef WGL_WGLEXT_PROTOTYPES
+int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
+BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
+BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue);
+#endif
+#endif /* WGL_NV_present_video */
+
+#ifndef WGL_NV_render_depth_texture
+#define WGL_NV_render_depth_texture 1
+#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
+#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
+#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
+#define WGL_DEPTH_COMPONENT_NV 0x20A7
+#endif /* WGL_NV_render_depth_texture */
+
+#ifndef WGL_NV_render_texture_rectangle
+#define WGL_NV_render_texture_rectangle 1
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
+#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
+#endif /* WGL_NV_render_texture_rectangle */
+
+#ifndef WGL_NV_swap_group
+#define WGL_NV_swap_group 1
+typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
+typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
+typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
+typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
+typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group);
+BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier);
+BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier);
+BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
+BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count);
+BOOL WINAPI wglResetFrameCountNV (HDC hDC);
+#endif
+#endif /* WGL_NV_swap_group */
+
+#ifndef WGL_NV_vertex_array_range
+#define WGL_NV_vertex_array_range 1
+typedef void *(WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
+#ifdef WGL_WGLEXT_PROTOTYPES
+void *WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+void WINAPI wglFreeMemoryNV (void *pointer);
+#endif
+#endif /* WGL_NV_vertex_array_range */
+
+#ifndef WGL_NV_video_capture
+#define WGL_NV_video_capture 1
+DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
+#define WGL_UNIQUE_ID_NV 0x20CE
+#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
+typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
+BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
+BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+#endif
+#endif /* WGL_NV_video_capture */
+
+#ifndef WGL_NV_video_output
+#define WGL_NV_video_output 1
+DECLARE_HANDLE(HPVIDEODEV);
+#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
+#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
+#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
+#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
+#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
+#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
+#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define WGL_VIDEO_OUT_FRAME 0x20C8
+#define WGL_VIDEO_OUT_FIELD_1 0x20C9
+#define WGL_VIDEO_OUT_FIELD_2 0x20CA
+#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
+#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
+typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
+typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
+BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice);
+BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer);
+BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
+BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif
+#endif /* WGL_NV_video_output */
+
+#ifndef WGL_OML_sync_control
+#define WGL_OML_sync_control 1
+typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
+typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
+#ifdef WGL_WGLEXT_PROTOTYPES
+BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
+BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator);
+INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
+BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
+#endif
+#endif /* WGL_OML_sync_control */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/include/angle_gl.h b/gfx/angle/checkout/include/angle_gl.h
new file mode 100644
index 0000000000..4ff294bf63
--- /dev/null
+++ b/gfx/angle/checkout/include/angle_gl.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.
+//
+// angle_gl.h:
+// Includes all necessary GL headers and definitions for ANGLE.
+//
+
+#ifndef ANGLEGL_H_
+#define ANGLEGL_H_
+
+#include "GLES/gl.h"
+#include "GLES/glext.h"
+#include "GLES2/gl2.h"
+#include "GLES2/gl2ext.h"
+#include "GLES3/gl3.h"
+#include "GLES3/gl31.h"
+#include "GLES3/gl32.h"
+
+// TODO(http://anglebug.com/3730): Autogenerate these enums from gl.xml
+// HACK: Defines for queries that are not in GLES
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+
+#endif // ANGLEGL_H_
diff --git a/gfx/angle/checkout/include/export.h b/gfx/angle/checkout/include/export.h
new file mode 100644
index 0000000000..6a8e30fd80
--- /dev/null
+++ b/gfx/angle/checkout/include/export.h
@@ -0,0 +1,40 @@
+//
+// 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.
+//
+
+// export.h : Defines ANGLE_EXPORT, a macro for exporting functions from the DLL
+
+#ifndef LIBGLESV2_EXPORT_H_
+#define LIBGLESV2_EXPORT_H_
+
+#if !defined(ANGLE_EXPORT)
+# if defined(_WIN32)
+# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) || \
+ defined(LIBFEATURE_SUPPORT_IMPLEMENTATION) || defined(LIBCL_IMPLEMENTATION)
+# define ANGLE_EXPORT __declspec(dllexport)
+# else
+# define ANGLE_EXPORT __declspec(dllimport)
+# endif
+# elif defined(__GNUC__)
+# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) || \
+ defined(LIBFEATURE_SUPPORT_IMPLEMENTATION) || defined(LIBCL_IMPLEMENTATION)
+# define ANGLE_EXPORT __attribute__((visibility("default")))
+# else
+# define ANGLE_EXPORT
+# endif
+# else
+# define ANGLE_EXPORT
+# endif
+#endif // !defined(ANGLE_EXPORT)
+
+#if !defined(ANGLE_NO_EXPORT)
+# if defined(__GNUC__)
+# define ANGLE_NO_EXPORT __attribute__((visibility("hidden")))
+# else
+# define ANGLE_NO_EXPORT
+# endif
+#endif // !defined(ANGLE_NO_EXPORT)
+
+#endif // LIBGLESV2_EXPORT_H_
diff --git a/gfx/angle/checkout/include/platform/Feature.h b/gfx/angle/checkout/include/platform/Feature.h
new file mode 100644
index 0000000000..c1de314e80
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/Feature.h
@@ -0,0 +1,196 @@
+//
+// 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.
+//
+// Feature.h: Definition of structs to hold feature/workaround information.
+//
+
+#ifndef ANGLE_PLATFORM_FEATURE_H_
+#define ANGLE_PLATFORM_FEATURE_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#define ANGLE_FEATURE_CONDITION(set, feature, cond) \
+ do \
+ { \
+ (set)->feature.enabled = cond; \
+ (set)->feature.condition = ANGLE_STRINGIFY(cond); \
+ } while (0)
+
+namespace angle
+{
+
+enum class FeatureCategory
+{
+ FrontendFeatures,
+ FrontendWorkarounds,
+ OpenGLWorkarounds,
+ OpenGLFeatures,
+ D3DWorkarounds,
+ VulkanFeatures,
+ VulkanWorkarounds,
+ VulkanAppWorkarounds,
+ MetalFeatures,
+ MetalWorkarounds,
+};
+
+constexpr char kFeatureCategoryFrontendWorkarounds[] = "Frontend workarounds";
+constexpr char kFeatureCategoryFrontendFeatures[] = "Frontend features";
+constexpr char kFeatureCategoryOpenGLWorkarounds[] = "OpenGL workarounds";
+constexpr char kFeatureCategoryOpenGLFeatures[] = "OpenGL features";
+constexpr char kFeatureCategoryD3DWorkarounds[] = "D3D workarounds";
+constexpr char kFeatureCategoryVulkanAppWorkarounds[] = "Vulkan app workarounds";
+constexpr char kFeatureCategoryVulkanWorkarounds[] = "Vulkan workarounds";
+constexpr char kFeatureCategoryVulkanFeatures[] = "Vulkan features";
+constexpr char kFeatureCategoryMetalFeatures[] = "Metal features";
+constexpr char kFeatureCategoryMetalWorkarounds[] = "Metal workarounds";
+constexpr char kFeatureCategoryUnknown[] = "Unknown";
+
+inline const char *FeatureCategoryToString(const FeatureCategory &fc)
+{
+ switch (fc)
+ {
+ case FeatureCategory::FrontendFeatures:
+ return kFeatureCategoryFrontendFeatures;
+ break;
+
+ case FeatureCategory::FrontendWorkarounds:
+ return kFeatureCategoryFrontendWorkarounds;
+ break;
+
+ case FeatureCategory::OpenGLWorkarounds:
+ return kFeatureCategoryOpenGLWorkarounds;
+ break;
+
+ case FeatureCategory::OpenGLFeatures:
+ return kFeatureCategoryOpenGLFeatures;
+ break;
+
+ case FeatureCategory::D3DWorkarounds:
+ return kFeatureCategoryD3DWorkarounds;
+ break;
+
+ case FeatureCategory::VulkanFeatures:
+ return kFeatureCategoryVulkanFeatures;
+ break;
+
+ case FeatureCategory::VulkanWorkarounds:
+ return kFeatureCategoryVulkanWorkarounds;
+ break;
+
+ case FeatureCategory::VulkanAppWorkarounds:
+ return kFeatureCategoryVulkanAppWorkarounds;
+ break;
+
+ case FeatureCategory::MetalFeatures:
+ return kFeatureCategoryMetalFeatures;
+ break;
+
+ case FeatureCategory::MetalWorkarounds:
+ return kFeatureCategoryMetalWorkarounds;
+ break;
+
+ default:
+ return kFeatureCategoryUnknown;
+ break;
+ }
+}
+
+constexpr char kFeatureStatusEnabled[] = "enabled";
+constexpr char kFeatureStatusDisabled[] = "disabled";
+
+inline const char *FeatureStatusToString(const bool &status)
+{
+ if (status)
+ {
+ return kFeatureStatusEnabled;
+ }
+ return kFeatureStatusDisabled;
+}
+
+struct FeatureInfo;
+
+using FeatureMap = std::map<std::string, FeatureInfo *>;
+using FeatureList = std::vector<const FeatureInfo *>;
+
+struct FeatureInfo
+{
+ FeatureInfo(const FeatureInfo &other);
+ FeatureInfo(const char *name,
+ const FeatureCategory &category,
+ const char *description,
+ FeatureMap *const mapPtr,
+ const char *bug);
+ ~FeatureInfo();
+
+ // The name of the workaround, lowercase, camel_case
+ const char *const name;
+
+ // The category that the workaround belongs to. Eg. "Vulkan workarounds"
+ const FeatureCategory category;
+
+ // A short description to be read by the user.
+ const char *const description;
+
+ // A link to the bug, if any
+ const char *const bug;
+
+ // Whether the workaround is enabled or not. Determined by heuristics like vendor ID and
+ // version, but may be overriden to any value.
+ bool enabled = false;
+
+ // A stringified version of the condition used to set 'enabled'. ie "IsNvidia() && IsApple()"
+ const char *condition;
+};
+
+inline FeatureInfo::FeatureInfo(const FeatureInfo &other) = default;
+inline FeatureInfo::FeatureInfo(const char *name,
+ const FeatureCategory &category,
+ const char *description,
+ FeatureMap *const mapPtr,
+ const char *bug = "")
+ : name(name),
+ category(category),
+ description(description),
+ bug(bug),
+ enabled(false),
+ condition("")
+{
+ if (mapPtr != nullptr)
+ {
+ (*mapPtr)[std::string(name)] = this;
+ }
+}
+
+inline FeatureInfo::~FeatureInfo() = default;
+
+struct FeatureSetBase
+{
+ public:
+ FeatureSetBase();
+ ~FeatureSetBase();
+
+ private:
+ // Non-copyable
+ FeatureSetBase(const FeatureSetBase &other) = delete;
+ FeatureSetBase &operator=(const FeatureSetBase &other) = delete;
+
+ protected:
+ FeatureMap members = FeatureMap();
+
+ public:
+ void overrideFeatures(const std::vector<std::string> &featureNames, bool enabled);
+ void populateFeatureList(FeatureList *features) const;
+
+ const FeatureMap &getFeatures() const { return members; }
+};
+
+inline FeatureSetBase::FeatureSetBase() = default;
+inline FeatureSetBase::~FeatureSetBase() = default;
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_WORKAROUND_H_
diff --git a/gfx/angle/checkout/include/platform/FeaturesD3D_autogen.h b/gfx/angle/checkout/include/platform/FeaturesD3D_autogen.h
new file mode 100644
index 0000000000..0df072b497
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/FeaturesD3D_autogen.h
@@ -0,0 +1,198 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_features.py using data from d3d_features.json.
+//
+// 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.
+//
+// FeaturesD3D_autogen.h: Features and workarounds for D3D driver bugs and other issues.
+
+#ifndef ANGLE_PLATFORM_FEATURESD3D_H_
+#define ANGLE_PLATFORM_FEATURESD3D_H_
+
+#include "platform/Feature.h"
+
+namespace angle
+{
+
+struct FeaturesD3D : FeatureSetBase
+{
+ FeaturesD3D();
+ ~FeaturesD3D();
+
+ FeatureInfo mrtPerfWorkaround = {
+ "mrtPerfWorkaround",
+ FeatureCategory::D3DWorkarounds,
+ "Some drivers have a bug where they ignore null render targets",
+ &members,
+ };
+
+ FeatureInfo setDataFasterThanImageUpload = {
+ "setDataFasterThanImageUpload",
+ FeatureCategory::D3DWorkarounds,
+ "Set data faster than image upload",
+ &members,
+ };
+
+ FeatureInfo setDataFasterThanImageUploadOn128bitFormats = {
+ "setDataFasterThanImageUploadOn128bitFormats",
+ FeatureCategory::D3DWorkarounds,
+ "Set data faster than image upload on 128bit formats",
+ &members,
+ };
+
+ FeatureInfo zeroMaxLodWorkaround = {
+ "zeroMaxLodWorkaround",
+ FeatureCategory::D3DWorkarounds,
+ "Missing an option to disable mipmaps on a mipmapped texture",
+ &members,
+ };
+
+ FeatureInfo useInstancedPointSpriteEmulation = {
+ "useInstancedPointSpriteEmulation",
+ FeatureCategory::D3DWorkarounds,
+ "Some D3D11 renderers do not support geometry shaders for pointsprite emulation",
+ &members,
+ };
+
+ FeatureInfo depthStencilBlitExtraCopy = {
+ "depthStencilBlitExtraCopy", FeatureCategory::D3DWorkarounds,
+ "Bug in some drivers triggers a TDR when using CopySubresourceRegion from a staging "
+ "texture to a depth/stencil",
+ &members, "http://anglebug.com/1452"};
+
+ FeatureInfo expandIntegerPowExpressions = {
+ "expandIntegerPowExpressions",
+ FeatureCategory::D3DWorkarounds,
+ "The HLSL optimizer has a bug with optimizing 'pow' in certain integer-valued expressions",
+ &members,
+ };
+
+ FeatureInfo flushAfterEndingTransformFeedback = {
+ "flushAfterEndingTransformFeedback",
+ FeatureCategory::D3DWorkarounds,
+ "Some drivers sometimes write out-of-order results to StreamOut buffers when transform "
+ "feedback is used to repeatedly write to the same buffer positions",
+ &members,
+ };
+
+ FeatureInfo getDimensionsIgnoresBaseLevel = {
+ "getDimensionsIgnoresBaseLevel",
+ FeatureCategory::D3DWorkarounds,
+ "Some drivers do not take into account the base level of the "
+ "texture in the results of the HLSL GetDimensions builtin",
+ &members,
+ };
+
+ FeatureInfo preAddTexelFetchOffsets = {
+ "preAddTexelFetchOffsets",
+ FeatureCategory::D3DWorkarounds,
+ "HLSL's function texture.Load returns 0 when the parameter Location is negative, even if "
+ "the sum of Offset and Location is in range",
+ &members,
+ };
+
+ FeatureInfo emulateTinyStencilTextures = {
+ "emulateTinyStencilTextures",
+ FeatureCategory::D3DWorkarounds,
+ "1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly",
+ &members,
+ };
+
+ FeatureInfo disableB5G6R5Support = {
+ "disableB5G6R5Support",
+ FeatureCategory::D3DWorkarounds,
+ "Textures with the format "
+ "DXGI_FORMAT_B5G6R5_UNORM have incorrect data",
+ &members,
+ };
+
+ FeatureInfo rewriteUnaryMinusOperator = {
+ "rewriteUnaryMinusOperator",
+ FeatureCategory::D3DWorkarounds,
+ "Evaluating unary minus operator on integer may get wrong answer in vertex shaders",
+ &members,
+ };
+
+ FeatureInfo emulateIsnanFloat = {"emulateIsnanFloat", FeatureCategory::D3DWorkarounds,
+ "Using isnan() on highp float will get wrong answer", &members,
+ "https://crbug.com/650547"};
+
+ FeatureInfo callClearTwice = {"callClearTwice", FeatureCategory::D3DWorkarounds,
+ "Using clear() may not take effect", &members,
+ "https://crbug.com/655534"};
+
+ FeatureInfo emulateClearViewAfterDualSourceBlending = {
+ "emulateClearViewAfterDualSourceBlending", FeatureCategory::D3DWorkarounds,
+ "On Sandybridge, calling ClearView after using dual source blending causes hardware to "
+ "hang",
+ &members, "https://bugzilla.mozilla.org/show_bug.cgi?id=1633628"};
+
+ FeatureInfo scissoredClearArtifacts = {
+ "scissoredClearArtifacts", FeatureCategory::D3DWorkarounds,
+ "On Skylake, calling ClearView with a scissor rect that is not a multiple of 8x4 pixels "
+ "causes corruption of pixels in the 8x4 pixel tiles along the edge which resembles a "
+ "square wave",
+ &members, "https://bugzilla.mozilla.org/show_bug.cgi?id=1817240"};
+
+ FeatureInfo useSystemMemoryForConstantBuffers = {
+ "useSystemMemoryForConstantBuffers", FeatureCategory::D3DWorkarounds,
+ "Copying from staging storage to constant buffer "
+ "storage does not work",
+ &members, "https://crbug.com/593024"};
+
+ FeatureInfo selectViewInGeometryShader = {
+ "selectViewInGeometryShader",
+ FeatureCategory::D3DWorkarounds,
+ "The viewport or render target slice will be selected in the geometry shader stage for "
+ "the ANGLE_multiview extension",
+ &members,
+ };
+
+ FeatureInfo addMockTextureNoRenderTarget = {
+ "addMockTextureNoRenderTarget", FeatureCategory::D3DWorkarounds,
+ "On some drivers when rendering with no render target, two bugs lead to incorrect behavior",
+ &members, "http://anglebug.com/2152"};
+
+ FeatureInfo skipVSConstantRegisterZero = {
+ "skipVSConstantRegisterZero",
+ FeatureCategory::D3DWorkarounds,
+ "In specific cases the driver doesn't handle constant register zero correctly",
+ &members,
+ };
+
+ FeatureInfo forceAtomicValueResolution = {
+ "forceAtomicValueResolution", FeatureCategory::D3DWorkarounds,
+ "On some drivers the return value from RWByteAddressBuffer.InterlockedAdd does not resolve "
+ "when used in the .yzw components of a RWByteAddressBuffer.Store operation",
+ &members, "http://anglebug.com/3246"};
+
+ FeatureInfo allowClearForRobustResourceInit = {
+ "allowClearForRobustResourceInit", FeatureCategory::D3DWorkarounds,
+ "Some drivers corrupt texture data when clearing for robust resource initialization.",
+ &members, "http://crbug.com/941620"};
+
+ FeatureInfo allowTranslateUniformBlockToStructuredBuffer = {
+ "allowTranslateUniformBlockToStructuredBuffer", FeatureCategory::D3DWorkarounds,
+ "There is a slow fxc compile performance issue with dynamic uniform indexing if "
+ "translating a uniform block with a large array member to cbuffer.",
+ &members, "http://anglebug.com/3682"};
+
+ FeatureInfo allowES3OnFL100 = {
+ "allowES3OnFL100",
+ FeatureCategory::D3DWorkarounds,
+ "Allow ES3 on 10.0 devices",
+ &members,
+ };
+
+ FeatureInfo disableRasterizerOrderViews = {
+ "disableRasterizerOrderViews", FeatureCategory::D3DWorkarounds, "Disable ROVs for testing",
+ &members, "http://anglebug.com/7279"};
+};
+
+inline FeaturesD3D::FeaturesD3D() = default;
+inline FeaturesD3D::~FeaturesD3D() = default;
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_FEATURESD3D_H_
diff --git a/gfx/angle/checkout/include/platform/FeaturesGL_autogen.h b/gfx/angle/checkout/include/platform/FeaturesGL_autogen.h
new file mode 100644
index 0000000000..5376f3400a
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/FeaturesGL_autogen.h
@@ -0,0 +1,501 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_features.py using data from gl_features.json.
+//
+// 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.
+//
+// FeaturesGL_autogen.h: angle::Features and workarounds for GL driver bugs and other issues.
+
+#ifndef ANGLE_PLATFORM_FEATURESGL_H_
+#define ANGLE_PLATFORM_FEATURESGL_H_
+
+#include "platform/Feature.h"
+
+namespace angle
+{
+
+struct FeaturesGL : FeatureSetBase
+{
+ FeaturesGL();
+ ~FeaturesGL();
+
+ FeatureInfo avoid1BitAlphaTextureFormats = {
+ "avoid1BitAlphaTextureFormats",
+ FeatureCategory::OpenGLWorkarounds,
+ "Issue with 1-bit alpha framebuffer formats",
+ &members,
+ };
+
+ FeatureInfo RGBA4IsNotSupportedForColorRendering = {
+ "RGBA4IsNotSupportedForColorRendering",
+ FeatureCategory::OpenGLWorkarounds,
+ "GL_RGBA4 is not color renderable",
+ &members,
+ };
+
+ FeatureInfo allowETCFormats = {
+ "allowETCFormats",
+ FeatureCategory::OpenGLWorkarounds,
+ "Enable ETC2/EAC on desktop OpenGL",
+ &members,
+ };
+
+ FeatureInfo allowAstcFormats = {
+ "allowAstcFormats",
+ FeatureCategory::OpenGLWorkarounds,
+ "Enable ASTC on desktop OpenGL",
+ &members,
+ };
+
+ FeatureInfo doesSRGBClearsOnLinearFramebufferAttachments = {
+ "doesSRGBClearsOnLinearFramebufferAttachments",
+ FeatureCategory::OpenGLWorkarounds,
+ "Issue clearing framebuffers with linear attachments when GL_FRAMEBUFFER_SRGB is enabled",
+ &members,
+ };
+
+ FeatureInfo doWhileGLSLCausesGPUHang = {
+ "doWhileGLSLCausesGPUHang", FeatureCategory::OpenGLWorkarounds,
+ "Some GLSL constructs involving do-while loops cause GPU hangs", &members,
+ "http://crbug.com/644669"};
+
+ FeatureInfo vertexIDDoesNotIncludeBaseVertex = {
+ "vertexIDDoesNotIncludeBaseVertex",
+ FeatureCategory::OpenGLWorkarounds,
+ "gl_VertexID in GLSL vertex shader doesn't include base vertex value",
+ &members,
+ };
+
+ FeatureInfo finishDoesNotCauseQueriesToBeAvailable = {
+ "finishDoesNotCauseQueriesToBeAvailable",
+ FeatureCategory::OpenGLWorkarounds,
+ "glFinish doesn't cause all queries to report available result",
+ &members,
+ };
+
+ FeatureInfo alwaysCallUseProgramAfterLink = {
+ "alwaysCallUseProgramAfterLink", FeatureCategory::OpenGLWorkarounds,
+ "Always call useProgram after a successful link to avoid a driver bug", &members,
+ "http://crbug.com/110263"};
+
+ FeatureInfo unpackOverlappingRowsSeparatelyUnpackBuffer = {
+ "unpackOverlappingRowsSeparatelyUnpackBuffer",
+ FeatureCategory::OpenGLWorkarounds,
+ "In the case of unpacking from a pixel unpack buffer, unpack overlapping rows row by row",
+ &members,
+ };
+
+ FeatureInfo packOverlappingRowsSeparatelyPackBuffer = {
+ "packOverlappingRowsSeparatelyPackBuffer",
+ FeatureCategory::OpenGLWorkarounds,
+ "In the case of packing to a pixel pack buffer, pack overlapping rows row by row",
+ &members,
+ };
+
+ FeatureInfo initializeCurrentVertexAttributes = {
+ "initializeCurrentVertexAttributes",
+ FeatureCategory::OpenGLWorkarounds,
+ "During initialization, assign the current vertex attributes to the spec-mandated defaults",
+ &members,
+ };
+
+ FeatureInfo emulateAbsIntFunction = {"emulateAbsIntFunction",
+ FeatureCategory::OpenGLWorkarounds,
+ "abs(i) where i is an integer returns unexpected result",
+ &members, "http://crbug.com/642227"};
+
+ FeatureInfo addAndTrueToLoopCondition = {
+ "addAndTrueToLoopCondition",
+ FeatureCategory::OpenGLWorkarounds,
+ "Calculation of loop conditions in for and while loop has bug",
+ &members,
+ };
+
+ FeatureInfo unpackLastRowSeparatelyForPaddingInclusion = {
+ "unpackLastRowSeparatelyForPaddingInclusion", FeatureCategory::OpenGLWorkarounds,
+ "When uploading textures from an unpack buffer, some drivers count an extra row padding",
+ &members, "http://anglebug.com/1512"};
+
+ FeatureInfo packLastRowSeparatelyForPaddingInclusion = {
+ "packLastRowSeparatelyForPaddingInclusion", FeatureCategory::OpenGLWorkarounds,
+ "When uploading textures from an pack buffer, some drivers count an extra row padding",
+ &members, "http://anglebug.com/1512"};
+
+ FeatureInfo emulateIsnanFloat = {"emulateIsnanFloat", FeatureCategory::OpenGLWorkarounds,
+ "Using isnan() on highp float will get wrong answer", &members,
+ "http://crbug.com/650547"};
+
+ FeatureInfo useUnusedBlocksWithStandardOrSharedLayout = {
+ "useUnusedBlocksWithStandardOrSharedLayout",
+ FeatureCategory::OpenGLWorkarounds,
+ "Unused std140 or shared uniform blocks will be treated as inactive",
+ &members,
+ };
+
+ FeatureInfo removeInvariantAndCentroidForESSL3 = {
+ "removeInvariantAndCentroidForESSL3",
+ FeatureCategory::OpenGLWorkarounds,
+ "Fix spec difference between GLSL 4.1 or lower and ESSL3",
+ &members,
+ };
+
+ FeatureInfo rewriteFloatUnaryMinusOperator = {
+ "rewriteFloatUnaryMinusOperator", FeatureCategory::OpenGLWorkarounds,
+ "Using '-<float>' will get wrong answer", &members, "http://crbug.com/308366"};
+
+ FeatureInfo emulateAtan2Float = {"emulateAtan2Float", FeatureCategory::OpenGLWorkarounds,
+ "atan(y, x) may return a wrong answer", &members,
+ "http://crbug.com/672380"};
+
+ FeatureInfo reapplyUBOBindingsAfterUsingBinaryProgram = {
+ "reapplyUBOBindingsAfterUsingBinaryProgram", FeatureCategory::OpenGLWorkarounds,
+ "Some drivers forget about UBO bindings when using program binaries", &members,
+ "http://anglebug.com/1637"};
+
+ FeatureInfo emulateMaxVertexAttribStride = {
+ "emulateMaxVertexAttribStride", FeatureCategory::OpenGLWorkarounds,
+ "Some drivers return 0 when MAX_VERTEX_ATTRIB_STRIED queried", &members,
+ "http://anglebug.com/1936"};
+
+ FeatureInfo dontInitializeUninitializedLocals = {
+ "dontInitializeUninitializedLocals", FeatureCategory::OpenGLWorkarounds,
+ "Initializing uninitialized locals caused odd behavior in a few WebGL 2 tests", &members,
+ "http://anglebug.com/2046"};
+
+ FeatureInfo clampPointSize = {
+ "clampPointSize",
+ FeatureCategory::OpenGLWorkarounds,
+ "The point size range reported from the API is inconsistent with the actual behavior",
+ &members,
+ };
+
+ FeatureInfo dontUseLoopsToInitializeVariables = {
+ "dontUseLoopsToInitializeVariables", FeatureCategory::OpenGLWorkarounds,
+ "For loops used to initialize variables hit native GLSL compiler bugs", &members,
+ "http://crbug.com/809422"};
+
+ FeatureInfo clampFragDepth = {
+ "clampFragDepth",
+ FeatureCategory::OpenGLWorkarounds,
+ "gl_FragDepth is not clamped correctly when rendering to a floating point depth buffer",
+ &members,
+ };
+
+ FeatureInfo rewriteRepeatedAssignToSwizzled = {
+ "rewriteRepeatedAssignToSwizzled",
+ FeatureCategory::OpenGLWorkarounds,
+ "Repeated assignment to swizzled values inside a "
+ "GLSL user-defined function have incorrect results",
+ &members,
+ };
+
+ FeatureInfo disableBlendFuncExtended = {
+ "disableBlendFuncExtended", FeatureCategory::OpenGLWorkarounds,
+ "ARB_blend_func_extended does not pass the tests", &members, "http://anglebug.com/1085"};
+
+ FeatureInfo unsizedSRGBReadPixelsDoesntTransform = {
+ "unsizedSRGBReadPixelsDoesntTransform", FeatureCategory::OpenGLWorkarounds,
+ "Drivers returning raw sRGB values instead of linearized values when calling glReadPixels "
+ "on unsized sRGB texture formats",
+ &members, "http://crbug.com/550292 http://crbug.com/565179"};
+
+ FeatureInfo queryCounterBitsGeneratesErrors = {
+ "queryCounterBitsGeneratesErrors", FeatureCategory::OpenGLWorkarounds,
+ "Drivers generate errors when querying the number of bits in timer queries", &members,
+ "http://anglebug.com/3027"};
+
+ FeatureInfo dontRelinkProgramsInParallel = {
+ "dontRelinkProgramsInParallel", FeatureCategory::OpenGLWorkarounds,
+ "Relinking a program in parallel is buggy", &members, "http://anglebug.com/3045"};
+
+ FeatureInfo disableWorkerContexts = {"disableWorkerContexts",
+ FeatureCategory::OpenGLWorkarounds,
+ "Some tests have been seen to fail using worker contexts",
+ &members, "http://crbug.com/849576"};
+
+ FeatureInfo limitWebglMaxTextureSizeTo4096 = {
+ "limitWebglMaxTextureSizeTo4096", FeatureCategory::OpenGLWorkarounds,
+ "Limit webgl max texture size to 4096 to avoid frequent "
+ "out-of-memory errors",
+ &members, "http://crbug.com/927470"};
+
+ FeatureInfo limitMaxMSAASamplesTo4 = {
+ "limitMaxMSAASamplesTo4", FeatureCategory::OpenGLWorkarounds,
+ "Various rendering bugs have been observed when using higher MSAA counts", &members,
+ "http://crbug.com/797243"};
+
+ FeatureInfo allowClearForRobustResourceInit = {
+ "allowClearForRobustResourceInit", FeatureCategory::OpenGLWorkarounds,
+ "Using glClear for robust resource initialization is buggy on some drivers and leads to "
+ "texture corruption. Default to data uploads except on MacOS where it is very slow.",
+ &members, "https://crbug.com/848952 http://crbug.com/883276"};
+
+ FeatureInfo clampArrayAccess = {"clampArrayAccess", FeatureCategory::OpenGLWorkarounds,
+ "Clamp uniform array access to avoid reading invalid memory.",
+ &members, "http://anglebug.com/2978"};
+
+ FeatureInfo resetTexImage2DBaseLevel = {
+ "resetTexImage2DBaseLevel", FeatureCategory::OpenGLWorkarounds,
+ "Reset texture base level before calling glTexImage2D to "
+ "work around pixel comparison failure.",
+ &members, "https://crbug.com/705865"};
+
+ FeatureInfo clearToZeroOrOneBroken = {
+ "clearToZeroOrOneBroken", FeatureCategory::OpenGLWorkarounds,
+ "Clears when the clear color is all zeros or ones do not work.", &members,
+ "https://crbug.com/710443"};
+
+ FeatureInfo limitMax3dArrayTextureSizeTo1024 = {
+ "limitMax3dArrayTextureSizeTo1024", FeatureCategory::OpenGLWorkarounds,
+ "Limit max 3d texture size and max array texture layers to 1024 to avoid system hang",
+ &members, "http://crbug.com/927470"};
+
+ FeatureInfo adjustSrcDstRegionForBlitFramebuffer = {
+ "adjustSrcDstRegionForBlitFramebuffer", FeatureCategory::OpenGLWorkarounds,
+ "Many platforms have issues with blitFramebuffer when the parameters are large.", &members,
+ "http://crbug.com/830046"};
+
+ FeatureInfo clipSrcRegionForBlitFramebuffer = {
+ "clipSrcRegionForBlitFramebuffer", FeatureCategory::OpenGLWorkarounds,
+ "Issues with blitFramebuffer when the parameters don't match the framebuffer size.",
+ &members, "http://crbug.com/830046"};
+
+ FeatureInfo RGBDXT1TexturesSampleZeroAlpha = {
+ "RGBDXT1TexturesSampleZeroAlpha", FeatureCategory::OpenGLWorkarounds,
+ "Sampling BLACK texels from RGB DXT1 textures returns transparent black on Mac.", &members,
+ "http://anglebug.com/3729"};
+
+ FeatureInfo unfoldShortCircuits = {
+ "unfoldShortCircuits", FeatureCategory::OpenGLWorkarounds,
+ "Mac incorrectly executes both sides of && and || expressions when they should "
+ "short-circuit.",
+ &members, "http://anglebug.com/482"};
+
+ FeatureInfo emulatePrimitiveRestartFixedIndex = {
+ "emulatePrimitiveRestartFixedIndex", FeatureCategory::OpenGLWorkarounds,
+ "When GL_PRIMITIVE_RESTART_FIXED_INDEX is not available, emulate it with "
+ "GL_PRIMITIVE_RESTART and glPrimitiveRestartIndex.",
+ &members, "http://anglebug.com/3997"};
+
+ FeatureInfo setPrimitiveRestartFixedIndexForDrawArrays = {
+ "setPrimitiveRestartFixedIndexForDrawArrays", FeatureCategory::OpenGLWorkarounds,
+ "Some drivers discard vertex data in DrawArrays calls when the fixed primitive restart "
+ "index is within the number of primitives being drawn.",
+ &members, "http://anglebug.com/3997"};
+
+ FeatureInfo removeDynamicIndexingOfSwizzledVector = {
+ "removeDynamicIndexingOfSwizzledVector", FeatureCategory::OpenGLWorkarounds,
+ "Dynamic indexing of swizzled l-values doesn't work correctly on various platforms.",
+ &members, "http://crbug.com/709351"};
+
+ FeatureInfo preAddTexelFetchOffsets = {
+ "preAddTexelFetchOffsets", FeatureCategory::OpenGLWorkarounds,
+ "Intel Mac drivers mistakenly consider the parameter position of nagative vaule as invalid "
+ "even if the sum of position and offset is in range, so we need to add workarounds by "
+ "rewriting texelFetchOffset(sampler, position, lod, offset) into texelFetch(sampler, "
+ "position + offset, lod).",
+ &members, "http://crbug.com/642605"};
+
+ FeatureInfo regenerateStructNames = {
+ "regenerateStructNames", FeatureCategory::OpenGLWorkarounds,
+ "All Mac drivers do not handle struct scopes correctly. This workaround overwrites a struct"
+ "name with a unique prefix.",
+ &members, "http://crbug.com/403957"};
+
+ FeatureInfo readPixelsUsingImplementationColorReadFormatForNorm16 = {
+ "readPixelsUsingImplementationColorReadFormatForNorm16", FeatureCategory::OpenGLWorkarounds,
+ "Quite some OpenGL ES drivers don't implement readPixels for RGBA/UNSIGNED_SHORT from "
+ "EXT_texture_norm16 correctly",
+ &members, "http://anglebug.com/4214"};
+
+ FeatureInfo flushBeforeDeleteTextureIfCopiedTo = {
+ "flushBeforeDeleteTextureIfCopiedTo", FeatureCategory::OpenGLWorkarounds,
+ "Some drivers track CopyTex{Sub}Image texture dependencies incorrectly. Flush"
+ " before glDeleteTextures in this case",
+ &members, "http://anglebug.com/4267"};
+
+ FeatureInfo rewriteRowMajorMatrices = {
+ "rewriteRowMajorMatrices", FeatureCategory::OpenGLWorkarounds,
+ "Rewrite row major matrices in shaders as column major as a driver bug workaround",
+ &members, "http://anglebug.com/2273"};
+
+ FeatureInfo disableDrawBuffersIndexed = {
+ "disableDrawBuffersIndexed",
+ FeatureCategory::OpenGLWorkarounds,
+ "Disable OES_draw_buffers_indexed extension.",
+ &members,
+ };
+
+ FeatureInfo disableSemaphoreFd = {"disableSemaphoreFd", FeatureCategory::OpenGLWorkarounds,
+ "Disable GL_EXT_semaphore_fd extension", &members,
+ "https://crbug.com/1046462"};
+
+ FeatureInfo disableTimestampQueries = {
+ "disableTimestampQueries", FeatureCategory::OpenGLWorkarounds,
+ "Disable GL_EXT_disjoint_timer_query extension", &members, "https://crbug.com/811661"};
+
+ FeatureInfo decodeEncodeSRGBForGenerateMipmap = {
+ "decodeEncodeSRGBForGenerateMipmap", FeatureCategory::OpenGLWorkarounds,
+ "Decode and encode before generateMipmap for srgb format textures.", &members,
+ "http://anglebug.com/4646"};
+
+ FeatureInfo emulateCopyTexImage2D = {
+ "emulateCopyTexImage2D",
+ FeatureCategory::OpenGLWorkarounds,
+ "Replace CopyTexImage2D with TexImage2D + CopyTexSubImage2D.",
+ &members,
+ };
+
+ FeatureInfo emulateCopyTexImage2DFromRenderbuffers = {
+ "emulateCopyTexImage2DFromRenderbuffers", FeatureCategory::OpenGLWorkarounds,
+ "CopyTexImage2D spuriously returns errors on iOS when copying from renderbuffers.",
+ &members, "https://anglebug.com/4674"};
+
+ FeatureInfo disableGPUSwitchingSupport = {
+ "disableGPUSwitchingSupport", FeatureCategory::OpenGLWorkarounds,
+ "Disable GPU switching support (use only the low-power GPU) on older MacBook Pros.",
+ &members, "https://crbug.com/1091824"};
+
+ FeatureInfo disableNativeParallelCompile = {
+ "disableNativeParallelCompile", FeatureCategory::OpenGLWorkarounds,
+ "Do not use native KHR_parallel_shader_compile even when available.", &members,
+ "http://crbug.com/1094869"};
+
+ FeatureInfo emulatePackSkipRowsAndPackSkipPixels = {
+ "emulatePackSkipRowsAndPackSkipPixels", FeatureCategory::OpenGLWorkarounds,
+ "GL_PACK_SKIP_ROWS and GL_PACK_SKIP_PIXELS are ignored in Apple's OpenGL driver.", &members,
+ "https://anglebug.com/4849"};
+
+ FeatureInfo clampMscRate = {
+ "clampMscRate", FeatureCategory::OpenGLWorkarounds,
+ "Some drivers return bogus values for GetMscRate, so we clamp it to 30Hz", &members,
+ "https://crbug.com/1042393"};
+
+ FeatureInfo bindTransformFeedbackBufferBeforeBindBufferRange = {
+ "bindTransformFeedbackBufferBeforeBindBufferRange", FeatureCategory::OpenGLWorkarounds,
+ "Bind transform feedback buffers to the generic binding point before calling "
+ "glBindBufferBase or glBindBufferRange.",
+ &members, "https://anglebug.com/5140"};
+
+ FeatureInfo disableSyncControlSupport = {
+ "disableSyncControlSupport", FeatureCategory::OpenGLWorkarounds,
+ "Speculative fix for issues on Linux/Wayland where exposing GLX_OML_sync_control renders "
+ "Chrome unusable",
+ &members, "https://crbug.com/1137851"};
+
+ FeatureInfo keepBufferShadowCopy = {
+ "keepBufferShadowCopy",
+ FeatureCategory::OpenGLWorkarounds,
+ "Maintain a shadow copy of buffer data when the GL API does not permit reading data back.",
+ &members,
+ };
+
+ FeatureInfo setZeroLevelBeforeGenerateMipmap = {
+ "setZeroLevelBeforeGenerateMipmap",
+ FeatureCategory::OpenGLWorkarounds,
+ "glGenerateMipmap fails if the zero texture level is not set on some Mac drivers.",
+ &members,
+ };
+
+ FeatureInfo promotePackedFormatsTo8BitPerChannel = {
+ "promotePackedFormatsTo8BitPerChannel", FeatureCategory::OpenGLWorkarounds,
+ "Packed color formats are buggy on Macs with AMD GPUs", &members,
+ "http://anglebug.com/5469"};
+
+ FeatureInfo initFragmentOutputVariables = {
+ "initFragmentOutputVariables", FeatureCategory::OpenGLWorkarounds,
+ "No init gl_FragColor causes context lost", &members, "http://crbug.com/1171371"};
+
+ FeatureInfo shiftInstancedArrayDataWithOffset = {
+ "shiftInstancedArrayDataWithOffset", FeatureCategory::OpenGLWorkarounds,
+ "glDrawArraysInstanced is buggy on certain new Mac Intel GPUs", &members,
+ "http://crbug.com/1144207"};
+
+ FeatureInfo syncVertexArraysToDefault = {
+ "syncVertexArraysToDefault", FeatureCategory::OpenGLWorkarounds,
+ "Only use the default VAO because of missing support or driver bugs", &members,
+ "http://anglebug.com/5577"};
+
+ FeatureInfo sanitizeAMDGPURendererString = {
+ "sanitizeAMDGPURendererString", FeatureCategory::OpenGLWorkarounds,
+ "Strip precise kernel and DRM version information from amdgpu renderer strings.", &members,
+ "http://crbug.com/1181193"};
+
+ FeatureInfo unbindFBOBeforeSwitchingContext = {
+ "unbindFBOBeforeSwitchingContext", FeatureCategory::OpenGLWorkarounds,
+ "Imagination GL drivers are buggy with context switching.", &members,
+ "http://crbug.com/1181193"};
+
+ FeatureInfo flushOnFramebufferChange = {"flushOnFramebufferChange",
+ FeatureCategory::OpenGLWorkarounds,
+ "Switching framebuffers without a flush can lead to "
+ "crashes on Intel 9th Generation GPU Macs.",
+ &members, "http://crbug.com/1181068"};
+
+ FeatureInfo disableMultisampledRenderToTexture = {
+ "disableMultisampledRenderToTexture", FeatureCategory::OpenGLWorkarounds,
+ "Many drivers have bugs when using GL_EXT_multisampled_render_to_texture", &members,
+ "http://anglebug.com/2894"};
+
+ FeatureInfo uploadTextureDataInChunks = {
+ "uploadTextureDataInChunks", FeatureCategory::OpenGLWorkarounds,
+ "Upload texture data in <120kb chunks to work around Mac driver hangs and crashes.",
+ &members, "http://crbug.com/1181068"};
+
+ FeatureInfo emulateImmutableCompressedTexture3D = {
+ "emulateImmutableCompressedTexture3D", FeatureCategory::OpenGLWorkarounds,
+ "Use non-immutable texture allocation to work around a driver bug.", &members,
+ "https://crbug.com/1060012"};
+
+ FeatureInfo emulateRGB10 = {"emulateRGB10", FeatureCategory::OpenGLWorkarounds,
+ "Emulate RGB10 support using RGB10_A2.", &members,
+ "https://crbug.com/1300575"};
+
+ FeatureInfo alwaysUnbindFramebufferTexture2D = {
+ "alwaysUnbindFramebufferTexture2D", FeatureCategory::OpenGLWorkarounds,
+ "Force unbind framebufferTexture2D before binding renderbuffer to work around driver bug.",
+ &members, "https://anglebug.com/5536"};
+
+ FeatureInfo disableTextureClampToBorder = {
+ "disableTextureClampToBorder", FeatureCategory::OpenGLWorkarounds,
+ "Imagination devices generate INVALID_ENUM when setting the texture border color.",
+ &members, "https://anglebug.com/7405"};
+
+ FeatureInfo passHighpToPackUnormSnormBuiltins = {
+ "passHighpToPackUnormSnormBuiltins", FeatureCategory::OpenGLWorkarounds,
+ "packUnorm4x8 fails on Pixel 4 if it is not passed a highp vec4.", &members,
+ "http://anglebug.com/7527"};
+
+ FeatureInfo supportsFragmentShaderInterlockNV = {
+ "supportsFragmentShaderInterlockNV", FeatureCategory::OpenGLFeatures,
+ "Backend GL context supports NV_fragment_shader_interlock extension", &members,
+ "http://anglebug.com/7279"};
+
+ FeatureInfo supportsFragmentShaderOrderingINTEL = {
+ "supportsFragmentShaderOrderingINTEL", FeatureCategory::OpenGLFeatures,
+ "Backend GL context supports GL_INTEL_fragment_shader_ordering extension", &members,
+ "http://anglebug.com/7279"};
+
+ FeatureInfo supportsFragmentShaderInterlockARB = {
+ "supportsFragmentShaderInterlockARB", FeatureCategory::OpenGLFeatures,
+ "Backend GL context supports ARB_fragment_shader_interlock extension", &members,
+ "http://anglebug.com/7279"};
+
+ FeatureInfo supportsShaderFramebufferFetchEXT = {
+ "supportsShaderFramebufferFetchEXT", FeatureCategory::OpenGLFeatures,
+ "Backend GL context supports EXT_shader_framebuffer_fetch extension", &members,
+ "http://anglebug.com/7279"};
+
+ FeatureInfo supportsShaderFramebufferFetchNonCoherentEXT = {
+ "supportsShaderFramebufferFetchNonCoherentEXT", FeatureCategory::OpenGLFeatures,
+ "Backend GL context supports EXT_shader_framebuffer_fetch_non_coherent extension", &members,
+ "http://anglebug.com/7279"};
+};
+
+inline FeaturesGL::FeaturesGL() = default;
+inline FeaturesGL::~FeaturesGL() = default;
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_FEATURESGL_H_
diff --git a/gfx/angle/checkout/include/platform/FeaturesMtl_autogen.h b/gfx/angle/checkout/include/platform/FeaturesMtl_autogen.h
new file mode 100644
index 0000000000..116a0ee8d7
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/FeaturesMtl_autogen.h
@@ -0,0 +1,242 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_features.py using data from mtl_features.json.
+//
+// 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.
+//
+// FeaturesMtl_autogen.h: Optional features for the Metal renderer.
+
+#ifndef ANGLE_PLATFORM_FEATURESMTL_H_
+#define ANGLE_PLATFORM_FEATURESMTL_H_
+
+#include "platform/Feature.h"
+
+namespace angle
+{
+
+struct FeaturesMtl : FeatureSetBase
+{
+ FeaturesMtl();
+ ~FeaturesMtl();
+
+ FeatureInfo hasBaseVertexInstancedDraw = {
+ "hasBaseVertexInstancedDraw",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports base vertex instanced draw",
+ &members,
+ };
+
+ FeatureInfo hasExplicitMemBarrier = {
+ "hasExplicitMemBarrier",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports explicit memory barrier",
+ &members,
+ };
+
+ FeatureInfo hasCheapRenderPass = {
+ "hasCheapRenderPass",
+ FeatureCategory::MetalFeatures,
+ "The renderer can cheaply break a render pass.",
+ &members,
+ };
+
+ FeatureInfo hasNonUniformDispatch = {
+ "hasNonUniformDispatch",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports non uniform compute shader dispatch's group size",
+ &members,
+ };
+
+ FeatureInfo hasShaderStencilOutput = {
+ "hasShaderStencilOutput",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports stencil output from fragment shader",
+ &members,
+ };
+
+ FeatureInfo hasTextureSwizzle = {
+ "hasTextureSwizzle",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports texture swizzle",
+ &members,
+ };
+
+ FeatureInfo hasDepthAutoResolve = {
+ "hasDepthAutoResolve",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports MSAA depth auto resolve at the end of render pass",
+ &members,
+ };
+
+ FeatureInfo hasStencilAutoResolve = {
+ "hasStencilAutoResolve",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports MSAA stencil auto resolve at the end of render pass",
+ &members,
+ };
+
+ FeatureInfo hasEvents = {
+ "hasEvents",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports MTL(Shared)Event",
+ &members,
+ };
+
+ FeatureInfo allowInlineConstVertexData = {
+ "allowInlineConstVertexData",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports using inline constant data for small client vertex data",
+ &members,
+ };
+
+ FeatureInfo allowSeparateDepthStencilBuffers = {
+ "allowSeparateDepthStencilBuffers",
+ FeatureCategory::MetalFeatures,
+ "Some Apple platforms such as iOS allows separate depth and stencil buffers, "
+ "whereas others such as macOS don't",
+ &members,
+ };
+
+ FeatureInfo allowRuntimeSamplerCompareMode = {
+ "allowRuntimeSamplerCompareMode",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports changing sampler's compare mode outside shaders",
+ &members,
+ };
+
+ FeatureInfo allowSamplerCompareGradient = {
+ "allowSamplerCompareGradient",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports sample_compare with gradients",
+ &members,
+ };
+
+ FeatureInfo allowSamplerCompareLod = {
+ "allowSamplerCompareLod",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports sample_compare with lod",
+ &members,
+ };
+
+ FeatureInfo allowBufferReadWrite = {
+ "allowBufferReadWrite",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports buffer read and write in the same shader",
+ &members,
+ };
+
+ FeatureInfo allowMultisampleStoreAndResolve = {
+ "allowMultisampleStoreAndResolve",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports MSAA store and resolve in the same pass",
+ &members,
+ };
+
+ FeatureInfo allowGenMultipleMipsPerPass = {
+ "allowGenMultipleMipsPerPass",
+ FeatureCategory::MetalFeatures,
+ "The renderer supports generating multiple mipmaps per pass",
+ &members,
+ };
+
+ FeatureInfo forceD24S8AsUnsupported = {
+ "forceD24S8AsUnsupported",
+ FeatureCategory::MetalFeatures,
+ "Force Depth24Stencil8 format as unsupported.",
+ &members,
+ };
+
+ FeatureInfo forceBufferGPUStorage = {
+ "forceBufferGPUStorage",
+ FeatureCategory::MetalFeatures,
+ "On systems that support both buffer' memory allocation on GPU and shared memory (such as "
+ "macOS), force using GPU memory allocation for buffers everytime or not.",
+ &members,
+ };
+
+ FeatureInfo directMetalGeneration = {"directMetalGeneration", FeatureCategory::MetalFeatures,
+ "Direct translation to Metal.", &members,
+ "http://anglebug.com/5505"};
+
+ FeatureInfo forceNonCSBaseMipmapGeneration = {
+ "forceNonCSBaseMipmapGeneration",
+ FeatureCategory::MetalFeatures,
+ "Turn this feature on to disallow Compute Shader based mipmap generation. Compute Shader "
+ "based mipmap generation might cause GPU hang on some older iOS devices.",
+ &members,
+ };
+
+ FeatureInfo emulateTransformFeedback = {
+ "emulateTransformFeedback",
+ FeatureCategory::MetalFeatures,
+ "Turn this on to allow transform feedback in Metal using a 2-pass VS for GLES3.",
+ &members,
+ };
+
+ FeatureInfo rewriteRowMajorMatrices = {
+ "rewriteRowMajorMatrices",
+ FeatureCategory::MetalFeatures,
+ "Rewrite row major matrices in shaders as column major.",
+ &members,
+ };
+
+ FeatureInfo intelExplicitBoolCastWorkaround = {
+ "intelExplicitBoolCastWorkaround",
+ FeatureCategory::MetalWorkarounds,
+ "Insert explicit casts for float/double/unsigned/signed int on macOS 10.15 with Intel "
+ "driver",
+ &members,
+ };
+
+ FeatureInfo intelDisableFastMath = {
+ "intelDisableFastMath",
+ FeatureCategory::MetalWorkarounds,
+ "Disable fast math in atan and invariance cases when running below macOS 12.0",
+ &members,
+ };
+
+ FeatureInfo multisampleColorFormatShaderReadWorkaround = {
+ "multisampleColorFormatShaderReadWorkaround", FeatureCategory::MetalWorkarounds,
+ "Add shaderRead usage to some multisampled texture formats", &members,
+ "http://anglebug.com/7049"};
+
+ FeatureInfo copyIOSurfaceToNonIOSurfaceForReadOptimization = {
+ "copyIOSurfaceToNonIOSurfaceForReadOptimization", FeatureCategory::MetalWorkarounds,
+ "some GPUs are faster to read an IOSurface texture by first copying the texture to a "
+ "non-IOSurface texture",
+ &members, "http://anglebug.com/7117 http://anglebug.com/7573"};
+
+ FeatureInfo copyTextureToBufferForReadOptimization = {
+ "copyTextureToBufferForReadOptimization", FeatureCategory::MetalWorkarounds,
+ "some GPUs are faster to read a texture by first copying the texture to a buffer", &members,
+ "http://anglebug.com/7117"};
+
+ FeatureInfo limitMaxDrawBuffersForTesting = {
+ "limitMaxDrawBuffersForTesting", FeatureCategory::MetalFeatures,
+ "Used to check the backend works when the device's advertized limit is less than the "
+ "code's limit",
+ &members, "http://anglebug.com/7280"};
+
+ FeatureInfo limitMaxColorTargetBitsForTesting = {
+ "limitMaxColorTargetBitsForTesting", FeatureCategory::MetalFeatures,
+ "Metal iOS has a limit on the number of color target bits per pixel.", &members,
+ "http://anglebug.com/7280"};
+
+ FeatureInfo preemptivelyStartProvokingVertexCommandBuffer = {
+ "preemptivelyStartProvokingVertexCommandBuffer", FeatureCategory::MetalFeatures,
+ "AMD Metal Drivers appear to have a bug this works around", &members,
+ "http://anglebug.com/7635"};
+
+ FeatureInfo uploadDataToIosurfacesWithStagingBuffers = {
+ "uploadDataToIosurfacesWithStagingBuffers", FeatureCategory::MetalWorkarounds,
+ "When uploading data to IOSurface-backed textures, use a staging buffer.", &members,
+ "http://anglebug.com/7573"};
+};
+
+inline FeaturesMtl::FeaturesMtl() = default;
+inline FeaturesMtl::~FeaturesMtl() = default;
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_FEATURESMTL_H_
diff --git a/gfx/angle/checkout/include/platform/FeaturesVk_autogen.h b/gfx/angle/checkout/include/platform/FeaturesVk_autogen.h
new file mode 100644
index 0000000000..dadd64c49b
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/FeaturesVk_autogen.h
@@ -0,0 +1,786 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_features.py using data from vk_features.json.
+//
+// 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.
+//
+// FeaturesVk_autogen.h: Optional features for the Vulkan renderer.
+
+#ifndef ANGLE_PLATFORM_FEATURESVK_H_
+#define ANGLE_PLATFORM_FEATURESVK_H_
+
+#include "platform/Feature.h"
+
+namespace angle
+{
+
+struct FeaturesVk : FeatureSetBase
+{
+ FeaturesVk();
+ ~FeaturesVk();
+
+ FeatureInfo bresenhamLineRasterization = {
+ "bresenhamLineRasterization",
+ FeatureCategory::VulkanFeatures,
+ "Enable Bresenham line rasterization via VK_EXT_line_rasterization extension",
+ &members,
+ };
+
+ FeatureInfo provokingVertex = {
+ "provokingVertex",
+ FeatureCategory::VulkanFeatures,
+ "Enable provoking vertex mode via VK_EXT_provoking_vertex extension",
+ &members,
+ };
+
+ FeatureInfo forceFallbackFormat = {
+ "forceFallbackFormat",
+ FeatureCategory::VulkanWorkarounds,
+ "Force a fallback format for angle_end2end_tests",
+ &members,
+ };
+
+ FeatureInfo clampPointSize = {
+ "clampPointSize", FeatureCategory::VulkanWorkarounds,
+ "The point size range reported from the API is inconsistent with the actual behavior",
+ &members, "http://anglebug.com/2970"};
+
+ FeatureInfo depthClamping = {
+ "depthClamping", FeatureCategory::VulkanWorkarounds,
+ "The depth value is not clamped to [0,1] for floating point depth buffers.", &members,
+ "http://anglebug.com/3970"};
+
+ FeatureInfo mutableMipmapTextureUpload = {
+ "mutableMipmapTextureUpload", FeatureCategory::VulkanFeatures,
+ "Enable uploading the previously defined mutable mipmap texture.", &members,
+ "https://anglebug.com/7308"};
+
+ FeatureInfo supportsRenderpass2 = {
+ "supportsRenderpass2",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_create_renderpass2 extension",
+ &members,
+ };
+
+ FeatureInfo supportsIncrementalPresent = {
+ "supportsIncrementalPresent",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_incremental_present extension",
+ &members,
+ };
+
+ FeatureInfo supportsAndroidHardwareBuffer = {
+ "supportsAndroidHardwareBuffer",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_ANDROID_external_memory_android_hardware_buffer extension",
+ &members,
+ };
+
+ FeatureInfo supportsGGPFrameToken = {
+ "supportsGGPFrameToken",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_GGP_frame_token extension",
+ &members,
+ };
+
+ FeatureInfo supportsExternalMemoryFd = {
+ "supportsExternalMemoryFd",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_external_memory_fd extension",
+ &members,
+ };
+
+ FeatureInfo supportsExternalMemoryFuchsia = {
+ "supportsExternalMemoryFuchsia",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_FUCHSIA_external_memory extension",
+ &members,
+ };
+
+ FeatureInfo supportsFilteringPrecision = {
+ "supportsFilteringPrecision",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_GOOGLE_sampler_filtering_precision extension",
+ &members,
+ };
+
+ FeatureInfo supportsExternalFenceCapabilities = {
+ "supportsExternalFenceCapabilities",
+ FeatureCategory::VulkanFeatures,
+ "VkInstance supports the VK_KHR_external_fence_capabilities extension",
+ &members,
+ };
+
+ FeatureInfo supportsExternalSemaphoreCapabilities = {
+ "supportsExternalSemaphoreCapabilities",
+ FeatureCategory::VulkanFeatures,
+ "VkInstance supports the VK_KHR_external_semaphore_capabilities extension",
+ &members,
+ };
+
+ FeatureInfo supportsExternalSemaphoreFd = {
+ "supportsExternalSemaphoreFd",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_external_semaphore_fd extension",
+ &members,
+ };
+
+ FeatureInfo supportsExternalSemaphoreFuchsia = {
+ "supportsExternalSemaphoreFuchsia",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_FUCHSIA_external_semaphore extension",
+ &members,
+ };
+
+ FeatureInfo supportsExternalFenceFd = {
+ "supportsExternalFenceFd", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_external_fence_fd extension", &members,
+ "http://anglebug.com/2517"};
+
+ FeatureInfo supportsAndroidNativeFenceSync = {
+ "supportsAndroidNativeFenceSync", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the EGL_ANDROID_native_fence_sync extension", &members,
+ "http://anglebug.com/2517"};
+
+ FeatureInfo supportsImageCubeArray = {"supportsImageCubeArray", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the imageCubeArray feature properly",
+ &members, "http://anglebug.com/3584"};
+
+ FeatureInfo supportsPipelineStatisticsQuery = {
+ "supportsPipelineStatisticsQuery", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the pipelineStatisticsQuery feature", &members,
+ "http://anglebug.com/5430"};
+
+ FeatureInfo supportsShaderStencilExport = {
+ "supportsShaderStencilExport",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_shader_stencil_export extension",
+ &members,
+ };
+
+ FeatureInfo supportsYUVSamplerConversion = {
+ "supportsYUVSamplerConversion",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_sampler_ycbcr_conversion extension",
+ &members,
+ };
+
+ FeatureInfo emulateTransformFeedback = {
+ "emulateTransformFeedback", FeatureCategory::VulkanFeatures,
+ "Emulate transform feedback as the VK_EXT_transform_feedback is not present.", &members,
+ "http://anglebug.com/3205"};
+
+ FeatureInfo supportsTransformFeedbackExtension = {
+ "supportsTransformFeedbackExtension", FeatureCategory::VulkanFeatures,
+ "Transform feedback uses the VK_EXT_transform_feedback extension.", &members,
+ "http://anglebug.com/3206"};
+
+ FeatureInfo supportsGeometryStreamsCapability = {
+ "supportsGeometryStreamsCapability", FeatureCategory::VulkanFeatures,
+ "Implementation supports the GeometryStreams SPIR-V capability.", &members,
+ "http://anglebug.com/3206"};
+
+ FeatureInfo supportsIndexTypeUint8 = {"supportsIndexTypeUint8", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_index_type_uint8 extension",
+ &members, "http://anglebug.com/4405"};
+
+ FeatureInfo supportsCustomBorderColor = {
+ "supportsCustomBorderColor", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_custom_border_color extension", &members,
+ "http://anglebug.com/3577"};
+
+ FeatureInfo supportsMultiDrawIndirect = {
+ "supportsMultiDrawIndirect", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the multiDrawIndirect extension", &members, "http://anglebug.com/6439"};
+
+ FeatureInfo supportsDepthStencilResolve = {"supportsDepthStencilResolve",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_depth_stencil_resolve "
+ "extension with the independentResolveNone feature",
+ &members, "http://anglebug.com/4836"};
+
+ FeatureInfo supportsMultisampledRenderToSingleSampledGOOGLEX = {
+ "supportsMultisampledRenderToSingleSampledGOOGLEX", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_GOOGLEX_multisampled_render_to_single_sampled extension",
+ &members, "http://anglebug.com/4836"};
+
+ FeatureInfo supportsMultisampledRenderToSingleSampled = {
+ "supportsMultisampledRenderToSingleSampled", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_multisampled_render_to_single_sampled extension", &members,
+ "http://anglebug.com/4836"};
+
+ FeatureInfo supportsMultiview = {"supportsMultiview", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_multiview extension", &members,
+ "http://anglebug.com/6048"};
+
+ FeatureInfo disableFifoPresentMode = {
+ "disableFifoPresentMode", FeatureCategory::VulkanWorkarounds,
+ "VK_PRESENT_MODE_FIFO_KHR causes random timeouts", &members, "http://anglebug.com/3153"};
+
+ FeatureInfo forceD16TexFilter = {
+ "forceD16TexFilter", FeatureCategory::VulkanWorkarounds,
+ "VK_FORMAT_D16_UNORM does not support VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, "
+ "which prevents OES_depth_texture from being supported.",
+ &members, "http://anglebug.com/3452"};
+
+ FeatureInfo disableFlippingBlitWithCommand = {
+ "disableFlippingBlitWithCommand", FeatureCategory::VulkanWorkarounds,
+ "vkCmdBlitImage with flipped coordinates blits incorrectly.", &members,
+ "http://anglebug.com/3498"};
+
+ FeatureInfo perFrameWindowSizeQuery = {
+ "perFrameWindowSizeQuery", FeatureCategory::VulkanWorkarounds,
+ "Vulkan swapchain is not returning VK_ERROR_OUT_OF_DATE when window resizing", &members,
+ "http://anglebug.com/3623, http://anglebug.com/3624, http://anglebug.com/3625"};
+
+ FeatureInfo padBuffersToMaxVertexAttribStride = {
+ "padBuffersToMaxVertexAttribStride", FeatureCategory::VulkanWorkarounds,
+ "Vulkan considers vertex attribute accesses to count up to the last multiple of the "
+ "stride. This additional access supports AMD's robust buffer access implementation. "
+ "AMDVLK in particular will return incorrect values when the vertex access extends into "
+ "the range that would be the stride padding and the buffer is too small. "
+ "This workaround limits GL_MAX_VERTEX_ATTRIB_STRIDE to a maximum value and "
+ "pads up every buffer allocation size to be a multiple of the maximum stride.",
+ &members, "http://anglebug.com/4428"};
+
+ FeatureInfo supportsExternalMemoryDmaBufAndModifiers = {
+ "supportsExternalMemoryDmaBufAndModifiers", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_external_memory_dma_buf and VK_EXT_image_drm_format_modifier "
+ "extensions",
+ &members, "http://anglebug.com/6248"};
+
+ FeatureInfo supportsExternalMemoryHost = {
+ "supportsExternalMemoryHost",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_external_memory_host extension",
+ &members,
+ };
+
+ FeatureInfo allocateNonZeroMemory = {
+ "allocateNonZeroMemory", FeatureCategory::VulkanFeatures,
+ "Fill new allocations with non-zero values to flush out errors.", &members,
+ "http://anglebug.com/4384"};
+
+ FeatureInfo logMemoryReportCallbacks = {
+ "logMemoryReportCallbacks",
+ FeatureCategory::VulkanFeatures,
+ "Log each callback from VK_EXT_device_memory_report",
+ &members,
+ };
+
+ FeatureInfo logMemoryReportStats = {
+ "logMemoryReportStats",
+ FeatureCategory::VulkanFeatures,
+ "Log stats from VK_EXT_device_memory_report each swap",
+ &members,
+ };
+
+ FeatureInfo shadowBuffers = {
+ "shadowBuffers", FeatureCategory::VulkanFeatures,
+ "Allocate a shadow buffer for GL buffer objects to reduce glMap* latency.", &members,
+ "http://anglebug.com/4339"};
+
+ FeatureInfo preferCPUForBufferSubData = {
+ "preferCPUForBufferSubData", FeatureCategory::VulkanFeatures,
+ "Prefer use CPU to do bufferSubData instead of staged update.", &members,
+ "http://issuetracker.google.com/200067929"};
+
+ FeatureInfo persistentlyMappedBuffers = {
+ "persistentlyMappedBuffers", FeatureCategory::VulkanFeatures,
+ "Persistently map buffer memory to reduce map/unmap IOCTL overhead.", &members,
+ "http://anglebug.com/2162"};
+
+ FeatureInfo enablePreRotateSurfaces = {"enablePreRotateSurfaces",
+ FeatureCategory::VulkanFeatures,
+ "Enable Android pre-rotation for landscape applications",
+ &members, "http://anglebug.com/3502"};
+
+ FeatureInfo enablePrecisionQualifiers = {
+ "enablePrecisionQualifiers", FeatureCategory::VulkanFeatures,
+ "Enable precision qualifiers in shaders", &members, "http://anglebug.com/3078"};
+
+ FeatureInfo preferAggregateBarrierCalls = {
+ "preferAggregateBarrierCalls", FeatureCategory::VulkanWorkarounds,
+ "Single barrier call is preferred over multiple calls with "
+ "fine grained pipeline stage dependency information",
+ &members, "http://anglebug.com/4633"};
+
+ FeatureInfo preferSkippingInvalidateForEmulatedFormats = {
+ "preferSkippingInvalidateForEmulatedFormats", FeatureCategory::VulkanWorkarounds,
+ "Skipping invalidate is preferred for emulated formats that have extra channels over "
+ "re-clearing the image",
+ &members, "http://anglebug.com/6860"};
+
+ FeatureInfo asyncCommandQueue = {"asyncCommandQueue", FeatureCategory::VulkanFeatures,
+ "Use CommandQueue worker thread to dispatch work to GPU.",
+ &members, "http://anglebug.com/4324"};
+
+ FeatureInfo supportsShaderFloat16 = {
+ "supportsShaderFloat16", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_shader_float16_int8 extension "
+ "and has the shaderFloat16 feature",
+ &members, "http://anglebug.com/4551"};
+
+ FeatureInfo allowGenerateMipmapWithCompute = {
+ "allowGenerateMipmapWithCompute", FeatureCategory::VulkanFeatures,
+ "Use the compute path to generate mipmaps on devices that meet the minimum requirements, "
+ "and the performance is better.",
+ &members, "http://anglebug.com/4551"};
+
+ FeatureInfo supportsRenderPassStoreOpNone = {
+ "supportsRenderPassStoreOpNone", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_QCOM_render_pass_store_ops extension.", &members,
+ "http://anglebug.com/5055"};
+
+ FeatureInfo supportsRenderPassLoadStoreOpNone = {
+ "supportsRenderPassLoadStoreOpNone", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_load_store_op_none extension.", &members,
+ "http://anglebug.com/5371"};
+
+ FeatureInfo disallowMixedDepthStencilLoadOpNoneAndLoad = {
+ "disallowMixedDepthStencilLoadOpNoneAndLoad", FeatureCategory::VulkanWorkarounds,
+ "Disallow use of LOAD_OP_NONE for only one of the depth or stencil aspects of a "
+ "depth/stencil attachment",
+ &members, "http://anglebug.com/7370"};
+
+ FeatureInfo supportsDepthClipControl = {
+ "supportsDepthClipControl", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_depth_clip_control extension.", &members,
+ "http://anglebug.com/5421"};
+
+ FeatureInfo supportsPrimitiveTopologyListRestart = {
+ "supportsPrimitiveTopologyListRestart", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_primitive_topology_list_restart extension.", &members,
+ "http://anglebug.com/3832"};
+
+ FeatureInfo supportsBlendOperationAdvanced = {
+ "supportsBlendOperationAdvanced", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_blend_operation_advanced extension.", &members,
+ "http://anglebug.com/3586"};
+
+ FeatureInfo forceMaxUniformBufferSize16KB = {
+ "forceMaxUniformBufferSize16KB", FeatureCategory::VulkanWorkarounds,
+ "Force max uniform buffer size to 16K on some device due to bug", &members,
+ "https://issuetracker.google.com/161903006"};
+
+ FeatureInfo supportsImageFormatList = {
+ "supportsImageFormatList", FeatureCategory::VulkanFeatures,
+ "Enable VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT by default for ICDs "
+ "that support VK_KHR_image_format_list",
+ &members, "http://anglebug.com/5281"};
+
+ FeatureInfo enableMultisampledRenderToTexture = {
+ "enableMultisampledRenderToTexture", FeatureCategory::VulkanWorkarounds,
+ "Expose EXT_multisampled_render_to_texture", &members, "http://anglebug.com/4937"};
+
+ FeatureInfo deferFlushUntilEndRenderPass = {
+ "deferFlushUntilEndRenderPass", FeatureCategory::VulkanWorkarounds,
+ "Allow glFlush to be deferred until renderpass ends", &members,
+ "https://issuetracker.google.com/issues/166475273"};
+
+ FeatureInfo waitIdleBeforeSwapchainRecreation = {
+ "waitIdleBeforeSwapchainRecreation", FeatureCategory::VulkanWorkarounds,
+ "Before passing an oldSwapchain to VkSwapchainCreateInfoKHR, wait for queue to be idle. "
+ "Works around a bug on platforms which destroy oldSwapchain in vkCreateSwapchainKHR.",
+ &members, "http://anglebug.com/5061"};
+
+ FeatureInfo forceTextureLodOffset1 = {
+ "forceTextureLodOffset1",
+ FeatureCategory::VulkanWorkarounds,
+ "Increase the minimum texture level-of-detail by 1 when sampling.",
+ &members,
+ };
+
+ FeatureInfo forceTextureLodOffset2 = {
+ "forceTextureLodOffset2",
+ FeatureCategory::VulkanWorkarounds,
+ "Increase the minimum texture level-of-detail by 2 when sampling.",
+ &members,
+ };
+
+ FeatureInfo forceTextureLodOffset3 = {
+ "forceTextureLodOffset3",
+ FeatureCategory::VulkanWorkarounds,
+ "Increase the minimum texture level-of-detail by 3 when sampling.",
+ &members,
+ };
+
+ FeatureInfo forceTextureLodOffset4 = {
+ "forceTextureLodOffset4",
+ FeatureCategory::VulkanWorkarounds,
+ "Increase the minimum texture level-of-detail by 4 when sampling.",
+ &members,
+ };
+
+ FeatureInfo forceNearestFiltering = {
+ "forceNearestFiltering",
+ FeatureCategory::VulkanWorkarounds,
+ "Force nearest filtering when sampling.",
+ &members,
+ };
+
+ FeatureInfo forceNearestMipFiltering = {
+ "forceNearestMipFiltering",
+ FeatureCategory::VulkanWorkarounds,
+ "Force nearest mip filtering when sampling.",
+ &members,
+ };
+
+ FeatureInfo compressVertexData = {
+ "compressVertexData",
+ FeatureCategory::VulkanWorkarounds,
+ "Compress vertex data to smaller data types when "
+ "possible. Using this feature makes ANGLE non-conformant.",
+ &members,
+ };
+
+ FeatureInfo preferDrawClearOverVkCmdClearAttachments = {
+ "preferDrawClearOverVkCmdClearAttachments", FeatureCategory::VulkanWorkarounds,
+ "On some hardware, clear using a draw call instead of vkCmdClearAttachments in the middle "
+ "of render pass due to bugs",
+ &members, "https://issuetracker.google.com/166809097"};
+
+ FeatureInfo emulatedPrerotation90 = {"emulatedPrerotation90", FeatureCategory::VulkanFeatures,
+ "Emulate 90-degree prerotation.", &members,
+ "http://anglebug.com/4901"};
+
+ FeatureInfo emulatedPrerotation180 = {"emulatedPrerotation180", FeatureCategory::VulkanFeatures,
+ "Emulate 180-degree prerotation.", &members,
+ "http://anglebug.com/4901"};
+
+ FeatureInfo emulatedPrerotation270 = {"emulatedPrerotation270", FeatureCategory::VulkanFeatures,
+ "Emulate 270-degree prerotation.", &members,
+ "http://anglebug.com/4901"};
+
+ FeatureInfo generateSPIRVThroughGlslang = {
+ "generateSPIRVThroughGlslang", FeatureCategory::VulkanFeatures,
+ "Translate SPIR-V through glslang.", &members, "http://anglebug.com/4889"};
+
+ FeatureInfo preferDriverUniformOverSpecConst = {
+ "preferDriverUniformOverSpecConst", FeatureCategory::VulkanFeatures,
+ "Prefer using driver uniforms instead of specialization constants.", &members,
+ "http://anglebug.com/7406"};
+
+ FeatureInfo exposeNonConformantExtensionsAndVersions = {
+ "exposeNonConformantExtensionsAndVersions", FeatureCategory::VulkanWorkarounds,
+ "Expose GLES versions and extensions that are not conformant.", &members,
+ "http://anglebug.com/5375"};
+
+ FeatureInfo emulateR32fImageAtomicExchange = {
+ "emulateR32fImageAtomicExchange", FeatureCategory::VulkanWorkarounds,
+ "Emulate r32f images with r32ui to support imageAtomicExchange.", &members,
+ "http://anglebug.com/5535"};
+
+ FeatureInfo supportsNegativeViewport = {
+ "supportsNegativeViewport",
+ FeatureCategory::VulkanFeatures,
+ "The driver supports inverting the viewport with a negative height.",
+ &members,
+ };
+
+ FeatureInfo forceFragmentShaderPrecisionHighpToMediump = {
+ "forceFragmentShaderPrecisionHighpToMediump", FeatureCategory::VulkanWorkarounds,
+ "Forces highp precision in fragment shader to mediump.", &members,
+ "https://issuetracker.google.com/184850002"};
+
+ FeatureInfo preferSubmitAtFBOBoundary = {
+ "preferSubmitAtFBOBoundary", FeatureCategory::VulkanWorkarounds,
+ "Submit commands to driver at each FBO boundary for performance improvements.", &members,
+ "https://issuetracker.google.com/187425444"};
+
+ FeatureInfo useMultipleDescriptorsForExternalFormats = {
+ "useMultipleDescriptorsForExternalFormats", FeatureCategory::VulkanWorkarounds,
+ "Return a default descriptor count for external formats.", &members,
+ "http://anglebug.com/6141"};
+
+ FeatureInfo supportsProtectedMemory = {
+ "supportsProtectedMemory", FeatureCategory::VulkanFeatures,
+ "VkDevice supports protected memory", &members, "http://anglebug.com/3965"};
+
+ FeatureInfo supportsHostQueryReset = {"supportsHostQueryReset", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_host_query_reset extension",
+ &members, "http://anglebug.com/6692"};
+
+ FeatureInfo supportsPipelineCreationCacheControl = {
+ "supportsPipelineCreationCacheControl", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_pipeline_creation_cache_control extension", &members,
+ "http://anglebug.com/5881"};
+
+ FeatureInfo supportsPipelineCreationFeedback = {
+ "supportsPipelineCreationFeedback", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_pipeline_creation_feedback extension", &members,
+ "http://anglebug.com/5881"};
+
+ FeatureInfo supportsPrimitivesGeneratedQuery = {
+ "supportsPrimitivesGeneratedQuery", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_primitives_generated_query extension", &members,
+ "http://anglebug.com/5430"};
+
+ FeatureInfo supportsSurfaceCapabilities2Extension = {
+ "supportsSurfaceCapabilities2Extension",
+ FeatureCategory::VulkanFeatures,
+ "VkInstance supports the VK_KHR_get_surface_capabilities2 extension",
+ &members,
+ };
+
+ FeatureInfo supportsSurfaceProtectedCapabilitiesExtension = {
+ "supportsSurfaceProtectedCapabilitiesExtension",
+ FeatureCategory::VulkanFeatures,
+ "VkInstance supports the VK_KHR_surface_protected_capabilities extension",
+ &members,
+ };
+
+ FeatureInfo supportsSurfacelessQueryExtension = {
+ "supportsSurfacelessQueryExtension",
+ FeatureCategory::VulkanFeatures,
+ "VkInstance supports the VK_GOOGLE_surfaceless_query extension",
+ &members,
+ };
+
+ FeatureInfo supportsSurfaceProtectedSwapchains = {
+ "supportsSurfaceProtectedSwapchains",
+ FeatureCategory::VulkanFeatures,
+ "VkSurface supportsProtected for protected swapchains",
+ &members,
+ };
+
+ FeatureInfo overrideSurfaceFormatRGB8ToRGBA8 = {
+ "overrideSurfaceFormatRGB8ToRGBA8", FeatureCategory::VulkanWorkarounds,
+ "Override surface format GL_RGB8 to GL_RGBA8", &members, "http://anglebug.com/6651"};
+
+ FeatureInfo supportsSharedPresentableImageExtension = {
+ "supportsSharedPresentableImageExtension",
+ FeatureCategory::VulkanFeatures,
+ "VkSurface supports the VK_KHR_shared_presentable_images extension",
+ &members,
+ };
+
+ FeatureInfo supportsShaderFramebufferFetch = {
+ "supportsShaderFramebufferFetch",
+ FeatureCategory::VulkanFeatures,
+ "Whether the Vulkan backend supports coherent framebuffer fetch",
+ &members,
+ };
+
+ FeatureInfo supportsShaderFramebufferFetchNonCoherent = {
+ "supportsShaderFramebufferFetchNonCoherent",
+ FeatureCategory::VulkanFeatures,
+ "Whether the Vulkan backend supports non-coherent framebuffer fetch",
+ &members,
+ };
+
+ FeatureInfo permanentlySwitchToFramebufferFetchMode = {
+ "permanentlySwitchToFramebufferFetchMode",
+ FeatureCategory::VulkanFeatures,
+ "Whether the context should permanently switch to framebuffer fetch mode on first"
+ "encounter",
+ &members,
+ };
+
+ FeatureInfo supportsLockSurfaceExtension = {
+ "supportsLockSurfaceExtension",
+ FeatureCategory::VulkanFeatures,
+ "Surface supports the EGL_KHR_lock_surface3 extension",
+ &members,
+ };
+
+ FeatureInfo swapbuffersOnFlushOrFinishWithSingleBuffer = {
+ "swapbuffersOnFlushOrFinishWithSingleBuffer", FeatureCategory::VulkanFeatures,
+ "Bypass deferredFlush with calling swapbuffers on flush or finish when in Shared "
+ "Present mode",
+ &members, "http://anglebug.com/6878"};
+
+ FeatureInfo emulateDithering = {"emulateDithering", FeatureCategory::VulkanFeatures,
+ "Emulate OpenGL dithering", &members,
+ "http://anglebug.com/6755"};
+
+ FeatureInfo roundOutputAfterDithering = {
+ "roundOutputAfterDithering", FeatureCategory::VulkanWorkarounds,
+ "Round output after dithering to workaround a driver bug that rounds the output up",
+ &members, "http://anglebug.com/6953"};
+
+ FeatureInfo emulateAdvancedBlendEquations = {
+ "emulateAdvancedBlendEquations", FeatureCategory::VulkanFeatures,
+ "Emulate GL_KHR_blend_equation_advanced", &members, "http://anglebug.com/3586"};
+
+ FeatureInfo precisionSafeDivision = {
+ "precisionSafeDivision",
+ FeatureCategory::VulkanWorkarounds,
+ "Special case handling for platforms that do not generate 1.0f even when the dividend and"
+ "divisor have the same value",
+ &members,
+ };
+
+ FeatureInfo bottomLeftOriginPresentRegionRectangles = {
+ "bottomLeftOriginPresentRegionRectangles",
+ FeatureCategory::VulkanWorkarounds,
+ "On some platforms present region rectangles are expected to have a bottom-left origin, "
+ "instead of top-left origin as from spec",
+ &members,
+ };
+
+ FeatureInfo forceSubmitImmutableTextureUpdates = {
+ "forceSubmitImmutableTextureUpdates", FeatureCategory::VulkanAppWorkarounds,
+ "Force submit updates to immutable textures", &members, "http://anglebug.com/6929"};
+
+ FeatureInfo retainSPIRVDebugInfo = {"retainSPIRVDebugInfo", FeatureCategory::VulkanFeatures,
+ "Retain debug info in SPIR-V blob.", &members,
+ "http://anglebug.com/5901"};
+
+ FeatureInfo warmUpPipelineCacheAtLink = {
+ "warmUpPipelineCacheAtLink", FeatureCategory::VulkanFeatures,
+ "Warm up the Vulkan pipeline cache at link time", &members, "http://anglebug.com/5881"};
+
+ FeatureInfo preferDeviceLocalMemoryHostVisible = {
+ "preferDeviceLocalMemoryHostVisible", FeatureCategory::VulkanFeatures,
+ "Prefer adding HOST_VISIBLE flag for DEVICE_LOCAL memory when picking memory types",
+ &members, "http://anglebug.com/7047"};
+
+ FeatureInfo forceStaticVertexStrideState = {
+ "forceStaticVertexStrideState", FeatureCategory::VulkanWorkarounds,
+ "Force static state for VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT due to"
+ "driver bugs",
+ &members, "https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=107106"};
+
+ FeatureInfo supportsExtendedDynamicState = {
+ "supportsExtendedDynamicState", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_extended_dynamic_state extension", &members,
+ "http://anglebug.com/5906"};
+
+ FeatureInfo supportsExtendedDynamicState2 = {
+ "supportsExtendedDynamicState2", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_extended_dynamic_state2 extension", &members,
+ "http://anglebug.com/5906"};
+
+ FeatureInfo supportsLogicOpDynamicState = {
+ "supportsLogicOpDynamicState", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the logicOp feature of VK_EXT_extended_dynamic_state2 extension",
+ &members, "http://anglebug.com/3862"};
+
+ FeatureInfo supportsFragmentShadingRate = {
+ "supportsFragmentShadingRate", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_KHR_fragment_shading_rate extension", &members,
+ "http://anglebug.com/7172"};
+
+ FeatureInfo supportsFragmentShaderPixelInterlock = {
+ "supportsFragmentShaderPixelInterlock",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_fragment_shader_interlock extension "
+ "and has the fragmentShaderPixelInterlock feature",
+ &members,
+ };
+
+ FeatureInfo explicitlyEnablePerSampleShading = {
+ "explicitlyEnablePerSampleShading", FeatureCategory::VulkanWorkarounds,
+ "Explicitly enable per-sample shading if the fragment shader contains the "
+ "sample qualifier",
+ &members, "http://anglebug.com/6876"};
+
+ FeatureInfo forceContinuousRefreshOnSharedPresent = {
+ "forceContinuousRefreshOnSharedPresent", FeatureCategory::VulkanFeatures,
+ "Force to create vulkan swapchain with continuous refresh on shared present", &members,
+ "https://issuetracker.google.com/229267970"};
+
+ FeatureInfo supportsImage2dViewOf3d = {
+ "supportsImage2dViewOf3d", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_image_2d_view_of_3d", &members, "https://anglebug.com/7320"};
+
+ FeatureInfo supportsImagelessFramebuffer = {
+ "supportsImagelessFramebuffer", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_KHR_imageless_framebuffer extension", &members,
+ "http://anglebug.com/7553"};
+
+ FeatureInfo preferLinearFilterForYUV = {
+ "preferLinearFilterForYUV", FeatureCategory::VulkanFeatures,
+ "Prefer to use VK_FILTER_LINEAR for VkSamplerYcbcrConversion", &members,
+ "https://anglebug.com/7382"};
+
+ FeatureInfo supportsYuvTarget = {
+ "supportsYuvTarget",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_ANDROID_render_to_external_format and VK_EXT_ycbcr_attachment",
+ &members,
+ };
+
+ FeatureInfo useNonZeroStencilWriteMaskStaticState = {
+ "useNonZeroStencilWriteMaskStaticState", FeatureCategory::VulkanWorkarounds,
+ "Work around a driver bug where 0 in stencil write mask static state would make the"
+ "corresponding dynamic state malfunction in the presence of discard or alpha to coverage",
+ &members, "http://anglebug.com/7556"};
+
+ FeatureInfo mapUnspecifiedColorSpaceToPassThrough = {
+ "mapUnspecifiedColorSpaceToPassThrough",
+ FeatureCategory::VulkanFeatures,
+ "Use VK_COLOR_SPACE_PASS_THROUGH_EXT for EGL_NONE or unspecifed color "
+ "spaces",
+ &members,
+ };
+
+ FeatureInfo supportsTimestampSurfaceAttribute = {
+ "supportsTimestampSurfaceAttribute", FeatureCategory::VulkanFeatures,
+ "Platform supports setting frame timestamp surface attribute", &members,
+ "https://anglebug.com/7489"};
+
+ FeatureInfo supportsRasterizationOrderAttachmentAccess = {
+ "supportsRasterizationOrderAttachmentAccess", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_rasterization_order_attachment_access extension", &members,
+ "https://anglebug.com/7604"};
+
+ FeatureInfo eglColorspaceAttributePassthrough = {
+ "eglColorspaceAttributePassthrough", FeatureCategory::VulkanFeatures,
+ "Support passthrough of EGL colorspace attribute values", &members,
+ "https://anglebug.com/7319"};
+
+ FeatureInfo supportsPipelineRobustness = {
+ "supportsPipelineRobustness", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_pipeline_robustness extension", &members,
+ "https://anglebug.com/5845"};
+
+ FeatureInfo supportsVertexInputDynamicState = {
+ "supportsVertexInputDynamicState", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_vertex_input_dynamic_state extension", &members,
+ "https://anglebug.com/7162"};
+
+ FeatureInfo supportsColorWriteEnable = {"supportsColorWriteEnable",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_EXT_color_write_enable extension",
+ &members, "https://anglebug.com/7161"};
+
+ FeatureInfo supportsPresentation = {
+ "supportsPresentation",
+ FeatureCategory::VulkanFeatures,
+ "VkDisplay supports presentation through a present family queue",
+ &members,
+ };
+
+ FeatureInfo supportsComputeTranscodeEtcToBc = {
+ "supportsComputeTranscodeEtcToBc",
+ FeatureCategory::VulkanFeatures,
+ "supports compute shader transcode etc format to bc format",
+ &members,
+ };
+
+ FeatureInfo supportsGraphicsPipelineLibrary = {
+ "supportsGraphicsPipelineLibrary", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_graphics_pipeline_library extension", &members,
+ "https://anglebug.com/7369"};
+
+ FeatureInfo supportsPipelineProtectedAccess = {
+ "supportsPipelineProtectedAccess", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_pipeline_protected_access extension", &members,
+ "https://anglebug.com/7714"};
+
+ FeatureInfo preferSubmitOnAnySamplesPassedQueryEnd = {
+ "preferSubmitOnAnySamplesPassedQueryEnd", FeatureCategory::VulkanWorkarounds,
+ "Submit commands to driver when last GL_ANY_SAMPLES_PASSED query is made for performance "
+ "improvements.",
+ &members, "https://issuetracker.google.com/250706693"};
+};
+
+inline FeaturesVk::FeaturesVk() = default;
+inline FeaturesVk::~FeaturesVk() = default;
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_FEATURESVK_H_
diff --git a/gfx/angle/checkout/include/platform/FrontendFeatures_autogen.h b/gfx/angle/checkout/include/platform/FrontendFeatures_autogen.h
new file mode 100644
index 0000000000..4cb5fa8afa
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/FrontendFeatures_autogen.h
@@ -0,0 +1,115 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_features.py using data from frontend_features.json.
+//
+// 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.
+//
+// FrontendFeatures_autogen.h: Features/workarounds for driver bugs and other behaviors seen
+// on all platforms.
+
+#ifndef ANGLE_PLATFORM_FRONTENDFEATURES_H_
+#define ANGLE_PLATFORM_FRONTENDFEATURES_H_
+
+#include "platform/Feature.h"
+
+namespace angle
+{
+
+struct FrontendFeatures : FeatureSetBase
+{
+ FrontendFeatures();
+ ~FrontendFeatures();
+
+ FeatureInfo loseContextOnOutOfMemory = {
+ "loseContextOnOutOfMemory",
+ FeatureCategory::FrontendWorkarounds,
+ "Some users rely on a lost context notification if a GL_OUT_OF_MEMORY error occurs",
+ &members,
+ };
+
+ FeatureInfo disableProgramCachingForTransformFeedback = {
+ "disableProgramCachingForTransformFeedback",
+ FeatureCategory::FrontendWorkarounds,
+ "On some GPUs, program binaries don't contain transform feedback varyings",
+ &members,
+ };
+
+ FeatureInfo scalarizeVecAndMatConstructorArgs = {
+ "scalarizeVecAndMatConstructorArgs", FeatureCategory::FrontendWorkarounds,
+ "Always rewrite vec/mat constructors to be consistent", &members,
+ "http://crbug.com/1165751"};
+
+ FeatureInfo disableProgramBinary = {"disableProgramBinary", FeatureCategory::FrontendFeatures,
+ "Disable support for GL_OES_get_program_binary", &members,
+ "http://anglebug.com/5007"};
+
+ FeatureInfo disableDrawBuffersIndexed = {
+ "disableDrawBuffersIndexed", FeatureCategory::FrontendFeatures,
+ "Disable support for OES_draw_buffers_indexed and EXT_draw_buffers_indexed", &members,
+ "http://anglebug.com/7724"};
+
+ FeatureInfo disableAnisotropicFiltering = {
+ "disableAnisotropicFiltering",
+ FeatureCategory::FrontendWorkarounds,
+ "Disable support for anisotropic filtering",
+ &members,
+ };
+
+ FeatureInfo allowCompressedFormats = {
+ "allowCompressedFormats",
+ FeatureCategory::FrontendWorkarounds,
+ "Allow compressed formats",
+ &members,
+ };
+
+ FeatureInfo forceDepthAttachmentInitOnClear = {
+ "forceDepthAttachmentInitOnClear", FeatureCategory::FrontendWorkarounds,
+ "Force depth attachment initialization on clear ops", &members,
+ "https://anglebug.com/7246"};
+
+ FeatureInfo enableCaptureLimits = {"enableCaptureLimits", FeatureCategory::FrontendFeatures,
+ "Set the context limits like frame capturing was enabled",
+ &members, "http://anglebug.com/5750"};
+
+ FeatureInfo enableCompressingPipelineCacheInThreadPool = {
+ "enableCompressingPipelineCacheInThreadPool", FeatureCategory::FrontendWorkarounds,
+ "Enable compressing pipeline cache in thread pool.", &members, "http://anglebug.com/4722"};
+
+ FeatureInfo forceRobustResourceInit = {
+ "forceRobustResourceInit", FeatureCategory::FrontendFeatures,
+ "Force-enable robust resource init", &members, "http://anglebug.com/6041"};
+
+ FeatureInfo forceInitShaderVariables = {
+ "forceInitShaderVariables",
+ FeatureCategory::FrontendFeatures,
+ "Force-enable shader variable initialization",
+ &members,
+ };
+
+ FeatureInfo enableProgramBinaryForCapture = {
+ "enableProgramBinaryForCapture", FeatureCategory::FrontendFeatures,
+ "Even if FrameCapture is enabled, enable GL_OES_get_program_binary", &members,
+ "http://anglebug.com/5658"};
+
+ FeatureInfo forceGlErrorChecking = {
+ "forceGlErrorChecking", FeatureCategory::FrontendFeatures,
+ "Force GL error checking (i.e. prevent applications from disabling error checking",
+ &members, "https://issuetracker.google.com/220069903"};
+
+ FeatureInfo emulatePixelLocalStorage = {
+ "emulatePixelLocalStorage", FeatureCategory::FrontendFeatures,
+ "Emulate ANGLE_shader_pixel_local_storage using shader images", &members,
+ "http://anglebug.com/7279"};
+
+ FeatureInfo cacheCompiledShader = {"cacheCompiledShader", FeatureCategory::FrontendFeatures,
+ "Enable to cache compiled shaders", &members,
+ "http://anglebug.com/7036"};
+};
+
+inline FrontendFeatures::FrontendFeatures() = default;
+inline FrontendFeatures::~FrontendFeatures() = default;
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_FRONTENDFEATURES_H_
diff --git a/gfx/angle/checkout/include/platform/PlatformMethods.h b/gfx/angle/checkout/include/platform/PlatformMethods.h
new file mode 100644
index 0000000000..48ef335796
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/PlatformMethods.h
@@ -0,0 +1,334 @@
+//
+// 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.
+
+// PlatformMethods.h: The public interface ANGLE exposes to the API layer, for
+// doing platform-specific tasks like gathering data, or for tracing.
+
+#ifndef ANGLE_PLATFORMMETHODS_H
+#define ANGLE_PLATFORMMETHODS_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <array>
+
+#define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x6AFB
+
+#if !defined(ANGLE_PLATFORM_EXPORT)
+# if defined(_WIN32)
+# if !defined(LIBANGLE_IMPLEMENTATION)
+# define ANGLE_PLATFORM_EXPORT __declspec(dllimport)
+# else
+# define ANGLE_PLATFORM_EXPORT __declspec(dllexport)
+# endif
+# elif defined(__GNUC__) || defined(__clang__)
+# define ANGLE_PLATFORM_EXPORT __attribute__((visibility("default")))
+# endif
+#endif
+#if !defined(ANGLE_PLATFORM_EXPORT)
+# define ANGLE_PLATFORM_EXPORT
+#endif
+
+#if defined(_WIN32)
+# define ANGLE_APIENTRY __stdcall
+#else
+# define ANGLE_APIENTRY
+#endif
+
+namespace angle
+{
+struct FeaturesD3D;
+struct FeaturesVk;
+struct FeaturesMtl;
+using TraceEventHandle = uint64_t;
+using EGLDisplayType = void *;
+struct PlatformMethods;
+
+// Use a C-like API to not trigger undefined calling behaviour.
+// Avoid using decltype here to work around sanitizer limitations.
+// TODO(jmadill): Use decltype here if/when UBSAN is fixed.
+
+// System --------------------------------------------------------------
+
+// Wall clock time in seconds since the epoch.
+// TODO(jmadill): investigate using an ANGLE internal time library
+using CurrentTimeFunc = double (*)(PlatformMethods *platform);
+inline double DefaultCurrentTime(PlatformMethods *platform)
+{
+ return 0.0;
+}
+
+// Monotonically increasing time in seconds from an arbitrary fixed point in the past.
+// This function is expected to return at least millisecond-precision values. For this reason,
+// it is recommended that the fixed point be no further in the past than the epoch.
+using MonotonicallyIncreasingTimeFunc = double (*)(PlatformMethods *platform);
+inline double DefaultMonotonicallyIncreasingTime(PlatformMethods *platform)
+{
+ return 0.0;
+}
+
+// Logging ------------------------------------------------------------
+
+// Log an error message within the platform implementation.
+using LogErrorFunc = void (*)(PlatformMethods *platform, const char *errorMessage);
+inline void DefaultLogError(PlatformMethods *platform, const char *errorMessage) {}
+
+// Log a warning message within the platform implementation.
+using LogWarningFunc = void (*)(PlatformMethods *platform, const char *warningMessage);
+inline void DefaultLogWarning(PlatformMethods *platform, const char *warningMessage) {}
+
+// Log an info message within the platform implementation.
+using LogInfoFunc = void (*)(PlatformMethods *platform, const char *infoMessage);
+inline void DefaultLogInfo(PlatformMethods *platform, const char *infoMessage) {}
+
+// Tracing --------
+
+// Get a pointer to the enabled state of the given trace category. The
+// embedder can dynamically change the enabled state as trace event
+// recording is started and stopped by the application. Only long-lived
+// literal strings should be given as the category name. The implementation
+// expects the returned pointer to be held permanently in a local static. If
+// the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
+// addTraceEvent is expected to be called by the trace event macros.
+using GetTraceCategoryEnabledFlagFunc = const unsigned char *(*)(PlatformMethods *platform,
+ const char *categoryName);
+inline const unsigned char *DefaultGetTraceCategoryEnabledFlag(PlatformMethods *platform,
+ const char *categoryName)
+{
+ return nullptr;
+}
+
+//
+// Add a trace event to the platform tracing system. Depending on the actual
+// enabled state, this event may be recorded or dropped.
+// - phase specifies the type of event:
+// - BEGIN ('B'): Marks the beginning of a scoped event.
+// - END ('E'): Marks the end of a scoped event.
+// - COMPLETE ('X'): Marks the beginning of a scoped event, but doesn't
+// need a matching END event. Instead, at the end of the scope,
+// updateTraceEventDuration() must be called with the TraceEventHandle
+// returned from addTraceEvent().
+// - INSTANT ('I'): Standalone, instantaneous event.
+// - START ('S'): Marks the beginning of an asynchronous event (the end
+// event can occur in a different scope or thread). The id parameter is
+// used to match START/FINISH pairs.
+// - FINISH ('F'): Marks the end of an asynchronous event.
+// - COUNTER ('C'): Used to trace integer quantities that change over
+// time. The argument values are expected to be of type int.
+// - METADATA ('M'): Reserved for internal use.
+// - categoryEnabled is the pointer returned by getTraceCategoryEnabledFlag.
+// - name is the name of the event. Also used to match BEGIN/END and
+// START/FINISH pairs.
+// - id optionally allows events of the same name to be distinguished from
+// each other. For example, to trace the construction and destruction of
+// objects, specify the pointer as the id parameter.
+// - timestamp should be a time value returned from monotonicallyIncreasingTime.
+// - numArgs specifies the number of elements in argNames, argTypes, and
+// argValues.
+// - argNames is the array of argument names. Use long-lived literal strings
+// or specify the COPY flag.
+// - argTypes is the array of argument types:
+// - BOOL (1): bool
+// - UINT (2): unsigned long long
+// - INT (3): long long
+// - DOUBLE (4): double
+// - POINTER (5): void*
+// - STRING (6): char* (long-lived null-terminated char* string)
+// - COPY_STRING (7): char* (temporary null-terminated char* string)
+// - CONVERTABLE (8): WebConvertableToTraceFormat
+// - argValues is the array of argument values. Each value is the unsigned
+// long long member of a union of all supported types.
+// - flags can be 0 or one or more of the following, ORed together:
+// - COPY (0x1): treat all strings (name, argNames and argValues of type
+// string) as temporary so that they will be copied by addTraceEvent.
+// - HAS_ID (0x2): use the id argument to uniquely identify the event for
+// matching with other events of the same name.
+// - MANGLE_ID (0x4): specify this flag if the id parameter is the value
+// of a pointer.
+using AddTraceEventFunc = angle::TraceEventHandle (*)(PlatformMethods *platform,
+ char phase,
+ const unsigned char *categoryEnabledFlag,
+ const char *name,
+ unsigned long long id,
+ double timestamp,
+ int numArgs,
+ const char **argNames,
+ const unsigned char *argTypes,
+ const unsigned long long *argValues,
+ unsigned char flags);
+inline angle::TraceEventHandle DefaultAddTraceEvent(PlatformMethods *platform,
+ char phase,
+ const unsigned char *categoryEnabledFlag,
+ const char *name,
+ unsigned long long id,
+ double timestamp,
+ int numArgs,
+ const char **argNames,
+ const unsigned char *argTypes,
+ const unsigned long long *argValues,
+ unsigned char flags)
+{
+ return 0;
+}
+
+// Set the duration field of a COMPLETE trace event.
+using UpdateTraceEventDurationFunc = void (*)(PlatformMethods *platform,
+ const unsigned char *categoryEnabledFlag,
+ const char *name,
+ angle::TraceEventHandle eventHandle);
+inline void DefaultUpdateTraceEventDuration(PlatformMethods *platform,
+ const unsigned char *categoryEnabledFlag,
+ const char *name,
+ angle::TraceEventHandle eventHandle)
+{}
+
+// Callbacks for reporting histogram data.
+// CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50
+// would do.
+using HistogramCustomCountsFunc = void (*)(PlatformMethods *platform,
+ const char *name,
+ int sample,
+ int min,
+ int max,
+ int bucketCount);
+inline void DefaultHistogramCustomCounts(PlatformMethods *platform,
+ const char *name,
+ int sample,
+ int min,
+ int max,
+ int bucketCount)
+{}
+// Enumeration histogram buckets are linear, boundaryValue should be larger than any possible sample
+// value.
+using HistogramEnumerationFunc = void (*)(PlatformMethods *platform,
+ const char *name,
+ int sample,
+ int boundaryValue);
+inline void DefaultHistogramEnumeration(PlatformMethods *platform,
+ const char *name,
+ int sample,
+ int boundaryValue)
+{}
+// Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets.
+using HistogramSparseFunc = void (*)(PlatformMethods *platform, const char *name, int sample);
+inline void DefaultHistogramSparse(PlatformMethods *platform, const char *name, int sample) {}
+// Boolean histograms track two-state variables.
+using HistogramBooleanFunc = void (*)(PlatformMethods *platform, const char *name, bool sample);
+inline void DefaultHistogramBoolean(PlatformMethods *platform, const char *name, bool sample) {}
+
+// Callback on a successful program link with the program binary. Can be used to store
+// shaders to disk. Keys are a 160-bit SHA-1 hash.
+using ProgramKeyType = std::array<uint8_t, 20>;
+using CacheProgramFunc = void (*)(PlatformMethods *platform,
+ const ProgramKeyType &key,
+ size_t programSize,
+ const uint8_t *programBytes);
+inline void DefaultCacheProgram(PlatformMethods *platform,
+ const ProgramKeyType &key,
+ size_t programSize,
+ const uint8_t *programBytes)
+{}
+
+using PostWorkerTaskCallback = void (*)(void *userData);
+using PostWorkerTaskFunc = void (*)(PlatformMethods *platform,
+ PostWorkerTaskCallback callback,
+ void *userData);
+constexpr PostWorkerTaskFunc DefaultPostWorkerTask = nullptr;
+
+// Placeholder values where feature override callbacks used to be. They are deprecated in favor of
+// EGL_ANGLE_feature_control. The placeholders are there to keep the layout of the PlatformMethods
+// constant to support drop-in replacement of ANGLE's .so files in applications built with an older
+// header.
+using PlaceholderCallbackFunc = void (*)(...);
+inline void DefaultPlaceholderCallback(...) {}
+
+// Platform methods are enumerated here once.
+#define ANGLE_PLATFORM_OP(OP) \
+ OP(currentTime, CurrentTime) \
+ OP(monotonicallyIncreasingTime, MonotonicallyIncreasingTime) \
+ OP(logError, LogError) \
+ OP(logWarning, LogWarning) \
+ OP(logInfo, LogInfo) \
+ OP(getTraceCategoryEnabledFlag, GetTraceCategoryEnabledFlag) \
+ OP(addTraceEvent, AddTraceEvent) \
+ OP(updateTraceEventDuration, UpdateTraceEventDuration) \
+ OP(histogramCustomCounts, HistogramCustomCounts) \
+ OP(histogramEnumeration, HistogramEnumeration) \
+ OP(histogramSparse, HistogramSparse) \
+ OP(histogramBoolean, HistogramBoolean) \
+ OP(placeholder1, PlaceholderCallback) \
+ OP(placeholder2, PlaceholderCallback) \
+ OP(cacheProgram, CacheProgram) \
+ OP(placeholder3, PlaceholderCallback) \
+ OP(postWorkerTask, PostWorkerTask)
+
+#define ANGLE_PLATFORM_METHOD_DEF(Name, CapsName) CapsName##Func Name = Default##CapsName;
+
+struct ANGLE_PLATFORM_EXPORT PlatformMethods
+{
+ inline PlatformMethods();
+
+ // User data pointer for any implementation specific members. Put it at the start of the
+ // platform structure so it doesn't become overwritten if one version of the platform
+ // adds or removes new members.
+ void *context = 0;
+
+ ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_DEF)
+};
+
+inline PlatformMethods::PlatformMethods() = default;
+
+#undef ANGLE_PLATFORM_METHOD_DEF
+
+// Subtract one to account for the context pointer.
+constexpr unsigned int g_NumPlatformMethods = (sizeof(PlatformMethods) / sizeof(uintptr_t)) - 1;
+
+// No further uses of platform methods is allowed. EGL extensions should be used instead. While
+// methods are being removed, use PlaceholderCallback to keep the layout of PlatformMethods
+// constant.
+static_assert(g_NumPlatformMethods == 17, "Avoid adding methods to PlatformMethods");
+
+#define ANGLE_PLATFORM_METHOD_STRING(Name) #Name
+#define ANGLE_PLATFORM_METHOD_STRING2(Name, CapsName) ANGLE_PLATFORM_METHOD_STRING(Name),
+
+constexpr const char *const g_PlatformMethodNames[g_NumPlatformMethods] = {
+ ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_STRING2)};
+
+#undef ANGLE_PLATFORM_METHOD_STRING2
+#undef ANGLE_PLATFORM_METHOD_STRING
+
+} // namespace angle
+
+extern "C" {
+
+// Gets the platform methods on the passed-in EGL display. If the method name signature does not
+// match the compiled signature for this ANGLE, false is returned. On success true is returned.
+// The application should set any platform methods it cares about on the returned pointer.
+// If display is not valid, behaviour is undefined.
+
+ANGLE_PLATFORM_EXPORT bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display,
+ const char *const methodNames[],
+ unsigned int methodNameCount,
+ void *context,
+ void *platformMethodsOut);
+
+// Sets the platform methods back to their defaults.
+// If display is not valid, behaviour is undefined.
+ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display);
+} // extern "C"
+
+namespace angle
+{
+typedef bool(ANGLE_APIENTRY *GetDisplayPlatformFunc)(angle::EGLDisplayType,
+ const char *const *,
+ unsigned int,
+ void *,
+ void *);
+typedef void(ANGLE_APIENTRY *ResetDisplayPlatformFunc)(angle::EGLDisplayType);
+} // namespace angle
+
+// This function is not exported
+angle::PlatformMethods *ANGLEPlatformCurrent();
+
+#endif // ANGLE_PLATFORMMETHODS_H
diff --git a/gfx/angle/checkout/include/vulkan/vulkan_fuchsia_ext.h b/gfx/angle/checkout/include/vulkan/vulkan_fuchsia_ext.h
new file mode 100644
index 0000000000..f5c3cf629b
--- /dev/null
+++ b/gfx/angle/checkout/include/vulkan/vulkan_fuchsia_ext.h
@@ -0,0 +1,31 @@
+//
+// 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.
+//
+// vulkan_fuchsia_ext:
+// Defines Fuchsia-specific Vulkan extensions when compiling on other
+// platforms.
+//
+
+#ifndef COMMON_VULKAN_FUCHSIA_EXT_H_
+#define COMMON_VULKAN_FUCHSIA_EXT_H_
+
+#if !defined(VK_NO_PROTOTYPES)
+# define VK_NO_PROTOTYPES
+#endif
+
+#include <vulkan/vulkan.h>
+
+// If this is not Fuchsia then define Fuchsia-specific types explicitly and include
+// vulkan_fuchsia.h to make it possible to compile the code on other platforms.
+//
+// TODO(https://anglebug.com/6040): Update all code to avoid dependencies on
+// Fuchsia-specific types when compiling on other platforms. Then remove this header.
+#if !defined(ANGLE_PLATFORM_FUCHSIA)
+typedef uint32_t zx_handle_t;
+# define ZX_HANDLE_INVALID ((zx_handle_t)0)
+# include <vulkan/vulkan_fuchsia.h>
+#endif
+
+#endif // COMMON_VULKAN_FUCHSIA_EXT_H_
diff --git a/gfx/angle/checkout/out/gen/angle/angle_commit.h b/gfx/angle/checkout/out/gen/angle/angle_commit.h
new file mode 100644
index 0000000000..8edfbf8fce
--- /dev/null
+++ b/gfx/angle/checkout/out/gen/angle/angle_commit.h
@@ -0,0 +1,5 @@
+#define ANGLE_COMMIT_HASH "fa03ab3adeaf"
+#define ANGLE_COMMIT_HASH_SIZE 12
+#define ANGLE_COMMIT_DATE "2024-01-09 17:44:29 -0800"
+#define ANGLE_COMMIT_POSITION 19736
+#define ANGLE_HAS_BINARY_LOADING
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 */
diff --git a/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_icd.h b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_icd.h
new file mode 100644
index 0000000000..41989ee354
--- /dev/null
+++ b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_icd.h
@@ -0,0 +1,245 @@
+//
+// File: vk_icd.h
+//
+/*
+ * Copyright (c) 2015-2016 The Khronos Group Inc.
+ * Copyright (c) 2015-2016 Valve Corporation
+ * Copyright (c) 2015-2016 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef VKICD_H
+#define VKICD_H
+
+#include "vulkan.h"
+#include <stdbool.h>
+
+// Loader-ICD version negotiation API. Versions add the following features:
+// Version 0 - Initial. Doesn't support vk_icdGetInstanceProcAddr
+// or vk_icdNegotiateLoaderICDInterfaceVersion.
+// Version 1 - Add support for vk_icdGetInstanceProcAddr.
+// Version 2 - Add Loader/ICD Interface version negotiation
+// via vk_icdNegotiateLoaderICDInterfaceVersion.
+// Version 3 - Add ICD creation/destruction of KHR_surface objects.
+// Version 4 - Add unknown physical device extension querying via
+// vk_icdGetPhysicalDeviceProcAddr.
+// Version 5 - Tells ICDs that the loader is now paying attention to the
+// application version of Vulkan passed into the ApplicationInfo
+// structure during vkCreateInstance. This will tell the ICD
+// that if the loader is older, it should automatically fail a
+// call for any API version > 1.0. Otherwise, the loader will
+// manually determine if it can support the expected version.
+// Version 6 - Add support for vk_icdEnumerateAdapterPhysicalDevices.
+#define CURRENT_LOADER_ICD_INTERFACE_VERSION 6
+#define MIN_SUPPORTED_LOADER_ICD_INTERFACE_VERSION 0
+#define MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION 4
+
+// Old typedefs that don't follow a proper naming convention but are preserved for compatibility
+typedef VkResult(VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion);
+// This is defined in vk_layer.h which will be found by the loader, but if an ICD is building against this
+// file directly, it won't be found.
+#ifndef PFN_GetPhysicalDeviceProcAddr
+typedef PFN_vkVoidFunction(VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char *pName);
+#endif
+
+// Typedefs for loader/ICD interface
+typedef VkResult (VKAPI_PTR *PFN_vk_icdNegotiateLoaderICDInterfaceVersion)(uint32_t* pVersion);
+typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vk_icdGetInstanceProcAddr)(VkInstance instance, const char* pName);
+typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vk_icdGetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+typedef VkResult (VKAPI_PTR *PFN_vk_icdEnumerateAdapterPhysicalDevices)(VkInstance instance, LUID adapterLUID,
+ uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices);
+#endif
+
+// Prototypes for loader/ICD interface
+#if !defined(VK_NO_PROTOTYPES)
+#ifdef __cplusplus
+extern "C" {
+#endif
+ VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pVersion);
+ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName);
+ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance isntance, const char* pName);
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+ VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
+ uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices);
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+/*
+ * The ICD must reserve space for a pointer for the loader's dispatch
+ * table, at the start of <each object>.
+ * The ICD must initialize this variable using the SET_LOADER_MAGIC_VALUE macro.
+ */
+
+#define ICD_LOADER_MAGIC 0x01CDC0DE
+
+typedef union {
+ uintptr_t loaderMagic;
+ void *loaderData;
+} VK_LOADER_DATA;
+
+static inline void set_loader_magic_value(void *pNewObject) {
+ VK_LOADER_DATA *loader_info = (VK_LOADER_DATA *)pNewObject;
+ loader_info->loaderMagic = ICD_LOADER_MAGIC;
+}
+
+static inline bool valid_loader_magic_value(void *pNewObject) {
+ const VK_LOADER_DATA *loader_info = (VK_LOADER_DATA *)pNewObject;
+ return (loader_info->loaderMagic & 0xffffffff) == ICD_LOADER_MAGIC;
+}
+
+/*
+ * Windows and Linux ICDs will treat VkSurfaceKHR as a pointer to a struct that
+ * contains the platform-specific connection and surface information.
+ */
+typedef enum {
+ VK_ICD_WSI_PLATFORM_MIR,
+ VK_ICD_WSI_PLATFORM_WAYLAND,
+ VK_ICD_WSI_PLATFORM_WIN32,
+ VK_ICD_WSI_PLATFORM_XCB,
+ VK_ICD_WSI_PLATFORM_XLIB,
+ VK_ICD_WSI_PLATFORM_ANDROID,
+ VK_ICD_WSI_PLATFORM_MACOS,
+ VK_ICD_WSI_PLATFORM_IOS,
+ VK_ICD_WSI_PLATFORM_DISPLAY,
+ VK_ICD_WSI_PLATFORM_HEADLESS,
+ VK_ICD_WSI_PLATFORM_METAL,
+ VK_ICD_WSI_PLATFORM_DIRECTFB,
+ VK_ICD_WSI_PLATFORM_VI,
+ VK_ICD_WSI_PLATFORM_GGP,
+ VK_ICD_WSI_PLATFORM_SCREEN,
+} VkIcdWsiPlatform;
+
+typedef struct {
+ VkIcdWsiPlatform platform;
+} VkIcdSurfaceBase;
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+typedef struct {
+ VkIcdSurfaceBase base;
+ MirConnection *connection;
+ MirSurface *mirSurface;
+} VkIcdSurfaceMir;
+#endif // VK_USE_PLATFORM_MIR_KHR
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+typedef struct {
+ VkIcdSurfaceBase base;
+ struct wl_display *display;
+ struct wl_surface *surface;
+} VkIcdSurfaceWayland;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+typedef struct {
+ VkIcdSurfaceBase base;
+ HINSTANCE hinstance;
+ HWND hwnd;
+} VkIcdSurfaceWin32;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+typedef struct {
+ VkIcdSurfaceBase base;
+ xcb_connection_t *connection;
+ xcb_window_t window;
+} VkIcdSurfaceXcb;
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+typedef struct {
+ VkIcdSurfaceBase base;
+ Display *dpy;
+ Window window;
+} VkIcdSurfaceXlib;
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+typedef struct {
+ VkIcdSurfaceBase base;
+ IDirectFB *dfb;
+ IDirectFBSurface *surface;
+} VkIcdSurfaceDirectFB;
+#endif // VK_USE_PLATFORM_DIRECTFB_EXT
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+typedef struct {
+ VkIcdSurfaceBase base;
+ struct ANativeWindow *window;
+} VkIcdSurfaceAndroid;
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+typedef struct {
+ VkIcdSurfaceBase base;
+ const void *pView;
+} VkIcdSurfaceMacOS;
+#endif // VK_USE_PLATFORM_MACOS_MVK
+
+#ifdef VK_USE_PLATFORM_IOS_MVK
+typedef struct {
+ VkIcdSurfaceBase base;
+ const void *pView;
+} VkIcdSurfaceIOS;
+#endif // VK_USE_PLATFORM_IOS_MVK
+
+#ifdef VK_USE_PLATFORM_GGP
+typedef struct {
+ VkIcdSurfaceBase base;
+ GgpStreamDescriptor streamDescriptor;
+} VkIcdSurfaceGgp;
+#endif // VK_USE_PLATFORM_GGP
+
+typedef struct {
+ VkIcdSurfaceBase base;
+ VkDisplayModeKHR displayMode;
+ uint32_t planeIndex;
+ uint32_t planeStackIndex;
+ VkSurfaceTransformFlagBitsKHR transform;
+ float globalAlpha;
+ VkDisplayPlaneAlphaFlagBitsKHR alphaMode;
+ VkExtent2D imageExtent;
+} VkIcdSurfaceDisplay;
+
+typedef struct {
+ VkIcdSurfaceBase base;
+} VkIcdSurfaceHeadless;
+
+#ifdef VK_USE_PLATFORM_METAL_EXT
+typedef struct {
+ VkIcdSurfaceBase base;
+ const CAMetalLayer *pLayer;
+} VkIcdSurfaceMetal;
+#endif // VK_USE_PLATFORM_METAL_EXT
+
+#ifdef VK_USE_PLATFORM_VI_NN
+typedef struct {
+ VkIcdSurfaceBase base;
+ void *window;
+} VkIcdSurfaceVi;
+#endif // VK_USE_PLATFORM_VI_NN
+
+#ifdef VK_USE_PLATFORM_SCREEN_QNX
+typedef struct {
+ VkIcdSurfaceBase base;
+ struct _screen_context *context;
+ struct _screen_window *window;
+} VkIcdSurfaceScreen;
+#endif // VK_USE_PLATFORM_SCREEN_QNX
+
+#endif // VKICD_H
diff --git a/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_layer.h b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_layer.h
new file mode 100644
index 0000000000..0651870c70
--- /dev/null
+++ b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_layer.h
@@ -0,0 +1,210 @@
+//
+// File: vk_layer.h
+//
+/*
+ * Copyright (c) 2015-2017 The Khronos Group Inc.
+ * Copyright (c) 2015-2017 Valve Corporation
+ * Copyright (c) 2015-2017 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/* Need to define dispatch table
+ * Core struct can then have ptr to dispatch table at the top
+ * Along with object ptrs for current and next OBJ
+ */
+#pragma once
+
+#include "vulkan.h"
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define VK_LAYER_EXPORT __attribute__((visibility("default")))
+#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
+#define VK_LAYER_EXPORT __attribute__((visibility("default")))
+#else
+#define VK_LAYER_EXPORT
+#endif
+
+#define MAX_NUM_UNKNOWN_EXTS 250
+
+ // Loader-Layer version negotiation API. Versions add the following features:
+ // Versions 0/1 - Initial. Doesn't support vk_layerGetPhysicalDeviceProcAddr
+ // or vk_icdNegotiateLoaderLayerInterfaceVersion.
+ // Version 2 - Add support for vk_layerGetPhysicalDeviceProcAddr and
+ // vk_icdNegotiateLoaderLayerInterfaceVersion.
+#define CURRENT_LOADER_LAYER_INTERFACE_VERSION 2
+#define MIN_SUPPORTED_LOADER_LAYER_INTERFACE_VERSION 1
+
+#define VK_CURRENT_CHAIN_VERSION 1
+
+// Typedef for use in the interfaces below
+typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName);
+
+// Version negotiation values
+typedef enum VkNegotiateLayerStructType {
+ LAYER_NEGOTIATE_UNINTIALIZED = 0,
+ LAYER_NEGOTIATE_INTERFACE_STRUCT = 1,
+} VkNegotiateLayerStructType;
+
+// Version negotiation structures
+typedef struct VkNegotiateLayerInterface {
+ VkNegotiateLayerStructType sType;
+ void *pNext;
+ uint32_t loaderLayerInterfaceVersion;
+ PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr pfnGetDeviceProcAddr;
+ PFN_GetPhysicalDeviceProcAddr pfnGetPhysicalDeviceProcAddr;
+} VkNegotiateLayerInterface;
+
+// Version negotiation functions
+typedef VkResult (VKAPI_PTR *PFN_vkNegotiateLoaderLayerInterfaceVersion)(VkNegotiateLayerInterface *pVersionStruct);
+
+// Function prototype for unknown physical device extension command
+typedef VkResult(VKAPI_PTR *PFN_PhysDevExt)(VkPhysicalDevice phys_device);
+
+// ------------------------------------------------------------------------------------------------
+// CreateInstance and CreateDevice support structures
+
+/* Sub type of structure for instance and device loader ext of CreateInfo.
+ * When sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
+ * or sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
+ * then VkLayerFunction indicates struct type pointed to by pNext
+ */
+typedef enum VkLayerFunction_ {
+ VK_LAYER_LINK_INFO = 0,
+ VK_LOADER_DATA_CALLBACK = 1,
+ VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK = 2,
+ VK_LOADER_FEATURES = 3,
+} VkLayerFunction;
+
+typedef struct VkLayerInstanceLink_ {
+ struct VkLayerInstanceLink_ *pNext;
+ PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
+ PFN_GetPhysicalDeviceProcAddr pfnNextGetPhysicalDeviceProcAddr;
+} VkLayerInstanceLink;
+
+/*
+ * When creating the device chain the loader needs to pass
+ * down information about it's device structure needed at
+ * the end of the chain. Passing the data via the
+ * VkLayerDeviceInfo avoids issues with finding the
+ * exact instance being used.
+ */
+typedef struct VkLayerDeviceInfo_ {
+ void *device_info;
+ PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
+} VkLayerDeviceInfo;
+
+typedef VkResult (VKAPI_PTR *PFN_vkSetInstanceLoaderData)(VkInstance instance,
+ void *object);
+typedef VkResult (VKAPI_PTR *PFN_vkSetDeviceLoaderData)(VkDevice device,
+ void *object);
+typedef VkResult (VKAPI_PTR *PFN_vkLayerCreateDevice)(VkInstance instance, VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, PFN_vkGetInstanceProcAddr layerGIPA, PFN_vkGetDeviceProcAddr *nextGDPA);
+typedef void (VKAPI_PTR *PFN_vkLayerDestroyDevice)(VkDevice physicalDevice, const VkAllocationCallbacks *pAllocator, PFN_vkDestroyDevice destroyFunction);
+
+typedef enum VkLoaderFeastureFlagBits {
+ VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING = 0x00000001,
+} VkLoaderFlagBits;
+typedef VkFlags VkLoaderFeatureFlags;
+
+typedef struct {
+ VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO
+ const void *pNext;
+ VkLayerFunction function;
+ union {
+ VkLayerInstanceLink *pLayerInfo;
+ PFN_vkSetInstanceLoaderData pfnSetInstanceLoaderData;
+ struct {
+ PFN_vkLayerCreateDevice pfnLayerCreateDevice;
+ PFN_vkLayerDestroyDevice pfnLayerDestroyDevice;
+ } layerDevice;
+ VkLoaderFeatureFlags loaderFeatures;
+ } u;
+} VkLayerInstanceCreateInfo;
+
+typedef struct VkLayerDeviceLink_ {
+ struct VkLayerDeviceLink_ *pNext;
+ PFN_vkGetInstanceProcAddr pfnNextGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr pfnNextGetDeviceProcAddr;
+} VkLayerDeviceLink;
+
+typedef struct {
+ VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO
+ const void *pNext;
+ VkLayerFunction function;
+ union {
+ VkLayerDeviceLink *pLayerInfo;
+ PFN_vkSetDeviceLoaderData pfnSetDeviceLoaderData;
+ } u;
+} VkLayerDeviceCreateInfo;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+VKAPI_ATTR VkResult VKAPI_CALL vkNegotiateLoaderLayerInterfaceVersion(VkNegotiateLayerInterface *pVersionStruct);
+
+typedef enum VkChainType {
+ VK_CHAIN_TYPE_UNKNOWN = 0,
+ VK_CHAIN_TYPE_ENUMERATE_INSTANCE_EXTENSION_PROPERTIES = 1,
+ VK_CHAIN_TYPE_ENUMERATE_INSTANCE_LAYER_PROPERTIES = 2,
+ VK_CHAIN_TYPE_ENUMERATE_INSTANCE_VERSION = 3,
+} VkChainType;
+
+typedef struct VkChainHeader {
+ VkChainType type;
+ uint32_t version;
+ uint32_t size;
+} VkChainHeader;
+
+typedef struct VkEnumerateInstanceExtensionPropertiesChain {
+ VkChainHeader header;
+ VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceExtensionPropertiesChain *, const char *, uint32_t *,
+ VkExtensionProperties *);
+ const struct VkEnumerateInstanceExtensionPropertiesChain *pNextLink;
+
+#if defined(__cplusplus)
+ inline VkResult CallDown(const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) const {
+ return pfnNextLayer(pNextLink, pLayerName, pPropertyCount, pProperties);
+ }
+#endif
+} VkEnumerateInstanceExtensionPropertiesChain;
+
+typedef struct VkEnumerateInstanceLayerPropertiesChain {
+ VkChainHeader header;
+ VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceLayerPropertiesChain *, uint32_t *, VkLayerProperties *);
+ const struct VkEnumerateInstanceLayerPropertiesChain *pNextLink;
+
+#if defined(__cplusplus)
+ inline VkResult CallDown(uint32_t *pPropertyCount, VkLayerProperties *pProperties) const {
+ return pfnNextLayer(pNextLink, pPropertyCount, pProperties);
+ }
+#endif
+} VkEnumerateInstanceLayerPropertiesChain;
+
+typedef struct VkEnumerateInstanceVersionChain {
+ VkChainHeader header;
+ VkResult(VKAPI_PTR *pfnNextLayer)(const struct VkEnumerateInstanceVersionChain *, uint32_t *);
+ const struct VkEnumerateInstanceVersionChain *pNextLink;
+
+#if defined(__cplusplus)
+ inline VkResult CallDown(uint32_t *pApiVersion) const {
+ return pfnNextLayer(pNextLink, pApiVersion);
+ }
+#endif
+} VkEnumerateInstanceVersionChain;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_platform.h b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_platform.h
new file mode 100644
index 0000000000..3ff8c5d146
--- /dev/null
+++ b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_platform.h
@@ -0,0 +1,84 @@
+//
+// File: vk_platform.h
+//
+/*
+** Copyright 2014-2022 The Khronos Group Inc.
+**
+** SPDX-License-Identifier: Apache-2.0
+*/
+
+
+#ifndef VK_PLATFORM_H_
+#define VK_PLATFORM_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+/*
+***************************************************************************************************
+* Platform-specific directives and type declarations
+***************************************************************************************************
+*/
+
+/* Platform-specific calling convention macros.
+ *
+ * Platforms should define these so that Vulkan clients call Vulkan commands
+ * with the same calling conventions that the Vulkan implementation expects.
+ *
+ * VKAPI_ATTR - Placed before the return type in function declarations.
+ * Useful for C++11 and GCC/Clang-style function attribute syntax.
+ * VKAPI_CALL - Placed after the return type in function declarations.
+ * Useful for MSVC-style calling convention syntax.
+ * VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
+ *
+ * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
+ * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
+ */
+#if defined(_WIN32)
+ // On Windows, Vulkan commands use the stdcall convention
+ #define VKAPI_ATTR
+ #define VKAPI_CALL __stdcall
+ #define VKAPI_PTR VKAPI_CALL
+#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
+ #error "Vulkan is not supported for the 'armeabi' NDK ABI"
+#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
+ // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
+ // calling convention, i.e. float parameters are passed in registers. This
+ // is true even if the rest of the application passes floats on the stack,
+ // as it does by default when compiling for the armeabi-v7a NDK ABI.
+ #define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
+ #define VKAPI_CALL
+ #define VKAPI_PTR VKAPI_ATTR
+#else
+ // On other platforms, use the default calling convention
+ #define VKAPI_ATTR
+ #define VKAPI_CALL
+ #define VKAPI_PTR
+#endif
+
+#if !defined(VK_NO_STDDEF_H)
+ #include <stddef.h>
+#endif // !defined(VK_NO_STDDEF_H)
+
+#if !defined(VK_NO_STDINT_H)
+ #if defined(_MSC_VER) && (_MSC_VER < 1600)
+ typedef signed __int8 int8_t;
+ typedef unsigned __int8 uint8_t;
+ typedef signed __int16 int16_t;
+ typedef unsigned __int16 uint16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int32 uint32_t;
+ typedef signed __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+ #else
+ #include <stdint.h>
+ #endif
+#endif // !defined(VK_NO_STDINT_H)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#endif
diff --git a/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_sdk_platform.h b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_sdk_platform.h
new file mode 100644
index 0000000000..96d8676949
--- /dev/null
+++ b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vk_sdk_platform.h
@@ -0,0 +1,69 @@
+//
+// File: vk_sdk_platform.h
+//
+/*
+ * Copyright (c) 2015-2016 The Khronos Group Inc.
+ * Copyright (c) 2015-2016 Valve Corporation
+ * Copyright (c) 2015-2016 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VK_SDK_PLATFORM_H
+#define VK_SDK_PLATFORM_H
+
+#if defined(_WIN32)
+#define NOMINMAX
+#ifndef __cplusplus
+#undef inline
+#define inline __inline
+#endif // __cplusplus
+
+#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
+// C99:
+// Microsoft didn't implement C99 in Visual Studio; but started adding it with
+// VS2013. However, VS2013 still didn't have snprintf(). The following is a
+// work-around (Note: The _CRT_SECURE_NO_WARNINGS macro must be set in the
+// "CMakeLists.txt" file).
+// NOTE: This is fixed in Visual Studio 2015.
+#define snprintf _snprintf
+#endif
+
+#define strdup _strdup
+
+#endif // _WIN32
+
+// Check for noexcept support using clang, with fallback to Windows or GCC version numbers
+#ifndef NOEXCEPT
+#if defined(__clang__)
+#if __has_feature(cxx_noexcept)
+#define HAS_NOEXCEPT
+#endif
+#else
+#if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46
+#define HAS_NOEXCEPT
+#else
+#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026 && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS
+#define HAS_NOEXCEPT
+#endif
+#endif
+#endif
+
+#ifdef HAS_NOEXCEPT
+#define NOEXCEPT noexcept
+#else
+#define NOEXCEPT
+#endif
+#endif
+
+#endif // VK_SDK_PLATFORM_H
diff --git a/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan.h b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan.h
new file mode 100644
index 0000000000..3510ac912b
--- /dev/null
+++ b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan.h
@@ -0,0 +1,91 @@
+#ifndef VULKAN_H_
+#define VULKAN_H_ 1
+
+/*
+** Copyright 2015-2022 The Khronos Group Inc.
+**
+** SPDX-License-Identifier: Apache-2.0
+*/
+
+#include "vk_platform.h"
+#include "vulkan_core.h"
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#include "vulkan_android.h"
+#endif
+
+#ifdef VK_USE_PLATFORM_FUCHSIA
+#include <zircon/types.h>
+#include "vulkan_fuchsia.h"
+#endif
+
+#ifdef VK_USE_PLATFORM_IOS_MVK
+#include "vulkan_ios.h"
+#endif
+
+
+#ifdef VK_USE_PLATFORM_MACOS_MVK
+#include "vulkan_macos.h"
+#endif
+
+#ifdef VK_USE_PLATFORM_METAL_EXT
+#include "vulkan_metal.h"
+#endif
+
+#ifdef VK_USE_PLATFORM_VI_NN
+#include "vulkan_vi.h"
+#endif
+
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+#include "vulkan_wayland.h"
+#endif
+
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+#include <windows.h>
+#include "vulkan_win32.h"
+#endif
+
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+#include <xcb/xcb.h>
+#include "vulkan_xcb.h"
+#endif
+
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+#include <X11/Xlib.h>
+#include "vulkan_xlib.h"
+#endif
+
+
+#ifdef VK_USE_PLATFORM_DIRECTFB_EXT
+#include <directfb.h>
+#include "vulkan_directfb.h"
+#endif
+
+
+#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrandr.h>
+#include "vulkan_xlib_xrandr.h"
+#endif
+
+
+#ifdef VK_USE_PLATFORM_GGP
+#include <ggp_c/vulkan_types.h>
+#include "vulkan_ggp.h"
+#endif
+
+
+#ifdef VK_USE_PLATFORM_SCREEN_QNX
+#include <screen/screen.h>
+#include "vulkan_screen.h"
+#endif
+
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+#include "vulkan_beta.h"
+#endif
+
+#endif // VULKAN_H_
diff --git a/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan.hpp b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan.hpp
new file mode 100644
index 0000000000..41f71cdf8f
--- /dev/null
+++ b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan.hpp
@@ -0,0 +1,15303 @@
+// Copyright 2015-2022 The Khronos Group Inc.
+//
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+
+// This header is generated from the Khronos Vulkan XML API Registry.
+
+#ifndef VULKAN_HPP
+#define VULKAN_HPP
+
+#if defined( _MSVC_LANG )
+# define VULKAN_HPP_CPLUSPLUS _MSVC_LANG
+#else
+# define VULKAN_HPP_CPLUSPLUS __cplusplus
+#endif
+
+#if 201703L < VULKAN_HPP_CPLUSPLUS
+# define VULKAN_HPP_CPP_VERSION 20
+#elif 201402L < VULKAN_HPP_CPLUSPLUS
+# define VULKAN_HPP_CPP_VERSION 17
+#elif 201103L < VULKAN_HPP_CPLUSPLUS
+# define VULKAN_HPP_CPP_VERSION 14
+#elif 199711L < VULKAN_HPP_CPLUSPLUS
+# define VULKAN_HPP_CPP_VERSION 11
+#else
+# error "vulkan.hpp needs at least c++ standard version 11"
+#endif
+
+#include <algorithm>
+#include <array> // ArrayWrapperND
+#include <string> // std::string
+#include <vulkan/vulkan.h>
+#if 17 <= VULKAN_HPP_CPP_VERSION
+# include <string_view> // std::string_view
+#endif
+
+#if defined( VULKAN_HPP_DISABLE_ENHANCED_MODE )
+# if !defined( VULKAN_HPP_NO_SMART_HANDLE )
+# define VULKAN_HPP_NO_SMART_HANDLE
+# endif
+#else
+# include <tuple> // std::tie
+# include <vector> // std::vector
+#endif
+
+#if !defined( VULKAN_HPP_NO_EXCEPTIONS )
+# include <system_error> // std::is_error_code_enum
+#endif
+
+#if defined( VULKAN_HPP_NO_CONSTRUCTORS )
+# if !defined( VULKAN_HPP_NO_STRUCT_CONSTRUCTORS )
+# define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
+# endif
+# if !defined( VULKAN_HPP_NO_UNION_CONSTRUCTORS )
+# define VULKAN_HPP_NO_UNION_CONSTRUCTORS
+# endif
+#endif
+
+#if defined( VULKAN_HPP_NO_SETTERS )
+# if !defined( VULKAN_HPP_NO_STRUCT_SETTERS )
+# define VULKAN_HPP_NO_STRUCT_SETTERS
+# endif
+# if !defined( VULKAN_HPP_NO_UNION_SETTERS )
+# define VULKAN_HPP_NO_UNION_SETTERS
+# endif
+#endif
+
+#if !defined( VULKAN_HPP_ASSERT )
+# include <cassert>
+# define VULKAN_HPP_ASSERT assert
+#endif
+
+#if !defined( VULKAN_HPP_ASSERT_ON_RESULT )
+# define VULKAN_HPP_ASSERT_ON_RESULT VULKAN_HPP_ASSERT
+#endif
+
+#if !defined( VULKAN_HPP_STATIC_ASSERT )
+# define VULKAN_HPP_STATIC_ASSERT static_assert
+#endif
+
+#if !defined( VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL )
+# define VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL 1
+#endif
+
+#if VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL == 1
+# if defined( __unix__ ) || defined( __APPLE__ ) || defined( __QNXNTO__ ) || defined( __Fuchsia__ )
+# include <dlfcn.h>
+# elif defined( _WIN32 )
+typedef struct HINSTANCE__ * HINSTANCE;
+# if defined( _WIN64 )
+typedef int64_t( __stdcall * FARPROC )();
+# else
+typedef int( __stdcall * FARPROC )();
+# endif
+extern "C" __declspec( dllimport ) HINSTANCE __stdcall LoadLibraryA( char const * lpLibFileName );
+extern "C" __declspec( dllimport ) int __stdcall FreeLibrary( HINSTANCE hLibModule );
+extern "C" __declspec( dllimport ) FARPROC __stdcall GetProcAddress( HINSTANCE hModule, const char * lpProcName );
+# endif
+#endif
+
+#if !defined( __has_include )
+# define __has_include( x ) false
+#endif
+
+#if ( 201907 <= __cpp_lib_three_way_comparison ) && __has_include( <compare> ) && !defined( VULKAN_HPP_NO_SPACESHIP_OPERATOR )
+# define VULKAN_HPP_HAS_SPACESHIP_OPERATOR
+#endif
+#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+# include <compare>
+#endif
+
+#if ( 201803 <= __cpp_lib_span )
+# define VULKAN_HPP_SUPPORT_SPAN
+# include <span>
+#endif
+
+static_assert( VK_HEADER_VERSION == 231, "Wrong VK_HEADER_VERSION!" );
+
+// 32-bit vulkan is not typesafe for non-dispatchable handles, so don't allow copy constructors on this platform by default.
+// To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION
+#if ( VK_USE_64_BIT_PTR_DEFINES == 1 )
+# if !defined( VULKAN_HPP_TYPESAFE_CONVERSION )
+# define VULKAN_HPP_TYPESAFE_CONVERSION
+# endif
+#endif
+
+// <tuple> includes <sys/sysmacros.h> through some other header
+// this results in major(x) being resolved to gnu_dev_major(x)
+// which is an expression in a constructor initializer list.
+#if defined( major )
+# undef major
+#endif
+#if defined( minor )
+# undef minor
+#endif
+
+// Windows defines MemoryBarrier which is deprecated and collides
+// with the VULKAN_HPP_NAMESPACE::MemoryBarrier struct.
+#if defined( MemoryBarrier )
+# undef MemoryBarrier
+#endif
+
+#if !defined( VULKAN_HPP_HAS_UNRESTRICTED_UNIONS )
+# if defined( __clang__ )
+# if __has_feature( cxx_unrestricted_unions )
+# define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS
+# endif
+# elif defined( __GNUC__ )
+# define GCC_VERSION ( __GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ )
+# if 40600 <= GCC_VERSION
+# define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS
+# endif
+# elif defined( _MSC_VER )
+# if 1900 <= _MSC_VER
+# define VULKAN_HPP_HAS_UNRESTRICTED_UNIONS
+# endif
+# endif
+#endif
+
+#if !defined( VULKAN_HPP_INLINE )
+# if defined( __clang__ )
+# if __has_attribute( always_inline )
+# define VULKAN_HPP_INLINE __attribute__( ( always_inline ) ) __inline__
+# else
+# define VULKAN_HPP_INLINE inline
+# endif
+# elif defined( __GNUC__ )
+# define VULKAN_HPP_INLINE __attribute__( ( always_inline ) ) __inline__
+# elif defined( _MSC_VER )
+# define VULKAN_HPP_INLINE inline
+# else
+# define VULKAN_HPP_INLINE inline
+# endif
+#endif
+
+#if defined( VULKAN_HPP_TYPESAFE_CONVERSION )
+# define VULKAN_HPP_TYPESAFE_EXPLICIT
+#else
+# define VULKAN_HPP_TYPESAFE_EXPLICIT explicit
+#endif
+
+#if defined( __cpp_constexpr )
+# define VULKAN_HPP_CONSTEXPR constexpr
+# if __cpp_constexpr >= 201304
+# define VULKAN_HPP_CONSTEXPR_14 constexpr
+# else
+# define VULKAN_HPP_CONSTEXPR_14
+# endif
+# define VULKAN_HPP_CONST_OR_CONSTEXPR constexpr
+#else
+# define VULKAN_HPP_CONSTEXPR
+# define VULKAN_HPP_CONSTEXPR_14
+# define VULKAN_HPP_CONST_OR_CONSTEXPR const
+#endif
+
+#if !defined( VULKAN_HPP_NOEXCEPT )
+# if defined( _MSC_VER ) && ( _MSC_VER <= 1800 )
+# define VULKAN_HPP_NOEXCEPT
+# else
+# define VULKAN_HPP_NOEXCEPT noexcept
+# define VULKAN_HPP_HAS_NOEXCEPT 1
+# if defined( VULKAN_HPP_NO_EXCEPTIONS )
+# define VULKAN_HPP_NOEXCEPT_WHEN_NO_EXCEPTIONS noexcept
+# else
+# define VULKAN_HPP_NOEXCEPT_WHEN_NO_EXCEPTIONS
+# endif
+# endif
+#endif
+
+#if 14 <= VULKAN_HPP_CPP_VERSION
+# define VULKAN_HPP_DEPRECATED( msg ) [[deprecated( msg )]]
+#else
+# define VULKAN_HPP_DEPRECATED( msg )
+#endif
+
+#if ( 17 <= VULKAN_HPP_CPP_VERSION ) && !defined( VULKAN_HPP_NO_NODISCARD_WARNINGS )
+# define VULKAN_HPP_NODISCARD [[nodiscard]]
+# if defined( VULKAN_HPP_NO_EXCEPTIONS )
+# define VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS [[nodiscard]]
+# else
+# define VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS
+# endif
+#else
+# define VULKAN_HPP_NODISCARD
+# define VULKAN_HPP_NODISCARD_WHEN_NO_EXCEPTIONS
+#endif
+
+#if !defined( VULKAN_HPP_NAMESPACE )
+# define VULKAN_HPP_NAMESPACE vk
+#endif
+
+#define VULKAN_HPP_STRINGIFY2( text ) #text
+#define VULKAN_HPP_STRINGIFY( text ) VULKAN_HPP_STRINGIFY2( text )
+#define VULKAN_HPP_NAMESPACE_STRING VULKAN_HPP_STRINGIFY( VULKAN_HPP_NAMESPACE )
+
+namespace VULKAN_HPP_NAMESPACE
+{
+ template <typename T, size_t N>
+ class ArrayWrapper1D : public std::array<T, N>
+ {
+ public:
+ VULKAN_HPP_CONSTEXPR ArrayWrapper1D() VULKAN_HPP_NOEXCEPT : std::array<T, N>() {}
+
+ VULKAN_HPP_CONSTEXPR ArrayWrapper1D( std::array<T, N> const & data ) VULKAN_HPP_NOEXCEPT : std::array<T, N>( data ) {}
+
+#if ( VK_USE_64_BIT_PTR_DEFINES == 0 )
+ // on 32 bit compiles, needs overloads on index type int to resolve ambiguities
+ VULKAN_HPP_CONSTEXPR T const & operator[]( int index ) const VULKAN_HPP_NOEXCEPT
+ {
+ return std::array<T, N>::operator[]( index );
+ }
+
+ T & operator[]( int index ) VULKAN_HPP_NOEXCEPT
+ {
+ return std::array<T, N>::operator[]( index );
+ }
+#endif
+
+ operator T const *() const VULKAN_HPP_NOEXCEPT
+ {
+ return this->data();
+ }
+
+ operator T *() VULKAN_HPP_NOEXCEPT
+ {
+ return this->data();
+ }
+
+ template <typename B = T, typename std::enable_if<std::is_same<B, char>::value, int>::type = 0>
+ operator std::string() const
+ {
+ return std::string( this->data() );
+ }
+
+#if 17 <= VULKAN_HPP_CPP_VERSION
+ template <typename B = T, typename std::enable_if<std::is_same<B, char>::value, int>::type = 0>
+ operator std::string_view() const
+ {
+ return std::string_view( this->data() );
+ }
+#endif
+
+#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+ template <typename B = T, typename std::enable_if<std::is_same<B, char>::value, int>::type = 0>
+ std::strong_ordering operator<=>( ArrayWrapper1D<char, N> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return *static_cast<std::array<char, N> const *>( this ) <=> *static_cast<std::array<char, N> const *>( &rhs );
+ }
+#else
+ template <typename B = T, typename std::enable_if<std::is_same<B, char>::value, int>::type = 0>
+ bool operator<( ArrayWrapper1D<char, N> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return *static_cast<std::array<char, N> const *>( this ) < *static_cast<std::array<char, N> const *>( &rhs );
+ }
+
+ template <typename B = T, typename std::enable_if<std::is_same<B, char>::value, int>::type = 0>
+ bool operator<=( ArrayWrapper1D<char, N> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return *static_cast<std::array<char, N> const *>( this ) <= *static_cast<std::array<char, N> const *>( &rhs );
+ }
+
+ template <typename B = T, typename std::enable_if<std::is_same<B, char>::value, int>::type = 0>
+ bool operator>( ArrayWrapper1D<char, N> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return *static_cast<std::array<char, N> const *>( this ) > *static_cast<std::array<char, N> const *>( &rhs );
+ }
+
+ template <typename B = T, typename std::enable_if<std::is_same<B, char>::value, int>::type = 0>
+ bool operator>=( ArrayWrapper1D<char, N> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return *static_cast<std::array<char, N> const *>( this ) >= *static_cast<std::array<char, N> const *>( &rhs );
+ }
+#endif
+
+ template <typename B = T, typename std::enable_if<std::is_same<B, char>::value, int>::type = 0>
+ bool operator==( ArrayWrapper1D<char, N> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return *static_cast<std::array<char, N> const *>( this ) == *static_cast<std::array<char, N> const *>( &rhs );
+ }
+
+ template <typename B = T, typename std::enable_if<std::is_same<B, char>::value, int>::type = 0>
+ bool operator!=( ArrayWrapper1D<char, N> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return *static_cast<std::array<char, N> const *>( this ) != *static_cast<std::array<char, N> const *>( &rhs );
+ }
+ };
+
+ // specialization of relational operators between std::string and arrays of chars
+ template <size_t N>
+ bool operator<( std::string const & lhs, ArrayWrapper1D<char, N> const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ return lhs < rhs.data();
+ }
+
+ template <size_t N>
+ bool operator<=( std::string const & lhs, ArrayWrapper1D<char, N> const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ return lhs <= rhs.data();
+ }
+
+ template <size_t N>
+ bool operator>( std::string const & lhs, ArrayWrapper1D<char, N> const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ return lhs > rhs.data();
+ }
+
+ template <size_t N>
+ bool operator>=( std::string const & lhs, ArrayWrapper1D<char, N> const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ return lhs >= rhs.data();
+ }
+
+ template <size_t N>
+ bool operator==( std::string const & lhs, ArrayWrapper1D<char, N> const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ return lhs == rhs.data();
+ }
+
+ template <size_t N>
+ bool operator!=( std::string const & lhs, ArrayWrapper1D<char, N> const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ return lhs != rhs.data();
+ }
+
+ template <typename T, size_t N, size_t M>
+ class ArrayWrapper2D : public std::array<ArrayWrapper1D<T, M>, N>
+ {
+ public:
+ VULKAN_HPP_CONSTEXPR ArrayWrapper2D() VULKAN_HPP_NOEXCEPT : std::array<ArrayWrapper1D<T, M>, N>() {}
+
+ VULKAN_HPP_CONSTEXPR ArrayWrapper2D( std::array<std::array<T, M>, N> const & data ) VULKAN_HPP_NOEXCEPT
+ : std::array<ArrayWrapper1D<T, M>, N>( *reinterpret_cast<std::array<ArrayWrapper1D<T, M>, N> const *>( &data ) )
+ {
+ }
+ };
+
+ template <typename FlagBitsType>
+ struct FlagTraits
+ {
+ static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = false;
+ };
+
+ template <typename BitType>
+ class Flags
+ {
+ public:
+ using MaskType = typename std::underlying_type<BitType>::type;
+
+ // constructors
+ VULKAN_HPP_CONSTEXPR Flags() VULKAN_HPP_NOEXCEPT : m_mask( 0 ) {}
+
+ VULKAN_HPP_CONSTEXPR Flags( BitType bit ) VULKAN_HPP_NOEXCEPT : m_mask( static_cast<MaskType>( bit ) ) {}
+
+ VULKAN_HPP_CONSTEXPR Flags( Flags<BitType> const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+
+ VULKAN_HPP_CONSTEXPR explicit Flags( MaskType flags ) VULKAN_HPP_NOEXCEPT : m_mask( flags ) {}
+
+ // relational operators
+#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+ auto operator<=>( Flags<BitType> const & ) const = default;
+#else
+ VULKAN_HPP_CONSTEXPR bool operator<( Flags<BitType> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return m_mask < rhs.m_mask;
+ }
+
+ VULKAN_HPP_CONSTEXPR bool operator<=( Flags<BitType> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return m_mask <= rhs.m_mask;
+ }
+
+ VULKAN_HPP_CONSTEXPR bool operator>( Flags<BitType> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return m_mask > rhs.m_mask;
+ }
+
+ VULKAN_HPP_CONSTEXPR bool operator>=( Flags<BitType> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return m_mask >= rhs.m_mask;
+ }
+
+ VULKAN_HPP_CONSTEXPR bool operator==( Flags<BitType> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return m_mask == rhs.m_mask;
+ }
+
+ VULKAN_HPP_CONSTEXPR bool operator!=( Flags<BitType> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return m_mask != rhs.m_mask;
+ }
+#endif
+
+ // logical operator
+ VULKAN_HPP_CONSTEXPR bool operator!() const VULKAN_HPP_NOEXCEPT
+ {
+ return !m_mask;
+ }
+
+ // bitwise operators
+ VULKAN_HPP_CONSTEXPR Flags<BitType> operator&( Flags<BitType> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return Flags<BitType>( m_mask & rhs.m_mask );
+ }
+
+ VULKAN_HPP_CONSTEXPR Flags<BitType> operator|( Flags<BitType> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return Flags<BitType>( m_mask | rhs.m_mask );
+ }
+
+ VULKAN_HPP_CONSTEXPR Flags<BitType> operator^( Flags<BitType> const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return Flags<BitType>( m_mask ^ rhs.m_mask );
+ }
+
+ VULKAN_HPP_CONSTEXPR Flags<BitType> operator~() const VULKAN_HPP_NOEXCEPT
+ {
+ return Flags<BitType>( m_mask ^ FlagTraits<BitType>::allFlags );
+ }
+
+ // assignment operators
+ VULKAN_HPP_CONSTEXPR_14 Flags<BitType> & operator=( Flags<BitType> const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+
+ VULKAN_HPP_CONSTEXPR_14 Flags<BitType> & operator|=( Flags<BitType> const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ m_mask |= rhs.m_mask;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 Flags<BitType> & operator&=( Flags<BitType> const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ m_mask &= rhs.m_mask;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 Flags<BitType> & operator^=( Flags<BitType> const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ m_mask ^= rhs.m_mask;
+ return *this;
+ }
+
+ // cast operators
+ explicit VULKAN_HPP_CONSTEXPR operator bool() const VULKAN_HPP_NOEXCEPT
+ {
+ return !!m_mask;
+ }
+
+ explicit VULKAN_HPP_CONSTEXPR operator MaskType() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_mask;
+ }
+
+#if defined( VULKAN_HPP_FLAGS_MASK_TYPE_AS_PUBLIC )
+ public:
+#else
+ private:
+#endif
+ MaskType m_mask;
+ };
+
+#if !defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+ // relational operators only needed for pre C++20
+ template <typename BitType>
+ VULKAN_HPP_CONSTEXPR bool operator<( BitType bit, Flags<BitType> const & flags ) VULKAN_HPP_NOEXCEPT
+ {
+ return flags.operator>( bit );
+ }
+
+ template <typename BitType>
+ VULKAN_HPP_CONSTEXPR bool operator<=( BitType bit, Flags<BitType> const & flags ) VULKAN_HPP_NOEXCEPT
+ {
+ return flags.operator>=( bit );
+ }
+
+ template <typename BitType>
+ VULKAN_HPP_CONSTEXPR bool operator>( BitType bit, Flags<BitType> const & flags ) VULKAN_HPP_NOEXCEPT
+ {
+ return flags.operator<( bit );
+ }
+
+ template <typename BitType>
+ VULKAN_HPP_CONSTEXPR bool operator>=( BitType bit, Flags<BitType> const & flags ) VULKAN_HPP_NOEXCEPT
+ {
+ return flags.operator<=( bit );
+ }
+
+ template <typename BitType>
+ VULKAN_HPP_CONSTEXPR bool operator==( BitType bit, Flags<BitType> const & flags ) VULKAN_HPP_NOEXCEPT
+ {
+ return flags.operator==( bit );
+ }
+
+ template <typename BitType>
+ VULKAN_HPP_CONSTEXPR bool operator!=( BitType bit, Flags<BitType> const & flags ) VULKAN_HPP_NOEXCEPT
+ {
+ return flags.operator!=( bit );
+ }
+#endif
+
+ // bitwise operators
+ template <typename BitType>
+ VULKAN_HPP_CONSTEXPR Flags<BitType> operator&( BitType bit, Flags<BitType> const & flags ) VULKAN_HPP_NOEXCEPT
+ {
+ return flags.operator&( bit );
+ }
+
+ template <typename BitType>
+ VULKAN_HPP_CONSTEXPR Flags<BitType> operator|( BitType bit, Flags<BitType> const & flags ) VULKAN_HPP_NOEXCEPT
+ {
+ return flags.operator|( bit );
+ }
+
+ template <typename BitType>
+ VULKAN_HPP_CONSTEXPR Flags<BitType> operator^( BitType bit, Flags<BitType> const & flags ) VULKAN_HPP_NOEXCEPT
+ {
+ return flags.operator^( bit );
+ }
+
+ // bitwise operators on BitType
+ template <typename BitType, typename std::enable_if<FlagTraits<BitType>::isBitmask, bool>::type = true>
+ VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR Flags<BitType> operator&( BitType lhs, BitType rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ return Flags<BitType>( lhs ) & rhs;
+ }
+
+ template <typename BitType, typename std::enable_if<FlagTraits<BitType>::isBitmask, bool>::type = true>
+ VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR Flags<BitType> operator|( BitType lhs, BitType rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ return Flags<BitType>( lhs ) | rhs;
+ }
+
+ template <typename BitType, typename std::enable_if<FlagTraits<BitType>::isBitmask, bool>::type = true>
+ VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR Flags<BitType> operator^( BitType lhs, BitType rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ return Flags<BitType>( lhs ) ^ rhs;
+ }
+
+ template <typename BitType, typename std::enable_if<FlagTraits<BitType>::isBitmask, bool>::type = true>
+ VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR Flags<BitType> operator~( BitType bit ) VULKAN_HPP_NOEXCEPT
+ {
+ return ~( Flags<BitType>( bit ) );
+ }
+
+#if !defined( VULKAN_HPP_DISABLE_ENHANCED_MODE )
+ template <typename T>
+ class ArrayProxy
+ {
+ public:
+ VULKAN_HPP_CONSTEXPR ArrayProxy() VULKAN_HPP_NOEXCEPT
+ : m_count( 0 )
+ , m_ptr( nullptr )
+ {
+ }
+
+ VULKAN_HPP_CONSTEXPR ArrayProxy( std::nullptr_t ) VULKAN_HPP_NOEXCEPT
+ : m_count( 0 )
+ , m_ptr( nullptr )
+ {
+ }
+
+ ArrayProxy( T const & value ) VULKAN_HPP_NOEXCEPT
+ : m_count( 1 )
+ , m_ptr( &value )
+ {
+ }
+
+ ArrayProxy( uint32_t count, T const * ptr ) VULKAN_HPP_NOEXCEPT
+ : m_count( count )
+ , m_ptr( ptr )
+ {
+ }
+
+ template <std::size_t C>
+ ArrayProxy( T const ( &ptr )[C] ) VULKAN_HPP_NOEXCEPT
+ : m_count( C )
+ , m_ptr( ptr )
+ {
+ }
+
+# if __GNUC__ >= 9
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Winit-list-lifetime"
+# endif
+
+ ArrayProxy( std::initializer_list<T> const & list ) VULKAN_HPP_NOEXCEPT
+ : m_count( static_cast<uint32_t>( list.size() ) )
+ , m_ptr( list.begin() )
+ {
+ }
+
+ template <typename B = T, typename std::enable_if<std::is_const<B>::value, int>::type = 0>
+ ArrayProxy( std::initializer_list<typename std::remove_const<T>::type> const & list ) VULKAN_HPP_NOEXCEPT
+ : m_count( static_cast<uint32_t>( list.size() ) )
+ , m_ptr( list.begin() )
+ {
+ }
+
+# if __GNUC__ >= 9
+# pragma GCC diagnostic pop
+# endif
+
+ // Any type with a .data() return type implicitly convertible to T*, and a .size() return type implicitly
+ // convertible to size_t. The const version can capture temporaries, with lifetime ending at end of statement.
+ template <typename V,
+ typename std::enable_if<std::is_convertible<decltype( std::declval<V>().data() ), T *>::value &&
+ std::is_convertible<decltype( std::declval<V>().size() ), std::size_t>::value>::type * = nullptr>
+ ArrayProxy( V const & v ) VULKAN_HPP_NOEXCEPT
+ : m_count( static_cast<uint32_t>( v.size() ) )
+ , m_ptr( v.data() )
+ {
+ }
+
+ const T * begin() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_ptr;
+ }
+
+ const T * end() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_ptr + m_count;
+ }
+
+ const T & front() const VULKAN_HPP_NOEXCEPT
+ {
+ VULKAN_HPP_ASSERT( m_count && m_ptr );
+ return *m_ptr;
+ }
+
+ const T & back() const VULKAN_HPP_NOEXCEPT
+ {
+ VULKAN_HPP_ASSERT( m_count && m_ptr );
+ return *( m_ptr + m_count - 1 );
+ }
+
+ bool empty() const VULKAN_HPP_NOEXCEPT
+ {
+ return ( m_count == 0 );
+ }
+
+ uint32_t size() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_count;
+ }
+
+ T const * data() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_ptr;
+ }
+
+ private:
+ uint32_t m_count;
+ T const * m_ptr;
+ };
+
+ template <typename T>
+ class ArrayProxyNoTemporaries
+ {
+ public:
+ VULKAN_HPP_CONSTEXPR ArrayProxyNoTemporaries() VULKAN_HPP_NOEXCEPT
+ : m_count( 0 )
+ , m_ptr( nullptr )
+ {
+ }
+
+ VULKAN_HPP_CONSTEXPR ArrayProxyNoTemporaries( std::nullptr_t ) VULKAN_HPP_NOEXCEPT
+ : m_count( 0 )
+ , m_ptr( nullptr )
+ {
+ }
+
+ ArrayProxyNoTemporaries( T & value ) VULKAN_HPP_NOEXCEPT
+ : m_count( 1 )
+ , m_ptr( &value )
+ {
+ }
+
+ template <typename V>
+ ArrayProxyNoTemporaries( V && value ) = delete;
+
+ template <typename B = T, typename std::enable_if<std::is_const<B>::value, int>::type = 0>
+ ArrayProxyNoTemporaries( typename std::remove_const<T>::type & value ) VULKAN_HPP_NOEXCEPT
+ : m_count( 1 )
+ , m_ptr( &value )
+ {
+ }
+
+ template <typename B = T, typename std::enable_if<std::is_const<B>::value, int>::type = 0>
+ ArrayProxyNoTemporaries( typename std::remove_const<T>::type && value ) = delete;
+
+ ArrayProxyNoTemporaries( uint32_t count, T * ptr ) VULKAN_HPP_NOEXCEPT
+ : m_count( count )
+ , m_ptr( ptr )
+ {
+ }
+
+ template <typename B = T, typename std::enable_if<std::is_const<B>::value, int>::type = 0>
+ ArrayProxyNoTemporaries( uint32_t count, typename std::remove_const<T>::type * ptr ) VULKAN_HPP_NOEXCEPT
+ : m_count( count )
+ , m_ptr( ptr )
+ {
+ }
+
+ template <std::size_t C>
+ ArrayProxyNoTemporaries( T ( &ptr )[C] ) VULKAN_HPP_NOEXCEPT
+ : m_count( C )
+ , m_ptr( ptr )
+ {
+ }
+
+ template <std::size_t C>
+ ArrayProxyNoTemporaries( T( &&ptr )[C] ) = delete;
+
+ template <std::size_t C, typename B = T, typename std::enable_if<std::is_const<B>::value, int>::type = 0>
+ ArrayProxyNoTemporaries( typename std::remove_const<T>::type ( &ptr )[C] ) VULKAN_HPP_NOEXCEPT
+ : m_count( C )
+ , m_ptr( ptr )
+ {
+ }
+
+ template <std::size_t C, typename B = T, typename std::enable_if<std::is_const<B>::value, int>::type = 0>
+ ArrayProxyNoTemporaries( typename std::remove_const<T>::type( &&ptr )[C] ) = delete;
+
+ ArrayProxyNoTemporaries( std::initializer_list<T> const & list ) VULKAN_HPP_NOEXCEPT
+ : m_count( static_cast<uint32_t>( list.size() ) )
+ , m_ptr( list.begin() )
+ {
+ }
+
+ ArrayProxyNoTemporaries( std::initializer_list<T> const && list ) = delete;
+
+ template <typename B = T, typename std::enable_if<std::is_const<B>::value, int>::type = 0>
+ ArrayProxyNoTemporaries( std::initializer_list<typename std::remove_const<T>::type> const & list ) VULKAN_HPP_NOEXCEPT
+ : m_count( static_cast<uint32_t>( list.size() ) )
+ , m_ptr( list.begin() )
+ {
+ }
+
+ template <typename B = T, typename std::enable_if<std::is_const<B>::value, int>::type = 0>
+ ArrayProxyNoTemporaries( std::initializer_list<typename std::remove_const<T>::type> const && list ) = delete;
+
+ ArrayProxyNoTemporaries( std::initializer_list<T> & list ) VULKAN_HPP_NOEXCEPT
+ : m_count( static_cast<uint32_t>( list.size() ) )
+ , m_ptr( list.begin() )
+ {
+ }
+
+ ArrayProxyNoTemporaries( std::initializer_list<T> && list ) = delete;
+
+ template <typename B = T, typename std::enable_if<std::is_const<B>::value, int>::type = 0>
+ ArrayProxyNoTemporaries( std::initializer_list<typename std::remove_const<T>::type> & list ) VULKAN_HPP_NOEXCEPT
+ : m_count( static_cast<uint32_t>( list.size() ) )
+ , m_ptr( list.begin() )
+ {
+ }
+
+ template <typename B = T, typename std::enable_if<std::is_const<B>::value, int>::type = 0>
+ ArrayProxyNoTemporaries( std::initializer_list<typename std::remove_const<T>::type> && list ) = delete;
+
+ // Any type with a .data() return type implicitly convertible to T*, and a // .size() return type implicitly
+ // convertible to size_t.
+ template <typename V,
+ typename std::enable_if<std::is_convertible<decltype( std::declval<V>().data() ), T *>::value &&
+ std::is_convertible<decltype( std::declval<V>().size() ), std::size_t>::value>::type * = nullptr>
+ ArrayProxyNoTemporaries( V & v ) VULKAN_HPP_NOEXCEPT
+ : m_count( static_cast<uint32_t>( v.size() ) )
+ , m_ptr( v.data() )
+ {
+ }
+
+ const T * begin() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_ptr;
+ }
+
+ const T * end() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_ptr + m_count;
+ }
+
+ const T & front() const VULKAN_HPP_NOEXCEPT
+ {
+ VULKAN_HPP_ASSERT( m_count && m_ptr );
+ return *m_ptr;
+ }
+
+ const T & back() const VULKAN_HPP_NOEXCEPT
+ {
+ VULKAN_HPP_ASSERT( m_count && m_ptr );
+ return *( m_ptr + m_count - 1 );
+ }
+
+ bool empty() const VULKAN_HPP_NOEXCEPT
+ {
+ return ( m_count == 0 );
+ }
+
+ uint32_t size() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_count;
+ }
+
+ T * data() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_ptr;
+ }
+
+ private:
+ uint32_t m_count;
+ T * m_ptr;
+ };
+
+ template <typename T>
+ class StridedArrayProxy : protected ArrayProxy<T>
+ {
+ public:
+ using ArrayProxy<T>::ArrayProxy;
+
+ StridedArrayProxy( uint32_t count, T const * ptr, uint32_t stride ) VULKAN_HPP_NOEXCEPT
+ : ArrayProxy<T>( count, ptr )
+ , m_stride( stride )
+ {
+ VULKAN_HPP_ASSERT( sizeof( T ) <= stride );
+ }
+
+ using ArrayProxy<T>::begin;
+
+ const T * end() const VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast<T const *>( static_cast<uint8_t const *>( begin() ) + size() * m_stride );
+ }
+
+ using ArrayProxy<T>::front;
+
+ const T & back() const VULKAN_HPP_NOEXCEPT
+ {
+ VULKAN_HPP_ASSERT( begin() && size() );
+ return *reinterpret_cast<T const *>( static_cast<uint8_t const *>( begin() ) + ( size() - 1 ) * m_stride );
+ }
+
+ using ArrayProxy<T>::empty;
+ using ArrayProxy<T>::size;
+ using ArrayProxy<T>::data;
+
+ uint32_t stride() const
+ {
+ return m_stride;
+ }
+
+ private:
+ uint32_t m_stride = sizeof( T );
+ };
+
+ template <typename RefType>
+ class Optional
+ {
+ public:
+ Optional( RefType & reference ) VULKAN_HPP_NOEXCEPT
+ {
+ m_ptr = &reference;
+ }
+ Optional( RefType * ptr ) VULKAN_HPP_NOEXCEPT
+ {
+ m_ptr = ptr;
+ }
+ Optional( std::nullptr_t ) VULKAN_HPP_NOEXCEPT
+ {
+ m_ptr = nullptr;
+ }
+
+ operator RefType *() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_ptr;
+ }
+ RefType const * operator->() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_ptr;
+ }
+ explicit operator bool() const VULKAN_HPP_NOEXCEPT
+ {
+ return !!m_ptr;
+ }
+
+ private:
+ RefType * m_ptr;
+ };
+
+ template <typename X, typename Y>
+ struct StructExtends
+ {
+ enum
+ {
+ value = false
+ };
+ };
+
+ template <typename Type, class...>
+ struct IsPartOfStructureChain
+ {
+ static const bool valid = false;
+ };
+
+ template <typename Type, typename Head, typename... Tail>
+ struct IsPartOfStructureChain<Type, Head, Tail...>
+ {
+ static const bool valid = std::is_same<Type, Head>::value || IsPartOfStructureChain<Type, Tail...>::valid;
+ };
+
+ template <size_t Index, typename T, typename... ChainElements>
+ struct StructureChainContains
+ {
+ static const bool value = std::is_same<T, typename std::tuple_element<Index, std::tuple<ChainElements...>>::type>::value ||
+ StructureChainContains<Index - 1, T, ChainElements...>::value;
+ };
+
+ template <typename T, typename... ChainElements>
+ struct StructureChainContains<0, T, ChainElements...>
+ {
+ static const bool value = std::is_same<T, typename std::tuple_element<0, std::tuple<ChainElements...>>::type>::value;
+ };
+
+ template <size_t Index, typename... ChainElements>
+ struct StructureChainValidation
+ {
+ using TestType = typename std::tuple_element<Index, std::tuple<ChainElements...>>::type;
+ static const bool valid = StructExtends<TestType, typename std::tuple_element<0, std::tuple<ChainElements...>>::type>::value &&
+ ( TestType::allowDuplicate || !StructureChainContains<Index - 1, TestType, ChainElements...>::value ) &&
+ StructureChainValidation<Index - 1, ChainElements...>::valid;
+ };
+
+ template <typename... ChainElements>
+ struct StructureChainValidation<0, ChainElements...>
+ {
+ static const bool valid = true;
+ };
+
+ template <typename... ChainElements>
+ class StructureChain : public std::tuple<ChainElements...>
+ {
+ public:
+ StructureChain() VULKAN_HPP_NOEXCEPT
+ {
+ static_assert( StructureChainValidation<sizeof...( ChainElements ) - 1, ChainElements...>::valid, "The structure chain is not valid!" );
+ link<sizeof...( ChainElements ) - 1>();
+ }
+
+ StructureChain( StructureChain const & rhs ) VULKAN_HPP_NOEXCEPT : std::tuple<ChainElements...>( rhs )
+ {
+ static_assert( StructureChainValidation<sizeof...( ChainElements ) - 1, ChainElements...>::valid, "The structure chain is not valid!" );
+ link( &std::get<0>( *this ),
+ &std::get<0>( rhs ),
+ reinterpret_cast<VkBaseOutStructure *>( &std::get<0>( *this ) ),
+ reinterpret_cast<VkBaseInStructure const *>( &std::get<0>( rhs ) ) );
+ }
+
+ StructureChain( StructureChain && rhs ) VULKAN_HPP_NOEXCEPT : std::tuple<ChainElements...>( std::forward<std::tuple<ChainElements...>>( rhs ) )
+ {
+ static_assert( StructureChainValidation<sizeof...( ChainElements ) - 1, ChainElements...>::valid, "The structure chain is not valid!" );
+ link( &std::get<0>( *this ),
+ &std::get<0>( rhs ),
+ reinterpret_cast<VkBaseOutStructure *>( &std::get<0>( *this ) ),
+ reinterpret_cast<VkBaseInStructure const *>( &std::get<0>( rhs ) ) );
+ }
+
+ StructureChain( ChainElements const &... elems ) VULKAN_HPP_NOEXCEPT : std::tuple<ChainElements...>( elems... )
+ {
+ static_assert( StructureChainValidation<sizeof...( ChainElements ) - 1, ChainElements...>::valid, "The structure chain is not valid!" );
+ link<sizeof...( ChainElements ) - 1>();
+ }
+
+ StructureChain & operator=( StructureChain const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ std::tuple<ChainElements...>::operator=( rhs );
+ link( &std::get<0>( *this ),
+ &std::get<0>( rhs ),
+ reinterpret_cast<VkBaseOutStructure *>( &std::get<0>( *this ) ),
+ reinterpret_cast<VkBaseInStructure const *>( &std::get<0>( rhs ) ) );
+ return *this;
+ }
+
+ StructureChain & operator=( StructureChain && rhs ) = delete;
+
+ template <typename T = typename std::tuple_element<0, std::tuple<ChainElements...>>::type, size_t Which = 0>
+ T & get() VULKAN_HPP_NOEXCEPT
+ {
+ return std::get<ChainElementIndex<0, T, Which, void, ChainElements...>::value>( static_cast<std::tuple<ChainElements...> &>( *this ) );
+ }
+
+ template <typename T = typename std::tuple_element<0, std::tuple<ChainElements...>>::type, size_t Which = 0>
+ T const & get() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::get<ChainElementIndex<0, T, Which, void, ChainElements...>::value>( static_cast<std::tuple<ChainElements...> const &>( *this ) );
+ }
+
+ template <typename T0, typename T1, typename... Ts>
+ std::tuple<T0 &, T1 &, Ts &...> get() VULKAN_HPP_NOEXCEPT
+ {
+ return std::tie( get<T0>(), get<T1>(), get<Ts>()... );
+ }
+
+ template <typename T0, typename T1, typename... Ts>
+ std::tuple<T0 const &, T1 const &, Ts const &...> get() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::tie( get<T0>(), get<T1>(), get<Ts>()... );
+ }
+
+ template <typename ClassType, size_t Which = 0>
+ typename std::enable_if<std::is_same<ClassType, typename std::tuple_element<0, std::tuple<ChainElements...>>::type>::value && ( Which == 0 ), bool>::type
+ isLinked() const VULKAN_HPP_NOEXCEPT
+ {
+ return true;
+ }
+
+ template <typename ClassType, size_t Which = 0>
+ typename std::enable_if<!std::is_same<ClassType, typename std::tuple_element<0, std::tuple<ChainElements...>>::type>::value || ( Which != 0 ), bool>::type
+ isLinked() const VULKAN_HPP_NOEXCEPT
+ {
+ static_assert( IsPartOfStructureChain<ClassType, ChainElements...>::valid, "Can't unlink Structure that's not part of this StructureChain!" );
+ return isLinked( reinterpret_cast<VkBaseInStructure const *>( &get<ClassType, Which>() ) );
+ }
+
+ template <typename ClassType, size_t Which = 0>
+ typename std::enable_if<!std::is_same<ClassType, typename std::tuple_element<0, std::tuple<ChainElements...>>::type>::value || ( Which != 0 ), void>::type
+ relink() VULKAN_HPP_NOEXCEPT
+ {
+ static_assert( IsPartOfStructureChain<ClassType, ChainElements...>::valid, "Can't relink Structure that's not part of this StructureChain!" );
+ auto pNext = reinterpret_cast<VkBaseInStructure *>( &get<ClassType, Which>() );
+ VULKAN_HPP_ASSERT( !isLinked( pNext ) );
+ auto & headElement = std::get<0>( static_cast<std::tuple<ChainElements...> &>( *this ) );
+ pNext->pNext = reinterpret_cast<VkBaseInStructure const *>( headElement.pNext );
+ headElement.pNext = pNext;
+ }
+
+ template <typename ClassType, size_t Which = 0>
+ typename std::enable_if<!std::is_same<ClassType, typename std::tuple_element<0, std::tuple<ChainElements...>>::type>::value || ( Which != 0 ), void>::type
+ unlink() VULKAN_HPP_NOEXCEPT
+ {
+ static_assert( IsPartOfStructureChain<ClassType, ChainElements...>::valid, "Can't unlink Structure that's not part of this StructureChain!" );
+ unlink( reinterpret_cast<VkBaseOutStructure const *>( &get<ClassType, Which>() ) );
+ }
+
+ private:
+ template <int Index, typename T, int Which, typename, class First, class... Types>
+ struct ChainElementIndex : ChainElementIndex<Index + 1, T, Which, void, Types...>
+ {
+ };
+
+ template <int Index, typename T, int Which, class First, class... Types>
+ struct ChainElementIndex<Index, T, Which, typename std::enable_if<!std::is_same<T, First>::value, void>::type, First, Types...>
+ : ChainElementIndex<Index + 1, T, Which, void, Types...>
+ {
+ };
+
+ template <int Index, typename T, int Which, class First, class... Types>
+ struct ChainElementIndex<Index, T, Which, typename std::enable_if<std::is_same<T, First>::value, void>::type, First, Types...>
+ : ChainElementIndex<Index + 1, T, Which - 1, void, Types...>
+ {
+ };
+
+ template <int Index, typename T, class First, class... Types>
+ struct ChainElementIndex<Index, T, 0, typename std::enable_if<std::is_same<T, First>::value, void>::type, First, Types...>
+ : std::integral_constant<int, Index>
+ {
+ };
+
+ bool isLinked( VkBaseInStructure const * pNext ) const VULKAN_HPP_NOEXCEPT
+ {
+ VkBaseInStructure const * elementPtr =
+ reinterpret_cast<VkBaseInStructure const *>( &std::get<0>( static_cast<std::tuple<ChainElements...> const &>( *this ) ) );
+ while ( elementPtr )
+ {
+ if ( elementPtr->pNext == pNext )
+ {
+ return true;
+ }
+ elementPtr = elementPtr->pNext;
+ }
+ return false;
+ }
+
+ template <size_t Index>
+ typename std::enable_if<Index != 0, void>::type link() VULKAN_HPP_NOEXCEPT
+ {
+ auto & x = std::get<Index - 1>( static_cast<std::tuple<ChainElements...> &>( *this ) );
+ x.pNext = &std::get<Index>( static_cast<std::tuple<ChainElements...> &>( *this ) );
+ link<Index - 1>();
+ }
+
+ template <size_t Index>
+ typename std::enable_if<Index == 0, void>::type link() VULKAN_HPP_NOEXCEPT
+ {
+ }
+
+ void link( void * dstBase, void const * srcBase, VkBaseOutStructure * dst, VkBaseInStructure const * src )
+ {
+ while ( src->pNext )
+ {
+ std::ptrdiff_t offset = reinterpret_cast<char const *>( src->pNext ) - reinterpret_cast<char const *>( srcBase );
+ dst->pNext = reinterpret_cast<VkBaseOutStructure *>( reinterpret_cast<char *>( dstBase ) + offset );
+ dst = dst->pNext;
+ src = src->pNext;
+ }
+ dst->pNext = nullptr;
+ }
+
+ void unlink( VkBaseOutStructure const * pNext ) VULKAN_HPP_NOEXCEPT
+ {
+ VkBaseOutStructure * elementPtr = reinterpret_cast<VkBaseOutStructure *>( &std::get<0>( static_cast<std::tuple<ChainElements...> &>( *this ) ) );
+ while ( elementPtr && ( elementPtr->pNext != pNext ) )
+ {
+ elementPtr = elementPtr->pNext;
+ }
+ if ( elementPtr )
+ {
+ elementPtr->pNext = pNext->pNext;
+ }
+ else
+ {
+ VULKAN_HPP_ASSERT( false ); // fires, if the ClassType member has already been unlinked !
+ }
+ }
+ };
+
+# if !defined( VULKAN_HPP_NO_SMART_HANDLE )
+ template <typename Type, typename Dispatch>
+ class UniqueHandleTraits;
+
+ template <typename Type, typename Dispatch>
+ class UniqueHandle : public UniqueHandleTraits<Type, Dispatch>::deleter
+ {
+ private:
+ using Deleter = typename UniqueHandleTraits<Type, Dispatch>::deleter;
+
+ public:
+ using element_type = Type;
+
+ UniqueHandle() : Deleter(), m_value() {}
+
+ explicit UniqueHandle( Type const & value, Deleter const & deleter = Deleter() ) VULKAN_HPP_NOEXCEPT
+ : Deleter( deleter )
+ , m_value( value )
+ {
+ }
+
+ UniqueHandle( UniqueHandle const & ) = delete;
+
+ UniqueHandle( UniqueHandle && other ) VULKAN_HPP_NOEXCEPT
+ : Deleter( std::move( static_cast<Deleter &>( other ) ) )
+ , m_value( other.release() )
+ {
+ }
+
+ ~UniqueHandle() VULKAN_HPP_NOEXCEPT
+ {
+ if ( m_value )
+ {
+ this->destroy( m_value );
+ }
+ }
+
+ UniqueHandle & operator=( UniqueHandle const & ) = delete;
+
+ UniqueHandle & operator=( UniqueHandle && other ) VULKAN_HPP_NOEXCEPT
+ {
+ reset( other.release() );
+ *static_cast<Deleter *>( this ) = std::move( static_cast<Deleter &>( other ) );
+ return *this;
+ }
+
+ explicit operator bool() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_value.operator bool();
+ }
+
+ Type const * operator->() const VULKAN_HPP_NOEXCEPT
+ {
+ return &m_value;
+ }
+
+ Type * operator->() VULKAN_HPP_NOEXCEPT
+ {
+ return &m_value;
+ }
+
+ Type const & operator*() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_value;
+ }
+
+ Type & operator*() VULKAN_HPP_NOEXCEPT
+ {
+ return m_value;
+ }
+
+ const Type & get() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_value;
+ }
+
+ Type & get() VULKAN_HPP_NOEXCEPT
+ {
+ return m_value;
+ }
+
+ void reset( Type const & value = Type() ) VULKAN_HPP_NOEXCEPT
+ {
+ if ( m_value != value )
+ {
+ if ( m_value )
+ {
+ this->destroy( m_value );
+ }
+ m_value = value;
+ }
+ }
+
+ Type release() VULKAN_HPP_NOEXCEPT
+ {
+ Type value = m_value;
+ m_value = nullptr;
+ return value;
+ }
+
+ void swap( UniqueHandle<Type, Dispatch> & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ std::swap( m_value, rhs.m_value );
+ std::swap( static_cast<Deleter &>( *this ), static_cast<Deleter &>( rhs ) );
+ }
+
+ private:
+ Type m_value;
+ };
+
+ template <typename UniqueType>
+ VULKAN_HPP_INLINE std::vector<typename UniqueType::element_type> uniqueToRaw( std::vector<UniqueType> const & handles )
+ {
+ std::vector<typename UniqueType::element_type> newBuffer( handles.size() );
+ std::transform( handles.begin(), handles.end(), newBuffer.begin(), []( UniqueType const & handle ) { return handle.get(); } );
+ return newBuffer;
+ }
+
+ template <typename Type, typename Dispatch>
+ VULKAN_HPP_INLINE void swap( UniqueHandle<Type, Dispatch> & lhs, UniqueHandle<Type, Dispatch> & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ lhs.swap( rhs );
+ }
+# endif
+#endif // VULKAN_HPP_DISABLE_ENHANCED_MODE
+
+ class DispatchLoaderBase
+ {
+ public:
+ DispatchLoaderBase() = default;
+ DispatchLoaderBase( std::nullptr_t )
+#if !defined( NDEBUG )
+ : m_valid( false )
+#endif
+ {
+ }
+
+#if !defined( NDEBUG )
+ size_t getVkHeaderVersion() const
+ {
+ VULKAN_HPP_ASSERT( m_valid );
+ return vkHeaderVersion;
+ }
+
+ private:
+ size_t vkHeaderVersion = VK_HEADER_VERSION;
+ bool m_valid = true;
+#endif
+ };
+
+#if !defined( VK_NO_PROTOTYPES )
+ class DispatchLoaderStatic : public DispatchLoaderBase
+ {
+ public:
+ //=== VK_VERSION_1_0 ===
+
+ VkResult
+ vkCreateInstance( const VkInstanceCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkInstance * pInstance ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateInstance( pCreateInfo, pAllocator, pInstance );
+ }
+
+ void vkDestroyInstance( VkInstance instance, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyInstance( instance, pAllocator );
+ }
+
+ VkResult vkEnumeratePhysicalDevices( VkInstance instance, uint32_t * pPhysicalDeviceCount, VkPhysicalDevice * pPhysicalDevices ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkEnumeratePhysicalDevices( instance, pPhysicalDeviceCount, pPhysicalDevices );
+ }
+
+ void vkGetPhysicalDeviceFeatures( VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures * pFeatures ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceFeatures( physicalDevice, pFeatures );
+ }
+
+ void
+ vkGetPhysicalDeviceFormatProperties( VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties * pFormatProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceFormatProperties( physicalDevice, format, pFormatProperties );
+ }
+
+ VkResult vkGetPhysicalDeviceImageFormatProperties( VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags flags,
+ VkImageFormatProperties * pImageFormatProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceImageFormatProperties( physicalDevice, format, type, tiling, usage, flags, pImageFormatProperties );
+ }
+
+ void vkGetPhysicalDeviceProperties( VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceProperties( physicalDevice, pProperties );
+ }
+
+ void vkGetPhysicalDeviceQueueFamilyProperties( VkPhysicalDevice physicalDevice,
+ uint32_t * pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties * pQueueFamilyProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceQueueFamilyProperties( physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties );
+ }
+
+ void vkGetPhysicalDeviceMemoryProperties( VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties * pMemoryProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceMemoryProperties( physicalDevice, pMemoryProperties );
+ }
+
+ PFN_vkVoidFunction vkGetInstanceProcAddr( VkInstance instance, const char * pName ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetInstanceProcAddr( instance, pName );
+ }
+
+ PFN_vkVoidFunction vkGetDeviceProcAddr( VkDevice device, const char * pName ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceProcAddr( device, pName );
+ }
+
+ VkResult vkCreateDevice( VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkDevice * pDevice ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateDevice( physicalDevice, pCreateInfo, pAllocator, pDevice );
+ }
+
+ void vkDestroyDevice( VkDevice device, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyDevice( device, pAllocator );
+ }
+
+ VkResult vkEnumerateInstanceExtensionProperties( const char * pLayerName,
+ uint32_t * pPropertyCount,
+ VkExtensionProperties * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkEnumerateInstanceExtensionProperties( pLayerName, pPropertyCount, pProperties );
+ }
+
+ VkResult vkEnumerateDeviceExtensionProperties( VkPhysicalDevice physicalDevice,
+ const char * pLayerName,
+ uint32_t * pPropertyCount,
+ VkExtensionProperties * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkEnumerateDeviceExtensionProperties( physicalDevice, pLayerName, pPropertyCount, pProperties );
+ }
+
+ VkResult vkEnumerateInstanceLayerProperties( uint32_t * pPropertyCount, VkLayerProperties * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkEnumerateInstanceLayerProperties( pPropertyCount, pProperties );
+ }
+
+ VkResult
+ vkEnumerateDeviceLayerProperties( VkPhysicalDevice physicalDevice, uint32_t * pPropertyCount, VkLayerProperties * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkEnumerateDeviceLayerProperties( physicalDevice, pPropertyCount, pProperties );
+ }
+
+ void vkGetDeviceQueue( VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue * pQueue ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceQueue( device, queueFamilyIndex, queueIndex, pQueue );
+ }
+
+ VkResult vkQueueSubmit( VkQueue queue, uint32_t submitCount, const VkSubmitInfo * pSubmits, VkFence fence ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkQueueSubmit( queue, submitCount, pSubmits, fence );
+ }
+
+ VkResult vkQueueWaitIdle( VkQueue queue ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkQueueWaitIdle( queue );
+ }
+
+ VkResult vkDeviceWaitIdle( VkDevice device ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDeviceWaitIdle( device );
+ }
+
+ VkResult vkAllocateMemory( VkDevice device,
+ const VkMemoryAllocateInfo * pAllocateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkDeviceMemory * pMemory ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkAllocateMemory( device, pAllocateInfo, pAllocator, pMemory );
+ }
+
+ void vkFreeMemory( VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkFreeMemory( device, memory, pAllocator );
+ }
+
+ VkResult vkMapMemory( VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void ** ppData ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkMapMemory( device, memory, offset, size, flags, ppData );
+ }
+
+ void vkUnmapMemory( VkDevice device, VkDeviceMemory memory ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkUnmapMemory( device, memory );
+ }
+
+ VkResult vkFlushMappedMemoryRanges( VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange * pMemoryRanges ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkFlushMappedMemoryRanges( device, memoryRangeCount, pMemoryRanges );
+ }
+
+ VkResult vkInvalidateMappedMemoryRanges( VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange * pMemoryRanges ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkInvalidateMappedMemoryRanges( device, memoryRangeCount, pMemoryRanges );
+ }
+
+ void vkGetDeviceMemoryCommitment( VkDevice device, VkDeviceMemory memory, VkDeviceSize * pCommittedMemoryInBytes ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceMemoryCommitment( device, memory, pCommittedMemoryInBytes );
+ }
+
+ VkResult vkBindBufferMemory( VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBindBufferMemory( device, buffer, memory, memoryOffset );
+ }
+
+ VkResult vkBindImageMemory( VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBindImageMemory( device, image, memory, memoryOffset );
+ }
+
+ void vkGetBufferMemoryRequirements( VkDevice device, VkBuffer buffer, VkMemoryRequirements * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetBufferMemoryRequirements( device, buffer, pMemoryRequirements );
+ }
+
+ void vkGetImageMemoryRequirements( VkDevice device, VkImage image, VkMemoryRequirements * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetImageMemoryRequirements( device, image, pMemoryRequirements );
+ }
+
+ void vkGetImageSparseMemoryRequirements( VkDevice device,
+ VkImage image,
+ uint32_t * pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements * pSparseMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetImageSparseMemoryRequirements( device, image, pSparseMemoryRequirementCount, pSparseMemoryRequirements );
+ }
+
+ void vkGetPhysicalDeviceSparseImageFormatProperties( VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkSampleCountFlagBits samples,
+ VkImageUsageFlags usage,
+ VkImageTiling tiling,
+ uint32_t * pPropertyCount,
+ VkSparseImageFormatProperties * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSparseImageFormatProperties( physicalDevice, format, type, samples, usage, tiling, pPropertyCount, pProperties );
+ }
+
+ VkResult vkQueueBindSparse( VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo * pBindInfo, VkFence fence ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkQueueBindSparse( queue, bindInfoCount, pBindInfo, fence );
+ }
+
+ VkResult vkCreateFence( VkDevice device,
+ const VkFenceCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkFence * pFence ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateFence( device, pCreateInfo, pAllocator, pFence );
+ }
+
+ void vkDestroyFence( VkDevice device, VkFence fence, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyFence( device, fence, pAllocator );
+ }
+
+ VkResult vkResetFences( VkDevice device, uint32_t fenceCount, const VkFence * pFences ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkResetFences( device, fenceCount, pFences );
+ }
+
+ VkResult vkGetFenceStatus( VkDevice device, VkFence fence ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetFenceStatus( device, fence );
+ }
+
+ VkResult vkWaitForFences( VkDevice device, uint32_t fenceCount, const VkFence * pFences, VkBool32 waitAll, uint64_t timeout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkWaitForFences( device, fenceCount, pFences, waitAll, timeout );
+ }
+
+ VkResult vkCreateSemaphore( VkDevice device,
+ const VkSemaphoreCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSemaphore * pSemaphore ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateSemaphore( device, pCreateInfo, pAllocator, pSemaphore );
+ }
+
+ void vkDestroySemaphore( VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroySemaphore( device, semaphore, pAllocator );
+ }
+
+ VkResult vkCreateEvent( VkDevice device,
+ const VkEventCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkEvent * pEvent ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateEvent( device, pCreateInfo, pAllocator, pEvent );
+ }
+
+ void vkDestroyEvent( VkDevice device, VkEvent event, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyEvent( device, event, pAllocator );
+ }
+
+ VkResult vkGetEventStatus( VkDevice device, VkEvent event ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetEventStatus( device, event );
+ }
+
+ VkResult vkSetEvent( VkDevice device, VkEvent event ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSetEvent( device, event );
+ }
+
+ VkResult vkResetEvent( VkDevice device, VkEvent event ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkResetEvent( device, event );
+ }
+
+ VkResult vkCreateQueryPool( VkDevice device,
+ const VkQueryPoolCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkQueryPool * pQueryPool ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateQueryPool( device, pCreateInfo, pAllocator, pQueryPool );
+ }
+
+ void vkDestroyQueryPool( VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyQueryPool( device, queryPool, pAllocator );
+ }
+
+ VkResult vkGetQueryPoolResults( VkDevice device,
+ VkQueryPool queryPool,
+ uint32_t firstQuery,
+ uint32_t queryCount,
+ size_t dataSize,
+ void * pData,
+ VkDeviceSize stride,
+ VkQueryResultFlags flags ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetQueryPoolResults( device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags );
+ }
+
+ VkResult vkCreateBuffer( VkDevice device,
+ const VkBufferCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkBuffer * pBuffer ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateBuffer( device, pCreateInfo, pAllocator, pBuffer );
+ }
+
+ void vkDestroyBuffer( VkDevice device, VkBuffer buffer, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyBuffer( device, buffer, pAllocator );
+ }
+
+ VkResult vkCreateBufferView( VkDevice device,
+ const VkBufferViewCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkBufferView * pView ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateBufferView( device, pCreateInfo, pAllocator, pView );
+ }
+
+ void vkDestroyBufferView( VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyBufferView( device, bufferView, pAllocator );
+ }
+
+ VkResult vkCreateImage( VkDevice device,
+ const VkImageCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkImage * pImage ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateImage( device, pCreateInfo, pAllocator, pImage );
+ }
+
+ void vkDestroyImage( VkDevice device, VkImage image, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyImage( device, image, pAllocator );
+ }
+
+ void vkGetImageSubresourceLayout( VkDevice device,
+ VkImage image,
+ const VkImageSubresource * pSubresource,
+ VkSubresourceLayout * pLayout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetImageSubresourceLayout( device, image, pSubresource, pLayout );
+ }
+
+ VkResult vkCreateImageView( VkDevice device,
+ const VkImageViewCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkImageView * pView ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateImageView( device, pCreateInfo, pAllocator, pView );
+ }
+
+ void vkDestroyImageView( VkDevice device, VkImageView imageView, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyImageView( device, imageView, pAllocator );
+ }
+
+ VkResult vkCreateShaderModule( VkDevice device,
+ const VkShaderModuleCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkShaderModule * pShaderModule ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateShaderModule( device, pCreateInfo, pAllocator, pShaderModule );
+ }
+
+ void vkDestroyShaderModule( VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyShaderModule( device, shaderModule, pAllocator );
+ }
+
+ VkResult vkCreatePipelineCache( VkDevice device,
+ const VkPipelineCacheCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkPipelineCache * pPipelineCache ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreatePipelineCache( device, pCreateInfo, pAllocator, pPipelineCache );
+ }
+
+ void vkDestroyPipelineCache( VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyPipelineCache( device, pipelineCache, pAllocator );
+ }
+
+ VkResult vkGetPipelineCacheData( VkDevice device, VkPipelineCache pipelineCache, size_t * pDataSize, void * pData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPipelineCacheData( device, pipelineCache, pDataSize, pData );
+ }
+
+ VkResult
+ vkMergePipelineCaches( VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache * pSrcCaches ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkMergePipelineCaches( device, dstCache, srcCacheCount, pSrcCaches );
+ }
+
+ VkResult vkCreateGraphicsPipelines( VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkGraphicsPipelineCreateInfo * pCreateInfos,
+ const VkAllocationCallbacks * pAllocator,
+ VkPipeline * pPipelines ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateGraphicsPipelines( device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines );
+ }
+
+ VkResult vkCreateComputePipelines( VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkComputePipelineCreateInfo * pCreateInfos,
+ const VkAllocationCallbacks * pAllocator,
+ VkPipeline * pPipelines ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateComputePipelines( device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines );
+ }
+
+ void vkDestroyPipeline( VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyPipeline( device, pipeline, pAllocator );
+ }
+
+ VkResult vkCreatePipelineLayout( VkDevice device,
+ const VkPipelineLayoutCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkPipelineLayout * pPipelineLayout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreatePipelineLayout( device, pCreateInfo, pAllocator, pPipelineLayout );
+ }
+
+ void vkDestroyPipelineLayout( VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyPipelineLayout( device, pipelineLayout, pAllocator );
+ }
+
+ VkResult vkCreateSampler( VkDevice device,
+ const VkSamplerCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSampler * pSampler ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateSampler( device, pCreateInfo, pAllocator, pSampler );
+ }
+
+ void vkDestroySampler( VkDevice device, VkSampler sampler, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroySampler( device, sampler, pAllocator );
+ }
+
+ VkResult vkCreateDescriptorSetLayout( VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkDescriptorSetLayout * pSetLayout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateDescriptorSetLayout( device, pCreateInfo, pAllocator, pSetLayout );
+ }
+
+ void vkDestroyDescriptorSetLayout( VkDevice device,
+ VkDescriptorSetLayout descriptorSetLayout,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyDescriptorSetLayout( device, descriptorSetLayout, pAllocator );
+ }
+
+ VkResult vkCreateDescriptorPool( VkDevice device,
+ const VkDescriptorPoolCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkDescriptorPool * pDescriptorPool ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateDescriptorPool( device, pCreateInfo, pAllocator, pDescriptorPool );
+ }
+
+ void vkDestroyDescriptorPool( VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyDescriptorPool( device, descriptorPool, pAllocator );
+ }
+
+ VkResult vkResetDescriptorPool( VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkResetDescriptorPool( device, descriptorPool, flags );
+ }
+
+ VkResult vkAllocateDescriptorSets( VkDevice device,
+ const VkDescriptorSetAllocateInfo * pAllocateInfo,
+ VkDescriptorSet * pDescriptorSets ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkAllocateDescriptorSets( device, pAllocateInfo, pDescriptorSets );
+ }
+
+ VkResult vkFreeDescriptorSets( VkDevice device,
+ VkDescriptorPool descriptorPool,
+ uint32_t descriptorSetCount,
+ const VkDescriptorSet * pDescriptorSets ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkFreeDescriptorSets( device, descriptorPool, descriptorSetCount, pDescriptorSets );
+ }
+
+ void vkUpdateDescriptorSets( VkDevice device,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet * pDescriptorWrites,
+ uint32_t descriptorCopyCount,
+ const VkCopyDescriptorSet * pDescriptorCopies ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkUpdateDescriptorSets( device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount, pDescriptorCopies );
+ }
+
+ VkResult vkCreateFramebuffer( VkDevice device,
+ const VkFramebufferCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkFramebuffer * pFramebuffer ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateFramebuffer( device, pCreateInfo, pAllocator, pFramebuffer );
+ }
+
+ void vkDestroyFramebuffer( VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyFramebuffer( device, framebuffer, pAllocator );
+ }
+
+ VkResult vkCreateRenderPass( VkDevice device,
+ const VkRenderPassCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkRenderPass * pRenderPass ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateRenderPass( device, pCreateInfo, pAllocator, pRenderPass );
+ }
+
+ void vkDestroyRenderPass( VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyRenderPass( device, renderPass, pAllocator );
+ }
+
+ void vkGetRenderAreaGranularity( VkDevice device, VkRenderPass renderPass, VkExtent2D * pGranularity ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetRenderAreaGranularity( device, renderPass, pGranularity );
+ }
+
+ VkResult vkCreateCommandPool( VkDevice device,
+ const VkCommandPoolCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkCommandPool * pCommandPool ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateCommandPool( device, pCreateInfo, pAllocator, pCommandPool );
+ }
+
+ void vkDestroyCommandPool( VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyCommandPool( device, commandPool, pAllocator );
+ }
+
+ VkResult vkResetCommandPool( VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkResetCommandPool( device, commandPool, flags );
+ }
+
+ VkResult vkAllocateCommandBuffers( VkDevice device,
+ const VkCommandBufferAllocateInfo * pAllocateInfo,
+ VkCommandBuffer * pCommandBuffers ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkAllocateCommandBuffers( device, pAllocateInfo, pCommandBuffers );
+ }
+
+ void vkFreeCommandBuffers( VkDevice device,
+ VkCommandPool commandPool,
+ uint32_t commandBufferCount,
+ const VkCommandBuffer * pCommandBuffers ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkFreeCommandBuffers( device, commandPool, commandBufferCount, pCommandBuffers );
+ }
+
+ VkResult vkBeginCommandBuffer( VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo * pBeginInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBeginCommandBuffer( commandBuffer, pBeginInfo );
+ }
+
+ VkResult vkEndCommandBuffer( VkCommandBuffer commandBuffer ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkEndCommandBuffer( commandBuffer );
+ }
+
+ VkResult vkResetCommandBuffer( VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkResetCommandBuffer( commandBuffer, flags );
+ }
+
+ void vkCmdBindPipeline( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBindPipeline( commandBuffer, pipelineBindPoint, pipeline );
+ }
+
+ void
+ vkCmdSetViewport( VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport * pViewports ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetViewport( commandBuffer, firstViewport, viewportCount, pViewports );
+ }
+
+ void vkCmdSetScissor( VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D * pScissors ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetScissor( commandBuffer, firstScissor, scissorCount, pScissors );
+ }
+
+ void vkCmdSetLineWidth( VkCommandBuffer commandBuffer, float lineWidth ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetLineWidth( commandBuffer, lineWidth );
+ }
+
+ void vkCmdSetDepthBias( VkCommandBuffer commandBuffer,
+ float depthBiasConstantFactor,
+ float depthBiasClamp,
+ float depthBiasSlopeFactor ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthBias( commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor );
+ }
+
+ void vkCmdSetBlendConstants( VkCommandBuffer commandBuffer, const float blendConstants[4] ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetBlendConstants( commandBuffer, blendConstants );
+ }
+
+ void vkCmdSetDepthBounds( VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthBounds( commandBuffer, minDepthBounds, maxDepthBounds );
+ }
+
+ void vkCmdSetStencilCompareMask( VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetStencilCompareMask( commandBuffer, faceMask, compareMask );
+ }
+
+ void vkCmdSetStencilWriteMask( VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetStencilWriteMask( commandBuffer, faceMask, writeMask );
+ }
+
+ void vkCmdSetStencilReference( VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetStencilReference( commandBuffer, faceMask, reference );
+ }
+
+ void vkCmdBindDescriptorSets( VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipelineLayout layout,
+ uint32_t firstSet,
+ uint32_t descriptorSetCount,
+ const VkDescriptorSet * pDescriptorSets,
+ uint32_t dynamicOffsetCount,
+ const uint32_t * pDynamicOffsets ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBindDescriptorSets(
+ commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets );
+ }
+
+ void vkCmdBindIndexBuffer( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBindIndexBuffer( commandBuffer, buffer, offset, indexType );
+ }
+
+ void vkCmdBindVertexBuffers( VkCommandBuffer commandBuffer,
+ uint32_t firstBinding,
+ uint32_t bindingCount,
+ const VkBuffer * pBuffers,
+ const VkDeviceSize * pOffsets ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBindVertexBuffers( commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets );
+ }
+
+ void vkCmdDraw( VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDraw( commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance );
+ }
+
+ void vkCmdDrawIndexed( VkCommandBuffer commandBuffer,
+ uint32_t indexCount,
+ uint32_t instanceCount,
+ uint32_t firstIndex,
+ int32_t vertexOffset,
+ uint32_t firstInstance ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawIndexed( commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance );
+ }
+
+ void vkCmdDrawIndirect( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawIndirect( commandBuffer, buffer, offset, drawCount, stride );
+ }
+
+ void vkCmdDrawIndexedIndirect( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawIndexedIndirect( commandBuffer, buffer, offset, drawCount, stride );
+ }
+
+ void vkCmdDispatch( VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDispatch( commandBuffer, groupCountX, groupCountY, groupCountZ );
+ }
+
+ void vkCmdDispatchIndirect( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDispatchIndirect( commandBuffer, buffer, offset );
+ }
+
+ void vkCmdCopyBuffer( VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy * pRegions ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyBuffer( commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions );
+ }
+
+ void vkCmdCopyImage( VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkImageCopy * pRegions ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyImage( commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions );
+ }
+
+ void vkCmdBlitImage( VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkImageBlit * pRegions,
+ VkFilter filter ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBlitImage( commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter );
+ }
+
+ void vkCmdCopyBufferToImage( VkCommandBuffer commandBuffer,
+ VkBuffer srcBuffer,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkBufferImageCopy * pRegions ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyBufferToImage( commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions );
+ }
+
+ void vkCmdCopyImageToBuffer( VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkBuffer dstBuffer,
+ uint32_t regionCount,
+ const VkBufferImageCopy * pRegions ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyImageToBuffer( commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions );
+ }
+
+ void vkCmdUpdateBuffer( VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void * pData ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdUpdateBuffer( commandBuffer, dstBuffer, dstOffset, dataSize, pData );
+ }
+
+ void
+ vkCmdFillBuffer( VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdFillBuffer( commandBuffer, dstBuffer, dstOffset, size, data );
+ }
+
+ void vkCmdClearColorImage( VkCommandBuffer commandBuffer,
+ VkImage image,
+ VkImageLayout imageLayout,
+ const VkClearColorValue * pColor,
+ uint32_t rangeCount,
+ const VkImageSubresourceRange * pRanges ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdClearColorImage( commandBuffer, image, imageLayout, pColor, rangeCount, pRanges );
+ }
+
+ void vkCmdClearDepthStencilImage( VkCommandBuffer commandBuffer,
+ VkImage image,
+ VkImageLayout imageLayout,
+ const VkClearDepthStencilValue * pDepthStencil,
+ uint32_t rangeCount,
+ const VkImageSubresourceRange * pRanges ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdClearDepthStencilImage( commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges );
+ }
+
+ void vkCmdClearAttachments( VkCommandBuffer commandBuffer,
+ uint32_t attachmentCount,
+ const VkClearAttachment * pAttachments,
+ uint32_t rectCount,
+ const VkClearRect * pRects ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdClearAttachments( commandBuffer, attachmentCount, pAttachments, rectCount, pRects );
+ }
+
+ void vkCmdResolveImage( VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkImageResolve * pRegions ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdResolveImage( commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions );
+ }
+
+ void vkCmdSetEvent( VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetEvent( commandBuffer, event, stageMask );
+ }
+
+ void vkCmdResetEvent( VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdResetEvent( commandBuffer, event, stageMask );
+ }
+
+ void vkCmdWaitEvents( VkCommandBuffer commandBuffer,
+ uint32_t eventCount,
+ const VkEvent * pEvents,
+ VkPipelineStageFlags srcStageMask,
+ VkPipelineStageFlags dstStageMask,
+ uint32_t memoryBarrierCount,
+ const VkMemoryBarrier * pMemoryBarriers,
+ uint32_t bufferMemoryBarrierCount,
+ const VkBufferMemoryBarrier * pBufferMemoryBarriers,
+ uint32_t imageMemoryBarrierCount,
+ const VkImageMemoryBarrier * pImageMemoryBarriers ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdWaitEvents( commandBuffer,
+ eventCount,
+ pEvents,
+ srcStageMask,
+ dstStageMask,
+ memoryBarrierCount,
+ pMemoryBarriers,
+ bufferMemoryBarrierCount,
+ pBufferMemoryBarriers,
+ imageMemoryBarrierCount,
+ pImageMemoryBarriers );
+ }
+
+ void vkCmdPipelineBarrier( VkCommandBuffer commandBuffer,
+ VkPipelineStageFlags srcStageMask,
+ VkPipelineStageFlags dstStageMask,
+ VkDependencyFlags dependencyFlags,
+ uint32_t memoryBarrierCount,
+ const VkMemoryBarrier * pMemoryBarriers,
+ uint32_t bufferMemoryBarrierCount,
+ const VkBufferMemoryBarrier * pBufferMemoryBarriers,
+ uint32_t imageMemoryBarrierCount,
+ const VkImageMemoryBarrier * pImageMemoryBarriers ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdPipelineBarrier( commandBuffer,
+ srcStageMask,
+ dstStageMask,
+ dependencyFlags,
+ memoryBarrierCount,
+ pMemoryBarriers,
+ bufferMemoryBarrierCount,
+ pBufferMemoryBarriers,
+ imageMemoryBarrierCount,
+ pImageMemoryBarriers );
+ }
+
+ void vkCmdBeginQuery( VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBeginQuery( commandBuffer, queryPool, query, flags );
+ }
+
+ void vkCmdEndQuery( VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEndQuery( commandBuffer, queryPool, query );
+ }
+
+ void vkCmdResetQueryPool( VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdResetQueryPool( commandBuffer, queryPool, firstQuery, queryCount );
+ }
+
+ void vkCmdWriteTimestamp( VkCommandBuffer commandBuffer,
+ VkPipelineStageFlagBits pipelineStage,
+ VkQueryPool queryPool,
+ uint32_t query ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdWriteTimestamp( commandBuffer, pipelineStage, queryPool, query );
+ }
+
+ void vkCmdCopyQueryPoolResults( VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t firstQuery,
+ uint32_t queryCount,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ VkDeviceSize stride,
+ VkQueryResultFlags flags ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyQueryPoolResults( commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags );
+ }
+
+ void vkCmdPushConstants( VkCommandBuffer commandBuffer,
+ VkPipelineLayout layout,
+ VkShaderStageFlags stageFlags,
+ uint32_t offset,
+ uint32_t size,
+ const void * pValues ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdPushConstants( commandBuffer, layout, stageFlags, offset, size, pValues );
+ }
+
+ void vkCmdBeginRenderPass( VkCommandBuffer commandBuffer,
+ const VkRenderPassBeginInfo * pRenderPassBegin,
+ VkSubpassContents contents ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBeginRenderPass( commandBuffer, pRenderPassBegin, contents );
+ }
+
+ void vkCmdNextSubpass( VkCommandBuffer commandBuffer, VkSubpassContents contents ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdNextSubpass( commandBuffer, contents );
+ }
+
+ void vkCmdEndRenderPass( VkCommandBuffer commandBuffer ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEndRenderPass( commandBuffer );
+ }
+
+ void vkCmdExecuteCommands( VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer * pCommandBuffers ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdExecuteCommands( commandBuffer, commandBufferCount, pCommandBuffers );
+ }
+
+ //=== VK_VERSION_1_1 ===
+
+ VkResult vkEnumerateInstanceVersion( uint32_t * pApiVersion ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkEnumerateInstanceVersion( pApiVersion );
+ }
+
+ VkResult vkBindBufferMemory2( VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo * pBindInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBindBufferMemory2( device, bindInfoCount, pBindInfos );
+ }
+
+ VkResult vkBindImageMemory2( VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo * pBindInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBindImageMemory2( device, bindInfoCount, pBindInfos );
+ }
+
+ void vkGetDeviceGroupPeerMemoryFeatures( VkDevice device,
+ uint32_t heapIndex,
+ uint32_t localDeviceIndex,
+ uint32_t remoteDeviceIndex,
+ VkPeerMemoryFeatureFlags * pPeerMemoryFeatures ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceGroupPeerMemoryFeatures( device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures );
+ }
+
+ void vkCmdSetDeviceMask( VkCommandBuffer commandBuffer, uint32_t deviceMask ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDeviceMask( commandBuffer, deviceMask );
+ }
+
+ void vkCmdDispatchBase( VkCommandBuffer commandBuffer,
+ uint32_t baseGroupX,
+ uint32_t baseGroupY,
+ uint32_t baseGroupZ,
+ uint32_t groupCountX,
+ uint32_t groupCountY,
+ uint32_t groupCountZ ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDispatchBase( commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ );
+ }
+
+ VkResult vkEnumeratePhysicalDeviceGroups( VkInstance instance,
+ uint32_t * pPhysicalDeviceGroupCount,
+ VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkEnumeratePhysicalDeviceGroups( instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties );
+ }
+
+ void vkGetImageMemoryRequirements2( VkDevice device,
+ const VkImageMemoryRequirementsInfo2 * pInfo,
+ VkMemoryRequirements2 * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetImageMemoryRequirements2( device, pInfo, pMemoryRequirements );
+ }
+
+ void vkGetBufferMemoryRequirements2( VkDevice device,
+ const VkBufferMemoryRequirementsInfo2 * pInfo,
+ VkMemoryRequirements2 * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetBufferMemoryRequirements2( device, pInfo, pMemoryRequirements );
+ }
+
+ void vkGetImageSparseMemoryRequirements2( VkDevice device,
+ const VkImageSparseMemoryRequirementsInfo2 * pInfo,
+ uint32_t * pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetImageSparseMemoryRequirements2( device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements );
+ }
+
+ void vkGetPhysicalDeviceFeatures2( VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2 * pFeatures ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceFeatures2( physicalDevice, pFeatures );
+ }
+
+ void vkGetPhysicalDeviceProperties2( VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceProperties2( physicalDevice, pProperties );
+ }
+
+ void vkGetPhysicalDeviceFormatProperties2( VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkFormatProperties2 * pFormatProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceFormatProperties2( physicalDevice, format, pFormatProperties );
+ }
+
+ VkResult vkGetPhysicalDeviceImageFormatProperties2( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,
+ VkImageFormatProperties2 * pImageFormatProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceImageFormatProperties2( physicalDevice, pImageFormatInfo, pImageFormatProperties );
+ }
+
+ void vkGetPhysicalDeviceQueueFamilyProperties2( VkPhysicalDevice physicalDevice,
+ uint32_t * pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties2 * pQueueFamilyProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceQueueFamilyProperties2( physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties );
+ }
+
+ void vkGetPhysicalDeviceMemoryProperties2( VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties2 * pMemoryProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceMemoryProperties2( physicalDevice, pMemoryProperties );
+ }
+
+ void vkGetPhysicalDeviceSparseImageFormatProperties2( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,
+ uint32_t * pPropertyCount,
+ VkSparseImageFormatProperties2 * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSparseImageFormatProperties2( physicalDevice, pFormatInfo, pPropertyCount, pProperties );
+ }
+
+ void vkTrimCommandPool( VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkTrimCommandPool( device, commandPool, flags );
+ }
+
+ void vkGetDeviceQueue2( VkDevice device, const VkDeviceQueueInfo2 * pQueueInfo, VkQueue * pQueue ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceQueue2( device, pQueueInfo, pQueue );
+ }
+
+ VkResult vkCreateSamplerYcbcrConversion( VkDevice device,
+ const VkSamplerYcbcrConversionCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSamplerYcbcrConversion * pYcbcrConversion ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateSamplerYcbcrConversion( device, pCreateInfo, pAllocator, pYcbcrConversion );
+ }
+
+ void vkDestroySamplerYcbcrConversion( VkDevice device,
+ VkSamplerYcbcrConversion ycbcrConversion,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroySamplerYcbcrConversion( device, ycbcrConversion, pAllocator );
+ }
+
+ VkResult vkCreateDescriptorUpdateTemplate( VkDevice device,
+ const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateDescriptorUpdateTemplate( device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate );
+ }
+
+ void vkDestroyDescriptorUpdateTemplate( VkDevice device,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyDescriptorUpdateTemplate( device, descriptorUpdateTemplate, pAllocator );
+ }
+
+ void vkUpdateDescriptorSetWithTemplate( VkDevice device,
+ VkDescriptorSet descriptorSet,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const void * pData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkUpdateDescriptorSetWithTemplate( device, descriptorSet, descriptorUpdateTemplate, pData );
+ }
+
+ void vkGetPhysicalDeviceExternalBufferProperties( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,
+ VkExternalBufferProperties * pExternalBufferProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceExternalBufferProperties( physicalDevice, pExternalBufferInfo, pExternalBufferProperties );
+ }
+
+ void vkGetPhysicalDeviceExternalFenceProperties( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo,
+ VkExternalFenceProperties * pExternalFenceProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceExternalFenceProperties( physicalDevice, pExternalFenceInfo, pExternalFenceProperties );
+ }
+
+ void vkGetPhysicalDeviceExternalSemaphoreProperties( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,
+ VkExternalSemaphoreProperties * pExternalSemaphoreProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceExternalSemaphoreProperties( physicalDevice, pExternalSemaphoreInfo, pExternalSemaphoreProperties );
+ }
+
+ void vkGetDescriptorSetLayoutSupport( VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo * pCreateInfo,
+ VkDescriptorSetLayoutSupport * pSupport ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDescriptorSetLayoutSupport( device, pCreateInfo, pSupport );
+ }
+
+ //=== VK_VERSION_1_2 ===
+
+ void vkCmdDrawIndirectCount( VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawIndirectCount( commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride );
+ }
+
+ void vkCmdDrawIndexedIndirectCount( VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawIndexedIndirectCount( commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride );
+ }
+
+ VkResult vkCreateRenderPass2( VkDevice device,
+ const VkRenderPassCreateInfo2 * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkRenderPass * pRenderPass ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateRenderPass2( device, pCreateInfo, pAllocator, pRenderPass );
+ }
+
+ void vkCmdBeginRenderPass2( VkCommandBuffer commandBuffer,
+ const VkRenderPassBeginInfo * pRenderPassBegin,
+ const VkSubpassBeginInfo * pSubpassBeginInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBeginRenderPass2( commandBuffer, pRenderPassBegin, pSubpassBeginInfo );
+ }
+
+ void vkCmdNextSubpass2( VkCommandBuffer commandBuffer,
+ const VkSubpassBeginInfo * pSubpassBeginInfo,
+ const VkSubpassEndInfo * pSubpassEndInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdNextSubpass2( commandBuffer, pSubpassBeginInfo, pSubpassEndInfo );
+ }
+
+ void vkCmdEndRenderPass2( VkCommandBuffer commandBuffer, const VkSubpassEndInfo * pSubpassEndInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEndRenderPass2( commandBuffer, pSubpassEndInfo );
+ }
+
+ void vkResetQueryPool( VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkResetQueryPool( device, queryPool, firstQuery, queryCount );
+ }
+
+ VkResult vkGetSemaphoreCounterValue( VkDevice device, VkSemaphore semaphore, uint64_t * pValue ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetSemaphoreCounterValue( device, semaphore, pValue );
+ }
+
+ VkResult vkWaitSemaphores( VkDevice device, const VkSemaphoreWaitInfo * pWaitInfo, uint64_t timeout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkWaitSemaphores( device, pWaitInfo, timeout );
+ }
+
+ VkResult vkSignalSemaphore( VkDevice device, const VkSemaphoreSignalInfo * pSignalInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSignalSemaphore( device, pSignalInfo );
+ }
+
+ VkDeviceAddress vkGetBufferDeviceAddress( VkDevice device, const VkBufferDeviceAddressInfo * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetBufferDeviceAddress( device, pInfo );
+ }
+
+ uint64_t vkGetBufferOpaqueCaptureAddress( VkDevice device, const VkBufferDeviceAddressInfo * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetBufferOpaqueCaptureAddress( device, pInfo );
+ }
+
+ uint64_t vkGetDeviceMemoryOpaqueCaptureAddress( VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceMemoryOpaqueCaptureAddress( device, pInfo );
+ }
+
+ //=== VK_VERSION_1_3 ===
+
+ VkResult vkGetPhysicalDeviceToolProperties( VkPhysicalDevice physicalDevice,
+ uint32_t * pToolCount,
+ VkPhysicalDeviceToolProperties * pToolProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceToolProperties( physicalDevice, pToolCount, pToolProperties );
+ }
+
+ VkResult vkCreatePrivateDataSlot( VkDevice device,
+ const VkPrivateDataSlotCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkPrivateDataSlot * pPrivateDataSlot ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreatePrivateDataSlot( device, pCreateInfo, pAllocator, pPrivateDataSlot );
+ }
+
+ void vkDestroyPrivateDataSlot( VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyPrivateDataSlot( device, privateDataSlot, pAllocator );
+ }
+
+ VkResult vkSetPrivateData( VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSetPrivateData( device, objectType, objectHandle, privateDataSlot, data );
+ }
+
+ void vkGetPrivateData( VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t * pData ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPrivateData( device, objectType, objectHandle, privateDataSlot, pData );
+ }
+
+ void vkCmdSetEvent2( VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo * pDependencyInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetEvent2( commandBuffer, event, pDependencyInfo );
+ }
+
+ void vkCmdResetEvent2( VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdResetEvent2( commandBuffer, event, stageMask );
+ }
+
+ void vkCmdWaitEvents2( VkCommandBuffer commandBuffer,
+ uint32_t eventCount,
+ const VkEvent * pEvents,
+ const VkDependencyInfo * pDependencyInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdWaitEvents2( commandBuffer, eventCount, pEvents, pDependencyInfos );
+ }
+
+ void vkCmdPipelineBarrier2( VkCommandBuffer commandBuffer, const VkDependencyInfo * pDependencyInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdPipelineBarrier2( commandBuffer, pDependencyInfo );
+ }
+
+ void vkCmdWriteTimestamp2( VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdWriteTimestamp2( commandBuffer, stage, queryPool, query );
+ }
+
+ VkResult vkQueueSubmit2( VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 * pSubmits, VkFence fence ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkQueueSubmit2( queue, submitCount, pSubmits, fence );
+ }
+
+ void vkCmdCopyBuffer2( VkCommandBuffer commandBuffer, const VkCopyBufferInfo2 * pCopyBufferInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyBuffer2( commandBuffer, pCopyBufferInfo );
+ }
+
+ void vkCmdCopyImage2( VkCommandBuffer commandBuffer, const VkCopyImageInfo2 * pCopyImageInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyImage2( commandBuffer, pCopyImageInfo );
+ }
+
+ void vkCmdCopyBufferToImage2( VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2 * pCopyBufferToImageInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyBufferToImage2( commandBuffer, pCopyBufferToImageInfo );
+ }
+
+ void vkCmdCopyImageToBuffer2( VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2 * pCopyImageToBufferInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyImageToBuffer2( commandBuffer, pCopyImageToBufferInfo );
+ }
+
+ void vkCmdBlitImage2( VkCommandBuffer commandBuffer, const VkBlitImageInfo2 * pBlitImageInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBlitImage2( commandBuffer, pBlitImageInfo );
+ }
+
+ void vkCmdResolveImage2( VkCommandBuffer commandBuffer, const VkResolveImageInfo2 * pResolveImageInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdResolveImage2( commandBuffer, pResolveImageInfo );
+ }
+
+ void vkCmdBeginRendering( VkCommandBuffer commandBuffer, const VkRenderingInfo * pRenderingInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBeginRendering( commandBuffer, pRenderingInfo );
+ }
+
+ void vkCmdEndRendering( VkCommandBuffer commandBuffer ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEndRendering( commandBuffer );
+ }
+
+ void vkCmdSetCullMode( VkCommandBuffer commandBuffer, VkCullModeFlags cullMode ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetCullMode( commandBuffer, cullMode );
+ }
+
+ void vkCmdSetFrontFace( VkCommandBuffer commandBuffer, VkFrontFace frontFace ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetFrontFace( commandBuffer, frontFace );
+ }
+
+ void vkCmdSetPrimitiveTopology( VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetPrimitiveTopology( commandBuffer, primitiveTopology );
+ }
+
+ void vkCmdSetViewportWithCount( VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport * pViewports ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetViewportWithCount( commandBuffer, viewportCount, pViewports );
+ }
+
+ void vkCmdSetScissorWithCount( VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D * pScissors ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetScissorWithCount( commandBuffer, scissorCount, pScissors );
+ }
+
+ void vkCmdBindVertexBuffers2( VkCommandBuffer commandBuffer,
+ uint32_t firstBinding,
+ uint32_t bindingCount,
+ const VkBuffer * pBuffers,
+ const VkDeviceSize * pOffsets,
+ const VkDeviceSize * pSizes,
+ const VkDeviceSize * pStrides ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBindVertexBuffers2( commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes, pStrides );
+ }
+
+ void vkCmdSetDepthTestEnable( VkCommandBuffer commandBuffer, VkBool32 depthTestEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthTestEnable( commandBuffer, depthTestEnable );
+ }
+
+ void vkCmdSetDepthWriteEnable( VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthWriteEnable( commandBuffer, depthWriteEnable );
+ }
+
+ void vkCmdSetDepthCompareOp( VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthCompareOp( commandBuffer, depthCompareOp );
+ }
+
+ void vkCmdSetDepthBoundsTestEnable( VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthBoundsTestEnable( commandBuffer, depthBoundsTestEnable );
+ }
+
+ void vkCmdSetStencilTestEnable( VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetStencilTestEnable( commandBuffer, stencilTestEnable );
+ }
+
+ void vkCmdSetStencilOp( VkCommandBuffer commandBuffer,
+ VkStencilFaceFlags faceMask,
+ VkStencilOp failOp,
+ VkStencilOp passOp,
+ VkStencilOp depthFailOp,
+ VkCompareOp compareOp ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetStencilOp( commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp );
+ }
+
+ void vkCmdSetRasterizerDiscardEnable( VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetRasterizerDiscardEnable( commandBuffer, rasterizerDiscardEnable );
+ }
+
+ void vkCmdSetDepthBiasEnable( VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthBiasEnable( commandBuffer, depthBiasEnable );
+ }
+
+ void vkCmdSetPrimitiveRestartEnable( VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetPrimitiveRestartEnable( commandBuffer, primitiveRestartEnable );
+ }
+
+ void vkGetDeviceBufferMemoryRequirements( VkDevice device,
+ const VkDeviceBufferMemoryRequirements * pInfo,
+ VkMemoryRequirements2 * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceBufferMemoryRequirements( device, pInfo, pMemoryRequirements );
+ }
+
+ void vkGetDeviceImageMemoryRequirements( VkDevice device,
+ const VkDeviceImageMemoryRequirements * pInfo,
+ VkMemoryRequirements2 * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceImageMemoryRequirements( device, pInfo, pMemoryRequirements );
+ }
+
+ void vkGetDeviceImageSparseMemoryRequirements( VkDevice device,
+ const VkDeviceImageMemoryRequirements * pInfo,
+ uint32_t * pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceImageSparseMemoryRequirements( device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements );
+ }
+
+ //=== VK_KHR_surface ===
+
+ void vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroySurfaceKHR( instance, surface, pAllocator );
+ }
+
+ VkResult vkGetPhysicalDeviceSurfaceSupportKHR( VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ VkSurfaceKHR surface,
+ VkBool32 * pSupported ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSurfaceSupportKHR( physicalDevice, queueFamilyIndex, surface, pSupported );
+ }
+
+ VkResult vkGetPhysicalDeviceSurfaceCapabilitiesKHR( VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilitiesKHR * pSurfaceCapabilities ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSurfaceCapabilitiesKHR( physicalDevice, surface, pSurfaceCapabilities );
+ }
+
+ VkResult vkGetPhysicalDeviceSurfaceFormatsKHR( VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t * pSurfaceFormatCount,
+ VkSurfaceFormatKHR * pSurfaceFormats ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSurfaceFormatsKHR( physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats );
+ }
+
+ VkResult vkGetPhysicalDeviceSurfacePresentModesKHR( VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t * pPresentModeCount,
+ VkPresentModeKHR * pPresentModes ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSurfacePresentModesKHR( physicalDevice, surface, pPresentModeCount, pPresentModes );
+ }
+
+ //=== VK_KHR_swapchain ===
+
+ VkResult vkCreateSwapchainKHR( VkDevice device,
+ const VkSwapchainCreateInfoKHR * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSwapchainKHR * pSwapchain ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateSwapchainKHR( device, pCreateInfo, pAllocator, pSwapchain );
+ }
+
+ void vkDestroySwapchainKHR( VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroySwapchainKHR( device, swapchain, pAllocator );
+ }
+
+ VkResult vkGetSwapchainImagesKHR( VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint32_t * pSwapchainImageCount,
+ VkImage * pSwapchainImages ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetSwapchainImagesKHR( device, swapchain, pSwapchainImageCount, pSwapchainImages );
+ }
+
+ VkResult vkAcquireNextImageKHR(
+ VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t * pImageIndex ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkAcquireNextImageKHR( device, swapchain, timeout, semaphore, fence, pImageIndex );
+ }
+
+ VkResult vkQueuePresentKHR( VkQueue queue, const VkPresentInfoKHR * pPresentInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkQueuePresentKHR( queue, pPresentInfo );
+ }
+
+ VkResult vkGetDeviceGroupPresentCapabilitiesKHR( VkDevice device,
+ VkDeviceGroupPresentCapabilitiesKHR * pDeviceGroupPresentCapabilities ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceGroupPresentCapabilitiesKHR( device, pDeviceGroupPresentCapabilities );
+ }
+
+ VkResult
+ vkGetDeviceGroupSurfacePresentModesKHR( VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR * pModes ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceGroupSurfacePresentModesKHR( device, surface, pModes );
+ }
+
+ VkResult vkGetPhysicalDevicePresentRectanglesKHR( VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t * pRectCount,
+ VkRect2D * pRects ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDevicePresentRectanglesKHR( physicalDevice, surface, pRectCount, pRects );
+ }
+
+ VkResult vkAcquireNextImage2KHR( VkDevice device, const VkAcquireNextImageInfoKHR * pAcquireInfo, uint32_t * pImageIndex ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkAcquireNextImage2KHR( device, pAcquireInfo, pImageIndex );
+ }
+
+ //=== VK_KHR_display ===
+
+ VkResult vkGetPhysicalDeviceDisplayPropertiesKHR( VkPhysicalDevice physicalDevice,
+ uint32_t * pPropertyCount,
+ VkDisplayPropertiesKHR * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceDisplayPropertiesKHR( physicalDevice, pPropertyCount, pProperties );
+ }
+
+ VkResult vkGetPhysicalDeviceDisplayPlanePropertiesKHR( VkPhysicalDevice physicalDevice,
+ uint32_t * pPropertyCount,
+ VkDisplayPlanePropertiesKHR * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceDisplayPlanePropertiesKHR( physicalDevice, pPropertyCount, pProperties );
+ }
+
+ VkResult vkGetDisplayPlaneSupportedDisplaysKHR( VkPhysicalDevice physicalDevice,
+ uint32_t planeIndex,
+ uint32_t * pDisplayCount,
+ VkDisplayKHR * pDisplays ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDisplayPlaneSupportedDisplaysKHR( physicalDevice, planeIndex, pDisplayCount, pDisplays );
+ }
+
+ VkResult vkGetDisplayModePropertiesKHR( VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display,
+ uint32_t * pPropertyCount,
+ VkDisplayModePropertiesKHR * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDisplayModePropertiesKHR( physicalDevice, display, pPropertyCount, pProperties );
+ }
+
+ VkResult vkCreateDisplayModeKHR( VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display,
+ const VkDisplayModeCreateInfoKHR * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkDisplayModeKHR * pMode ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateDisplayModeKHR( physicalDevice, display, pCreateInfo, pAllocator, pMode );
+ }
+
+ VkResult vkGetDisplayPlaneCapabilitiesKHR( VkPhysicalDevice physicalDevice,
+ VkDisplayModeKHR mode,
+ uint32_t planeIndex,
+ VkDisplayPlaneCapabilitiesKHR * pCapabilities ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDisplayPlaneCapabilitiesKHR( physicalDevice, mode, planeIndex, pCapabilities );
+ }
+
+ VkResult vkCreateDisplayPlaneSurfaceKHR( VkInstance instance,
+ const VkDisplaySurfaceCreateInfoKHR * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateDisplayPlaneSurfaceKHR( instance, pCreateInfo, pAllocator, pSurface );
+ }
+
+ //=== VK_KHR_display_swapchain ===
+
+ VkResult vkCreateSharedSwapchainsKHR( VkDevice device,
+ uint32_t swapchainCount,
+ const VkSwapchainCreateInfoKHR * pCreateInfos,
+ const VkAllocationCallbacks * pAllocator,
+ VkSwapchainKHR * pSwapchains ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateSharedSwapchainsKHR( device, swapchainCount, pCreateInfos, pAllocator, pSwapchains );
+ }
+
+# if defined( VK_USE_PLATFORM_XLIB_KHR )
+ //=== VK_KHR_xlib_surface ===
+
+ VkResult vkCreateXlibSurfaceKHR( VkInstance instance,
+ const VkXlibSurfaceCreateInfoKHR * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateXlibSurfaceKHR( instance, pCreateInfo, pAllocator, pSurface );
+ }
+
+ VkBool32 vkGetPhysicalDeviceXlibPresentationSupportKHR( VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ Display * dpy,
+ VisualID visualID ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceXlibPresentationSupportKHR( physicalDevice, queueFamilyIndex, dpy, visualID );
+ }
+# endif /*VK_USE_PLATFORM_XLIB_KHR*/
+
+# if defined( VK_USE_PLATFORM_XCB_KHR )
+ //=== VK_KHR_xcb_surface ===
+
+ VkResult vkCreateXcbSurfaceKHR( VkInstance instance,
+ const VkXcbSurfaceCreateInfoKHR * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateXcbSurfaceKHR( instance, pCreateInfo, pAllocator, pSurface );
+ }
+
+ VkBool32 vkGetPhysicalDeviceXcbPresentationSupportKHR( VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ xcb_connection_t * connection,
+ xcb_visualid_t visual_id ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceXcbPresentationSupportKHR( physicalDevice, queueFamilyIndex, connection, visual_id );
+ }
+# endif /*VK_USE_PLATFORM_XCB_KHR*/
+
+# if defined( VK_USE_PLATFORM_WAYLAND_KHR )
+ //=== VK_KHR_wayland_surface ===
+
+ VkResult vkCreateWaylandSurfaceKHR( VkInstance instance,
+ const VkWaylandSurfaceCreateInfoKHR * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateWaylandSurfaceKHR( instance, pCreateInfo, pAllocator, pSurface );
+ }
+
+ VkBool32 vkGetPhysicalDeviceWaylandPresentationSupportKHR( VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ struct wl_display * display ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceWaylandPresentationSupportKHR( physicalDevice, queueFamilyIndex, display );
+ }
+# endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+
+# if defined( VK_USE_PLATFORM_ANDROID_KHR )
+ //=== VK_KHR_android_surface ===
+
+ VkResult vkCreateAndroidSurfaceKHR( VkInstance instance,
+ const VkAndroidSurfaceCreateInfoKHR * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateAndroidSurfaceKHR( instance, pCreateInfo, pAllocator, pSurface );
+ }
+# endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_win32_surface ===
+
+ VkResult vkCreateWin32SurfaceKHR( VkInstance instance,
+ const VkWin32SurfaceCreateInfoKHR * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateWin32SurfaceKHR( instance, pCreateInfo, pAllocator, pSurface );
+ }
+
+ VkBool32 vkGetPhysicalDeviceWin32PresentationSupportKHR( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceWin32PresentationSupportKHR( physicalDevice, queueFamilyIndex );
+ }
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_EXT_debug_report ===
+
+ VkResult vkCreateDebugReportCallbackEXT( VkInstance instance,
+ const VkDebugReportCallbackCreateInfoEXT * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkDebugReportCallbackEXT * pCallback ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateDebugReportCallbackEXT( instance, pCreateInfo, pAllocator, pCallback );
+ }
+
+ void vkDestroyDebugReportCallbackEXT( VkInstance instance,
+ VkDebugReportCallbackEXT callback,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyDebugReportCallbackEXT( instance, callback, pAllocator );
+ }
+
+ void vkDebugReportMessageEXT( VkInstance instance,
+ VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objectType,
+ uint64_t object,
+ size_t location,
+ int32_t messageCode,
+ const char * pLayerPrefix,
+ const char * pMessage ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDebugReportMessageEXT( instance, flags, objectType, object, location, messageCode, pLayerPrefix, pMessage );
+ }
+
+ //=== VK_EXT_debug_marker ===
+
+ VkResult vkDebugMarkerSetObjectTagEXT( VkDevice device, const VkDebugMarkerObjectTagInfoEXT * pTagInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDebugMarkerSetObjectTagEXT( device, pTagInfo );
+ }
+
+ VkResult vkDebugMarkerSetObjectNameEXT( VkDevice device, const VkDebugMarkerObjectNameInfoEXT * pNameInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDebugMarkerSetObjectNameEXT( device, pNameInfo );
+ }
+
+ void vkCmdDebugMarkerBeginEXT( VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT * pMarkerInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDebugMarkerBeginEXT( commandBuffer, pMarkerInfo );
+ }
+
+ void vkCmdDebugMarkerEndEXT( VkCommandBuffer commandBuffer ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDebugMarkerEndEXT( commandBuffer );
+ }
+
+ void vkCmdDebugMarkerInsertEXT( VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT * pMarkerInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDebugMarkerInsertEXT( commandBuffer, pMarkerInfo );
+ }
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_queue ===
+
+ VkResult vkGetPhysicalDeviceVideoCapabilitiesKHR( VkPhysicalDevice physicalDevice,
+ const VkVideoProfileInfoKHR * pVideoProfile,
+ VkVideoCapabilitiesKHR * pCapabilities ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceVideoCapabilitiesKHR( physicalDevice, pVideoProfile, pCapabilities );
+ }
+
+ VkResult vkGetPhysicalDeviceVideoFormatPropertiesKHR( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceVideoFormatInfoKHR * pVideoFormatInfo,
+ uint32_t * pVideoFormatPropertyCount,
+ VkVideoFormatPropertiesKHR * pVideoFormatProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceVideoFormatPropertiesKHR( physicalDevice, pVideoFormatInfo, pVideoFormatPropertyCount, pVideoFormatProperties );
+ }
+
+ VkResult vkCreateVideoSessionKHR( VkDevice device,
+ const VkVideoSessionCreateInfoKHR * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkVideoSessionKHR * pVideoSession ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateVideoSessionKHR( device, pCreateInfo, pAllocator, pVideoSession );
+ }
+
+ void vkDestroyVideoSessionKHR( VkDevice device, VkVideoSessionKHR videoSession, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyVideoSessionKHR( device, videoSession, pAllocator );
+ }
+
+ VkResult vkGetVideoSessionMemoryRequirementsKHR( VkDevice device,
+ VkVideoSessionKHR videoSession,
+ uint32_t * pMemoryRequirementsCount,
+ VkVideoSessionMemoryRequirementsKHR * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetVideoSessionMemoryRequirementsKHR( device, videoSession, pMemoryRequirementsCount, pMemoryRequirements );
+ }
+
+ VkResult vkBindVideoSessionMemoryKHR( VkDevice device,
+ VkVideoSessionKHR videoSession,
+ uint32_t bindSessionMemoryInfoCount,
+ const VkBindVideoSessionMemoryInfoKHR * pBindSessionMemoryInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBindVideoSessionMemoryKHR( device, videoSession, bindSessionMemoryInfoCount, pBindSessionMemoryInfos );
+ }
+
+ VkResult vkCreateVideoSessionParametersKHR( VkDevice device,
+ const VkVideoSessionParametersCreateInfoKHR * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkVideoSessionParametersKHR * pVideoSessionParameters ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateVideoSessionParametersKHR( device, pCreateInfo, pAllocator, pVideoSessionParameters );
+ }
+
+ VkResult vkUpdateVideoSessionParametersKHR( VkDevice device,
+ VkVideoSessionParametersKHR videoSessionParameters,
+ const VkVideoSessionParametersUpdateInfoKHR * pUpdateInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkUpdateVideoSessionParametersKHR( device, videoSessionParameters, pUpdateInfo );
+ }
+
+ void vkDestroyVideoSessionParametersKHR( VkDevice device,
+ VkVideoSessionParametersKHR videoSessionParameters,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyVideoSessionParametersKHR( device, videoSessionParameters, pAllocator );
+ }
+
+ void vkCmdBeginVideoCodingKHR( VkCommandBuffer commandBuffer, const VkVideoBeginCodingInfoKHR * pBeginInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBeginVideoCodingKHR( commandBuffer, pBeginInfo );
+ }
+
+ void vkCmdEndVideoCodingKHR( VkCommandBuffer commandBuffer, const VkVideoEndCodingInfoKHR * pEndCodingInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEndVideoCodingKHR( commandBuffer, pEndCodingInfo );
+ }
+
+ void vkCmdControlVideoCodingKHR( VkCommandBuffer commandBuffer, const VkVideoCodingControlInfoKHR * pCodingControlInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdControlVideoCodingKHR( commandBuffer, pCodingControlInfo );
+ }
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_decode_queue ===
+
+ void vkCmdDecodeVideoKHR( VkCommandBuffer commandBuffer, const VkVideoDecodeInfoKHR * pDecodeInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDecodeVideoKHR( commandBuffer, pDecodeInfo );
+ }
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+ //=== VK_EXT_transform_feedback ===
+
+ void vkCmdBindTransformFeedbackBuffersEXT( VkCommandBuffer commandBuffer,
+ uint32_t firstBinding,
+ uint32_t bindingCount,
+ const VkBuffer * pBuffers,
+ const VkDeviceSize * pOffsets,
+ const VkDeviceSize * pSizes ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBindTransformFeedbackBuffersEXT( commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes );
+ }
+
+ void vkCmdBeginTransformFeedbackEXT( VkCommandBuffer commandBuffer,
+ uint32_t firstCounterBuffer,
+ uint32_t counterBufferCount,
+ const VkBuffer * pCounterBuffers,
+ const VkDeviceSize * pCounterBufferOffsets ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBeginTransformFeedbackEXT( commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers, pCounterBufferOffsets );
+ }
+
+ void vkCmdEndTransformFeedbackEXT( VkCommandBuffer commandBuffer,
+ uint32_t firstCounterBuffer,
+ uint32_t counterBufferCount,
+ const VkBuffer * pCounterBuffers,
+ const VkDeviceSize * pCounterBufferOffsets ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEndTransformFeedbackEXT( commandBuffer, firstCounterBuffer, counterBufferCount, pCounterBuffers, pCounterBufferOffsets );
+ }
+
+ void vkCmdBeginQueryIndexedEXT( VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags, uint32_t index ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBeginQueryIndexedEXT( commandBuffer, queryPool, query, flags, index );
+ }
+
+ void vkCmdEndQueryIndexedEXT( VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, uint32_t index ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEndQueryIndexedEXT( commandBuffer, queryPool, query, index );
+ }
+
+ void vkCmdDrawIndirectByteCountEXT( VkCommandBuffer commandBuffer,
+ uint32_t instanceCount,
+ uint32_t firstInstance,
+ VkBuffer counterBuffer,
+ VkDeviceSize counterBufferOffset,
+ uint32_t counterOffset,
+ uint32_t vertexStride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawIndirectByteCountEXT( commandBuffer, instanceCount, firstInstance, counterBuffer, counterBufferOffset, counterOffset, vertexStride );
+ }
+
+ //=== VK_NVX_binary_import ===
+
+ VkResult vkCreateCuModuleNVX( VkDevice device,
+ const VkCuModuleCreateInfoNVX * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkCuModuleNVX * pModule ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateCuModuleNVX( device, pCreateInfo, pAllocator, pModule );
+ }
+
+ VkResult vkCreateCuFunctionNVX( VkDevice device,
+ const VkCuFunctionCreateInfoNVX * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkCuFunctionNVX * pFunction ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateCuFunctionNVX( device, pCreateInfo, pAllocator, pFunction );
+ }
+
+ void vkDestroyCuModuleNVX( VkDevice device, VkCuModuleNVX module, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyCuModuleNVX( device, module, pAllocator );
+ }
+
+ void vkDestroyCuFunctionNVX( VkDevice device, VkCuFunctionNVX function, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyCuFunctionNVX( device, function, pAllocator );
+ }
+
+ void vkCmdCuLaunchKernelNVX( VkCommandBuffer commandBuffer, const VkCuLaunchInfoNVX * pLaunchInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCuLaunchKernelNVX( commandBuffer, pLaunchInfo );
+ }
+
+ //=== VK_NVX_image_view_handle ===
+
+ uint32_t vkGetImageViewHandleNVX( VkDevice device, const VkImageViewHandleInfoNVX * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetImageViewHandleNVX( device, pInfo );
+ }
+
+ VkResult vkGetImageViewAddressNVX( VkDevice device, VkImageView imageView, VkImageViewAddressPropertiesNVX * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetImageViewAddressNVX( device, imageView, pProperties );
+ }
+
+ //=== VK_AMD_draw_indirect_count ===
+
+ void vkCmdDrawIndirectCountAMD( VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawIndirectCountAMD( commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride );
+ }
+
+ void vkCmdDrawIndexedIndirectCountAMD( VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawIndexedIndirectCountAMD( commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride );
+ }
+
+ //=== VK_AMD_shader_info ===
+
+ VkResult vkGetShaderInfoAMD( VkDevice device,
+ VkPipeline pipeline,
+ VkShaderStageFlagBits shaderStage,
+ VkShaderInfoTypeAMD infoType,
+ size_t * pInfoSize,
+ void * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetShaderInfoAMD( device, pipeline, shaderStage, infoType, pInfoSize, pInfo );
+ }
+
+ //=== VK_KHR_dynamic_rendering ===
+
+ void vkCmdBeginRenderingKHR( VkCommandBuffer commandBuffer, const VkRenderingInfo * pRenderingInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBeginRenderingKHR( commandBuffer, pRenderingInfo );
+ }
+
+ void vkCmdEndRenderingKHR( VkCommandBuffer commandBuffer ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEndRenderingKHR( commandBuffer );
+ }
+
+# if defined( VK_USE_PLATFORM_GGP )
+ //=== VK_GGP_stream_descriptor_surface ===
+
+ VkResult vkCreateStreamDescriptorSurfaceGGP( VkInstance instance,
+ const VkStreamDescriptorSurfaceCreateInfoGGP * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateStreamDescriptorSurfaceGGP( instance, pCreateInfo, pAllocator, pSurface );
+ }
+# endif /*VK_USE_PLATFORM_GGP*/
+
+ //=== VK_NV_external_memory_capabilities ===
+
+ VkResult vkGetPhysicalDeviceExternalImageFormatPropertiesNV( VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags flags,
+ VkExternalMemoryHandleTypeFlagsNV externalHandleType,
+ VkExternalImageFormatPropertiesNV * pExternalImageFormatProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceExternalImageFormatPropertiesNV(
+ physicalDevice, format, type, tiling, usage, flags, externalHandleType, pExternalImageFormatProperties );
+ }
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_NV_external_memory_win32 ===
+
+ VkResult vkGetMemoryWin32HandleNV( VkDevice device,
+ VkDeviceMemory memory,
+ VkExternalMemoryHandleTypeFlagsNV handleType,
+ HANDLE * pHandle ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetMemoryWin32HandleNV( device, memory, handleType, pHandle );
+ }
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_get_physical_device_properties2 ===
+
+ void vkGetPhysicalDeviceFeatures2KHR( VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2 * pFeatures ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceFeatures2KHR( physicalDevice, pFeatures );
+ }
+
+ void vkGetPhysicalDeviceProperties2KHR( VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceProperties2KHR( physicalDevice, pProperties );
+ }
+
+ void vkGetPhysicalDeviceFormatProperties2KHR( VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkFormatProperties2 * pFormatProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceFormatProperties2KHR( physicalDevice, format, pFormatProperties );
+ }
+
+ VkResult vkGetPhysicalDeviceImageFormatProperties2KHR( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,
+ VkImageFormatProperties2 * pImageFormatProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceImageFormatProperties2KHR( physicalDevice, pImageFormatInfo, pImageFormatProperties );
+ }
+
+ void vkGetPhysicalDeviceQueueFamilyProperties2KHR( VkPhysicalDevice physicalDevice,
+ uint32_t * pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties2 * pQueueFamilyProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceQueueFamilyProperties2KHR( physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties );
+ }
+
+ void vkGetPhysicalDeviceMemoryProperties2KHR( VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties2 * pMemoryProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceMemoryProperties2KHR( physicalDevice, pMemoryProperties );
+ }
+
+ void vkGetPhysicalDeviceSparseImageFormatProperties2KHR( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,
+ uint32_t * pPropertyCount,
+ VkSparseImageFormatProperties2 * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSparseImageFormatProperties2KHR( physicalDevice, pFormatInfo, pPropertyCount, pProperties );
+ }
+
+ //=== VK_KHR_device_group ===
+
+ void vkGetDeviceGroupPeerMemoryFeaturesKHR( VkDevice device,
+ uint32_t heapIndex,
+ uint32_t localDeviceIndex,
+ uint32_t remoteDeviceIndex,
+ VkPeerMemoryFeatureFlags * pPeerMemoryFeatures ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceGroupPeerMemoryFeaturesKHR( device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures );
+ }
+
+ void vkCmdSetDeviceMaskKHR( VkCommandBuffer commandBuffer, uint32_t deviceMask ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDeviceMaskKHR( commandBuffer, deviceMask );
+ }
+
+ void vkCmdDispatchBaseKHR( VkCommandBuffer commandBuffer,
+ uint32_t baseGroupX,
+ uint32_t baseGroupY,
+ uint32_t baseGroupZ,
+ uint32_t groupCountX,
+ uint32_t groupCountY,
+ uint32_t groupCountZ ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDispatchBaseKHR( commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ );
+ }
+
+# if defined( VK_USE_PLATFORM_VI_NN )
+ //=== VK_NN_vi_surface ===
+
+ VkResult vkCreateViSurfaceNN( VkInstance instance,
+ const VkViSurfaceCreateInfoNN * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateViSurfaceNN( instance, pCreateInfo, pAllocator, pSurface );
+ }
+# endif /*VK_USE_PLATFORM_VI_NN*/
+
+ //=== VK_KHR_maintenance1 ===
+
+ void vkTrimCommandPoolKHR( VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkTrimCommandPoolKHR( device, commandPool, flags );
+ }
+
+ //=== VK_KHR_device_group_creation ===
+
+ VkResult vkEnumeratePhysicalDeviceGroupsKHR( VkInstance instance,
+ uint32_t * pPhysicalDeviceGroupCount,
+ VkPhysicalDeviceGroupProperties * pPhysicalDeviceGroupProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkEnumeratePhysicalDeviceGroupsKHR( instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties );
+ }
+
+ //=== VK_KHR_external_memory_capabilities ===
+
+ void vkGetPhysicalDeviceExternalBufferPropertiesKHR( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,
+ VkExternalBufferProperties * pExternalBufferProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceExternalBufferPropertiesKHR( physicalDevice, pExternalBufferInfo, pExternalBufferProperties );
+ }
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_memory_win32 ===
+
+ VkResult vkGetMemoryWin32HandleKHR( VkDevice device, const VkMemoryGetWin32HandleInfoKHR * pGetWin32HandleInfo, HANDLE * pHandle ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetMemoryWin32HandleKHR( device, pGetWin32HandleInfo, pHandle );
+ }
+
+ VkResult vkGetMemoryWin32HandlePropertiesKHR( VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ HANDLE handle,
+ VkMemoryWin32HandlePropertiesKHR * pMemoryWin32HandleProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetMemoryWin32HandlePropertiesKHR( device, handleType, handle, pMemoryWin32HandleProperties );
+ }
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_memory_fd ===
+
+ VkResult vkGetMemoryFdKHR( VkDevice device, const VkMemoryGetFdInfoKHR * pGetFdInfo, int * pFd ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetMemoryFdKHR( device, pGetFdInfo, pFd );
+ }
+
+ VkResult vkGetMemoryFdPropertiesKHR( VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ int fd,
+ VkMemoryFdPropertiesKHR * pMemoryFdProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetMemoryFdPropertiesKHR( device, handleType, fd, pMemoryFdProperties );
+ }
+
+ //=== VK_KHR_external_semaphore_capabilities ===
+
+ void vkGetPhysicalDeviceExternalSemaphorePropertiesKHR( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalSemaphoreInfo * pExternalSemaphoreInfo,
+ VkExternalSemaphoreProperties * pExternalSemaphoreProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceExternalSemaphorePropertiesKHR( physicalDevice, pExternalSemaphoreInfo, pExternalSemaphoreProperties );
+ }
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_semaphore_win32 ===
+
+ VkResult vkImportSemaphoreWin32HandleKHR( VkDevice device,
+ const VkImportSemaphoreWin32HandleInfoKHR * pImportSemaphoreWin32HandleInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkImportSemaphoreWin32HandleKHR( device, pImportSemaphoreWin32HandleInfo );
+ }
+
+ VkResult
+ vkGetSemaphoreWin32HandleKHR( VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR * pGetWin32HandleInfo, HANDLE * pHandle ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetSemaphoreWin32HandleKHR( device, pGetWin32HandleInfo, pHandle );
+ }
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_semaphore_fd ===
+
+ VkResult vkImportSemaphoreFdKHR( VkDevice device, const VkImportSemaphoreFdInfoKHR * pImportSemaphoreFdInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkImportSemaphoreFdKHR( device, pImportSemaphoreFdInfo );
+ }
+
+ VkResult vkGetSemaphoreFdKHR( VkDevice device, const VkSemaphoreGetFdInfoKHR * pGetFdInfo, int * pFd ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetSemaphoreFdKHR( device, pGetFdInfo, pFd );
+ }
+
+ //=== VK_KHR_push_descriptor ===
+
+ void vkCmdPushDescriptorSetKHR( VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipelineLayout layout,
+ uint32_t set,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet * pDescriptorWrites ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdPushDescriptorSetKHR( commandBuffer, pipelineBindPoint, layout, set, descriptorWriteCount, pDescriptorWrites );
+ }
+
+ void vkCmdPushDescriptorSetWithTemplateKHR( VkCommandBuffer commandBuffer,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ VkPipelineLayout layout,
+ uint32_t set,
+ const void * pData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdPushDescriptorSetWithTemplateKHR( commandBuffer, descriptorUpdateTemplate, layout, set, pData );
+ }
+
+ //=== VK_EXT_conditional_rendering ===
+
+ void vkCmdBeginConditionalRenderingEXT( VkCommandBuffer commandBuffer,
+ const VkConditionalRenderingBeginInfoEXT * pConditionalRenderingBegin ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBeginConditionalRenderingEXT( commandBuffer, pConditionalRenderingBegin );
+ }
+
+ void vkCmdEndConditionalRenderingEXT( VkCommandBuffer commandBuffer ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEndConditionalRenderingEXT( commandBuffer );
+ }
+
+ //=== VK_KHR_descriptor_update_template ===
+
+ VkResult vkCreateDescriptorUpdateTemplateKHR( VkDevice device,
+ const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateDescriptorUpdateTemplateKHR( device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate );
+ }
+
+ void vkDestroyDescriptorUpdateTemplateKHR( VkDevice device,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyDescriptorUpdateTemplateKHR( device, descriptorUpdateTemplate, pAllocator );
+ }
+
+ void vkUpdateDescriptorSetWithTemplateKHR( VkDevice device,
+ VkDescriptorSet descriptorSet,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const void * pData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkUpdateDescriptorSetWithTemplateKHR( device, descriptorSet, descriptorUpdateTemplate, pData );
+ }
+
+ //=== VK_NV_clip_space_w_scaling ===
+
+ void vkCmdSetViewportWScalingNV( VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkViewportWScalingNV * pViewportWScalings ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetViewportWScalingNV( commandBuffer, firstViewport, viewportCount, pViewportWScalings );
+ }
+
+ //=== VK_EXT_direct_mode_display ===
+
+ VkResult vkReleaseDisplayEXT( VkPhysicalDevice physicalDevice, VkDisplayKHR display ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkReleaseDisplayEXT( physicalDevice, display );
+ }
+
+# if defined( VK_USE_PLATFORM_XLIB_XRANDR_EXT )
+ //=== VK_EXT_acquire_xlib_display ===
+
+ VkResult vkAcquireXlibDisplayEXT( VkPhysicalDevice physicalDevice, Display * dpy, VkDisplayKHR display ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkAcquireXlibDisplayEXT( physicalDevice, dpy, display );
+ }
+
+ VkResult vkGetRandROutputDisplayEXT( VkPhysicalDevice physicalDevice, Display * dpy, RROutput rrOutput, VkDisplayKHR * pDisplay ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetRandROutputDisplayEXT( physicalDevice, dpy, rrOutput, pDisplay );
+ }
+# endif /*VK_USE_PLATFORM_XLIB_XRANDR_EXT*/
+
+ //=== VK_EXT_display_surface_counter ===
+
+ VkResult vkGetPhysicalDeviceSurfaceCapabilities2EXT( VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilities2EXT * pSurfaceCapabilities ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSurfaceCapabilities2EXT( physicalDevice, surface, pSurfaceCapabilities );
+ }
+
+ //=== VK_EXT_display_control ===
+
+ VkResult vkDisplayPowerControlEXT( VkDevice device, VkDisplayKHR display, const VkDisplayPowerInfoEXT * pDisplayPowerInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDisplayPowerControlEXT( device, display, pDisplayPowerInfo );
+ }
+
+ VkResult vkRegisterDeviceEventEXT( VkDevice device,
+ const VkDeviceEventInfoEXT * pDeviceEventInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkFence * pFence ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkRegisterDeviceEventEXT( device, pDeviceEventInfo, pAllocator, pFence );
+ }
+
+ VkResult vkRegisterDisplayEventEXT( VkDevice device,
+ VkDisplayKHR display,
+ const VkDisplayEventInfoEXT * pDisplayEventInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkFence * pFence ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkRegisterDisplayEventEXT( device, display, pDisplayEventInfo, pAllocator, pFence );
+ }
+
+ VkResult vkGetSwapchainCounterEXT( VkDevice device,
+ VkSwapchainKHR swapchain,
+ VkSurfaceCounterFlagBitsEXT counter,
+ uint64_t * pCounterValue ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetSwapchainCounterEXT( device, swapchain, counter, pCounterValue );
+ }
+
+ //=== VK_GOOGLE_display_timing ===
+
+ VkResult vkGetRefreshCycleDurationGOOGLE( VkDevice device,
+ VkSwapchainKHR swapchain,
+ VkRefreshCycleDurationGOOGLE * pDisplayTimingProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetRefreshCycleDurationGOOGLE( device, swapchain, pDisplayTimingProperties );
+ }
+
+ VkResult vkGetPastPresentationTimingGOOGLE( VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint32_t * pPresentationTimingCount,
+ VkPastPresentationTimingGOOGLE * pPresentationTimings ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPastPresentationTimingGOOGLE( device, swapchain, pPresentationTimingCount, pPresentationTimings );
+ }
+
+ //=== VK_EXT_discard_rectangles ===
+
+ void vkCmdSetDiscardRectangleEXT( VkCommandBuffer commandBuffer,
+ uint32_t firstDiscardRectangle,
+ uint32_t discardRectangleCount,
+ const VkRect2D * pDiscardRectangles ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDiscardRectangleEXT( commandBuffer, firstDiscardRectangle, discardRectangleCount, pDiscardRectangles );
+ }
+
+ //=== VK_EXT_hdr_metadata ===
+
+ void vkSetHdrMetadataEXT( VkDevice device,
+ uint32_t swapchainCount,
+ const VkSwapchainKHR * pSwapchains,
+ const VkHdrMetadataEXT * pMetadata ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSetHdrMetadataEXT( device, swapchainCount, pSwapchains, pMetadata );
+ }
+
+ //=== VK_KHR_create_renderpass2 ===
+
+ VkResult vkCreateRenderPass2KHR( VkDevice device,
+ const VkRenderPassCreateInfo2 * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkRenderPass * pRenderPass ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateRenderPass2KHR( device, pCreateInfo, pAllocator, pRenderPass );
+ }
+
+ void vkCmdBeginRenderPass2KHR( VkCommandBuffer commandBuffer,
+ const VkRenderPassBeginInfo * pRenderPassBegin,
+ const VkSubpassBeginInfo * pSubpassBeginInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBeginRenderPass2KHR( commandBuffer, pRenderPassBegin, pSubpassBeginInfo );
+ }
+
+ void vkCmdNextSubpass2KHR( VkCommandBuffer commandBuffer,
+ const VkSubpassBeginInfo * pSubpassBeginInfo,
+ const VkSubpassEndInfo * pSubpassEndInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdNextSubpass2KHR( commandBuffer, pSubpassBeginInfo, pSubpassEndInfo );
+ }
+
+ void vkCmdEndRenderPass2KHR( VkCommandBuffer commandBuffer, const VkSubpassEndInfo * pSubpassEndInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEndRenderPass2KHR( commandBuffer, pSubpassEndInfo );
+ }
+
+ //=== VK_KHR_shared_presentable_image ===
+
+ VkResult vkGetSwapchainStatusKHR( VkDevice device, VkSwapchainKHR swapchain ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetSwapchainStatusKHR( device, swapchain );
+ }
+
+ //=== VK_KHR_external_fence_capabilities ===
+
+ void vkGetPhysicalDeviceExternalFencePropertiesKHR( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalFenceInfo * pExternalFenceInfo,
+ VkExternalFenceProperties * pExternalFenceProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceExternalFencePropertiesKHR( physicalDevice, pExternalFenceInfo, pExternalFenceProperties );
+ }
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_fence_win32 ===
+
+ VkResult vkImportFenceWin32HandleKHR( VkDevice device, const VkImportFenceWin32HandleInfoKHR * pImportFenceWin32HandleInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkImportFenceWin32HandleKHR( device, pImportFenceWin32HandleInfo );
+ }
+
+ VkResult vkGetFenceWin32HandleKHR( VkDevice device, const VkFenceGetWin32HandleInfoKHR * pGetWin32HandleInfo, HANDLE * pHandle ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetFenceWin32HandleKHR( device, pGetWin32HandleInfo, pHandle );
+ }
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_fence_fd ===
+
+ VkResult vkImportFenceFdKHR( VkDevice device, const VkImportFenceFdInfoKHR * pImportFenceFdInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkImportFenceFdKHR( device, pImportFenceFdInfo );
+ }
+
+ VkResult vkGetFenceFdKHR( VkDevice device, const VkFenceGetFdInfoKHR * pGetFdInfo, int * pFd ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetFenceFdKHR( device, pGetFdInfo, pFd );
+ }
+
+ //=== VK_KHR_performance_query ===
+
+ VkResult
+ vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR( VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ uint32_t * pCounterCount,
+ VkPerformanceCounterKHR * pCounters,
+ VkPerformanceCounterDescriptionKHR * pCounterDescriptions ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
+ physicalDevice, queueFamilyIndex, pCounterCount, pCounters, pCounterDescriptions );
+ }
+
+ void vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR( VkPhysicalDevice physicalDevice,
+ const VkQueryPoolPerformanceCreateInfoKHR * pPerformanceQueryCreateInfo,
+ uint32_t * pNumPasses ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR( physicalDevice, pPerformanceQueryCreateInfo, pNumPasses );
+ }
+
+ VkResult vkAcquireProfilingLockKHR( VkDevice device, const VkAcquireProfilingLockInfoKHR * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkAcquireProfilingLockKHR( device, pInfo );
+ }
+
+ void vkReleaseProfilingLockKHR( VkDevice device ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkReleaseProfilingLockKHR( device );
+ }
+
+ //=== VK_KHR_get_surface_capabilities2 ===
+
+ VkResult vkGetPhysicalDeviceSurfaceCapabilities2KHR( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,
+ VkSurfaceCapabilities2KHR * pSurfaceCapabilities ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSurfaceCapabilities2KHR( physicalDevice, pSurfaceInfo, pSurfaceCapabilities );
+ }
+
+ VkResult vkGetPhysicalDeviceSurfaceFormats2KHR( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,
+ uint32_t * pSurfaceFormatCount,
+ VkSurfaceFormat2KHR * pSurfaceFormats ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSurfaceFormats2KHR( physicalDevice, pSurfaceInfo, pSurfaceFormatCount, pSurfaceFormats );
+ }
+
+ //=== VK_KHR_get_display_properties2 ===
+
+ VkResult vkGetPhysicalDeviceDisplayProperties2KHR( VkPhysicalDevice physicalDevice,
+ uint32_t * pPropertyCount,
+ VkDisplayProperties2KHR * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceDisplayProperties2KHR( physicalDevice, pPropertyCount, pProperties );
+ }
+
+ VkResult vkGetPhysicalDeviceDisplayPlaneProperties2KHR( VkPhysicalDevice physicalDevice,
+ uint32_t * pPropertyCount,
+ VkDisplayPlaneProperties2KHR * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceDisplayPlaneProperties2KHR( physicalDevice, pPropertyCount, pProperties );
+ }
+
+ VkResult vkGetDisplayModeProperties2KHR( VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display,
+ uint32_t * pPropertyCount,
+ VkDisplayModeProperties2KHR * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDisplayModeProperties2KHR( physicalDevice, display, pPropertyCount, pProperties );
+ }
+
+ VkResult vkGetDisplayPlaneCapabilities2KHR( VkPhysicalDevice physicalDevice,
+ const VkDisplayPlaneInfo2KHR * pDisplayPlaneInfo,
+ VkDisplayPlaneCapabilities2KHR * pCapabilities ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDisplayPlaneCapabilities2KHR( physicalDevice, pDisplayPlaneInfo, pCapabilities );
+ }
+
+# if defined( VK_USE_PLATFORM_IOS_MVK )
+ //=== VK_MVK_ios_surface ===
+
+ VkResult vkCreateIOSSurfaceMVK( VkInstance instance,
+ const VkIOSSurfaceCreateInfoMVK * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateIOSSurfaceMVK( instance, pCreateInfo, pAllocator, pSurface );
+ }
+# endif /*VK_USE_PLATFORM_IOS_MVK*/
+
+# if defined( VK_USE_PLATFORM_MACOS_MVK )
+ //=== VK_MVK_macos_surface ===
+
+ VkResult vkCreateMacOSSurfaceMVK( VkInstance instance,
+ const VkMacOSSurfaceCreateInfoMVK * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateMacOSSurfaceMVK( instance, pCreateInfo, pAllocator, pSurface );
+ }
+# endif /*VK_USE_PLATFORM_MACOS_MVK*/
+
+ //=== VK_EXT_debug_utils ===
+
+ VkResult vkSetDebugUtilsObjectNameEXT( VkDevice device, const VkDebugUtilsObjectNameInfoEXT * pNameInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSetDebugUtilsObjectNameEXT( device, pNameInfo );
+ }
+
+ VkResult vkSetDebugUtilsObjectTagEXT( VkDevice device, const VkDebugUtilsObjectTagInfoEXT * pTagInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSetDebugUtilsObjectTagEXT( device, pTagInfo );
+ }
+
+ void vkQueueBeginDebugUtilsLabelEXT( VkQueue queue, const VkDebugUtilsLabelEXT * pLabelInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkQueueBeginDebugUtilsLabelEXT( queue, pLabelInfo );
+ }
+
+ void vkQueueEndDebugUtilsLabelEXT( VkQueue queue ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkQueueEndDebugUtilsLabelEXT( queue );
+ }
+
+ void vkQueueInsertDebugUtilsLabelEXT( VkQueue queue, const VkDebugUtilsLabelEXT * pLabelInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkQueueInsertDebugUtilsLabelEXT( queue, pLabelInfo );
+ }
+
+ void vkCmdBeginDebugUtilsLabelEXT( VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT * pLabelInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBeginDebugUtilsLabelEXT( commandBuffer, pLabelInfo );
+ }
+
+ void vkCmdEndDebugUtilsLabelEXT( VkCommandBuffer commandBuffer ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEndDebugUtilsLabelEXT( commandBuffer );
+ }
+
+ void vkCmdInsertDebugUtilsLabelEXT( VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT * pLabelInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdInsertDebugUtilsLabelEXT( commandBuffer, pLabelInfo );
+ }
+
+ VkResult vkCreateDebugUtilsMessengerEXT( VkInstance instance,
+ const VkDebugUtilsMessengerCreateInfoEXT * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkDebugUtilsMessengerEXT * pMessenger ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateDebugUtilsMessengerEXT( instance, pCreateInfo, pAllocator, pMessenger );
+ }
+
+ void vkDestroyDebugUtilsMessengerEXT( VkInstance instance,
+ VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyDebugUtilsMessengerEXT( instance, messenger, pAllocator );
+ }
+
+ void vkSubmitDebugUtilsMessageEXT( VkInstance instance,
+ VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const VkDebugUtilsMessengerCallbackDataEXT * pCallbackData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSubmitDebugUtilsMessageEXT( instance, messageSeverity, messageTypes, pCallbackData );
+ }
+
+# if defined( VK_USE_PLATFORM_ANDROID_KHR )
+ //=== VK_ANDROID_external_memory_android_hardware_buffer ===
+
+ VkResult vkGetAndroidHardwareBufferPropertiesANDROID( VkDevice device,
+ const struct AHardwareBuffer * buffer,
+ VkAndroidHardwareBufferPropertiesANDROID * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetAndroidHardwareBufferPropertiesANDROID( device, buffer, pProperties );
+ }
+
+ VkResult vkGetMemoryAndroidHardwareBufferANDROID( VkDevice device,
+ const VkMemoryGetAndroidHardwareBufferInfoANDROID * pInfo,
+ struct AHardwareBuffer ** pBuffer ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetMemoryAndroidHardwareBufferANDROID( device, pInfo, pBuffer );
+ }
+# endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+ //=== VK_EXT_sample_locations ===
+
+ void vkCmdSetSampleLocationsEXT( VkCommandBuffer commandBuffer, const VkSampleLocationsInfoEXT * pSampleLocationsInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetSampleLocationsEXT( commandBuffer, pSampleLocationsInfo );
+ }
+
+ void vkGetPhysicalDeviceMultisamplePropertiesEXT( VkPhysicalDevice physicalDevice,
+ VkSampleCountFlagBits samples,
+ VkMultisamplePropertiesEXT * pMultisampleProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceMultisamplePropertiesEXT( physicalDevice, samples, pMultisampleProperties );
+ }
+
+ //=== VK_KHR_get_memory_requirements2 ===
+
+ void vkGetImageMemoryRequirements2KHR( VkDevice device,
+ const VkImageMemoryRequirementsInfo2 * pInfo,
+ VkMemoryRequirements2 * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetImageMemoryRequirements2KHR( device, pInfo, pMemoryRequirements );
+ }
+
+ void vkGetBufferMemoryRequirements2KHR( VkDevice device,
+ const VkBufferMemoryRequirementsInfo2 * pInfo,
+ VkMemoryRequirements2 * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetBufferMemoryRequirements2KHR( device, pInfo, pMemoryRequirements );
+ }
+
+ void vkGetImageSparseMemoryRequirements2KHR( VkDevice device,
+ const VkImageSparseMemoryRequirementsInfo2 * pInfo,
+ uint32_t * pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetImageSparseMemoryRequirements2KHR( device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements );
+ }
+
+ //=== VK_KHR_acceleration_structure ===
+
+ VkResult vkCreateAccelerationStructureKHR( VkDevice device,
+ const VkAccelerationStructureCreateInfoKHR * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkAccelerationStructureKHR * pAccelerationStructure ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateAccelerationStructureKHR( device, pCreateInfo, pAllocator, pAccelerationStructure );
+ }
+
+ void vkDestroyAccelerationStructureKHR( VkDevice device,
+ VkAccelerationStructureKHR accelerationStructure,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyAccelerationStructureKHR( device, accelerationStructure, pAllocator );
+ }
+
+ void vkCmdBuildAccelerationStructuresKHR( VkCommandBuffer commandBuffer,
+ uint32_t infoCount,
+ const VkAccelerationStructureBuildGeometryInfoKHR * pInfos,
+ const VkAccelerationStructureBuildRangeInfoKHR * const * ppBuildRangeInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBuildAccelerationStructuresKHR( commandBuffer, infoCount, pInfos, ppBuildRangeInfos );
+ }
+
+ void vkCmdBuildAccelerationStructuresIndirectKHR( VkCommandBuffer commandBuffer,
+ uint32_t infoCount,
+ const VkAccelerationStructureBuildGeometryInfoKHR * pInfos,
+ const VkDeviceAddress * pIndirectDeviceAddresses,
+ const uint32_t * pIndirectStrides,
+ const uint32_t * const * ppMaxPrimitiveCounts ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBuildAccelerationStructuresIndirectKHR(
+ commandBuffer, infoCount, pInfos, pIndirectDeviceAddresses, pIndirectStrides, ppMaxPrimitiveCounts );
+ }
+
+ VkResult vkBuildAccelerationStructuresKHR( VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ uint32_t infoCount,
+ const VkAccelerationStructureBuildGeometryInfoKHR * pInfos,
+ const VkAccelerationStructureBuildRangeInfoKHR * const * ppBuildRangeInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBuildAccelerationStructuresKHR( device, deferredOperation, infoCount, pInfos, ppBuildRangeInfos );
+ }
+
+ VkResult vkCopyAccelerationStructureKHR( VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ const VkCopyAccelerationStructureInfoKHR * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCopyAccelerationStructureKHR( device, deferredOperation, pInfo );
+ }
+
+ VkResult vkCopyAccelerationStructureToMemoryKHR( VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ const VkCopyAccelerationStructureToMemoryInfoKHR * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCopyAccelerationStructureToMemoryKHR( device, deferredOperation, pInfo );
+ }
+
+ VkResult vkCopyMemoryToAccelerationStructureKHR( VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ const VkCopyMemoryToAccelerationStructureInfoKHR * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCopyMemoryToAccelerationStructureKHR( device, deferredOperation, pInfo );
+ }
+
+ VkResult vkWriteAccelerationStructuresPropertiesKHR( VkDevice device,
+ uint32_t accelerationStructureCount,
+ const VkAccelerationStructureKHR * pAccelerationStructures,
+ VkQueryType queryType,
+ size_t dataSize,
+ void * pData,
+ size_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkWriteAccelerationStructuresPropertiesKHR( device, accelerationStructureCount, pAccelerationStructures, queryType, dataSize, pData, stride );
+ }
+
+ void vkCmdCopyAccelerationStructureKHR( VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureInfoKHR * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyAccelerationStructureKHR( commandBuffer, pInfo );
+ }
+
+ void vkCmdCopyAccelerationStructureToMemoryKHR( VkCommandBuffer commandBuffer,
+ const VkCopyAccelerationStructureToMemoryInfoKHR * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyAccelerationStructureToMemoryKHR( commandBuffer, pInfo );
+ }
+
+ void vkCmdCopyMemoryToAccelerationStructureKHR( VkCommandBuffer commandBuffer,
+ const VkCopyMemoryToAccelerationStructureInfoKHR * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyMemoryToAccelerationStructureKHR( commandBuffer, pInfo );
+ }
+
+ VkDeviceAddress vkGetAccelerationStructureDeviceAddressKHR( VkDevice device,
+ const VkAccelerationStructureDeviceAddressInfoKHR * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetAccelerationStructureDeviceAddressKHR( device, pInfo );
+ }
+
+ void vkCmdWriteAccelerationStructuresPropertiesKHR( VkCommandBuffer commandBuffer,
+ uint32_t accelerationStructureCount,
+ const VkAccelerationStructureKHR * pAccelerationStructures,
+ VkQueryType queryType,
+ VkQueryPool queryPool,
+ uint32_t firstQuery ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdWriteAccelerationStructuresPropertiesKHR(
+ commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery );
+ }
+
+ void vkGetDeviceAccelerationStructureCompatibilityKHR( VkDevice device,
+ const VkAccelerationStructureVersionInfoKHR * pVersionInfo,
+ VkAccelerationStructureCompatibilityKHR * pCompatibility ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceAccelerationStructureCompatibilityKHR( device, pVersionInfo, pCompatibility );
+ }
+
+ void vkGetAccelerationStructureBuildSizesKHR( VkDevice device,
+ VkAccelerationStructureBuildTypeKHR buildType,
+ const VkAccelerationStructureBuildGeometryInfoKHR * pBuildInfo,
+ const uint32_t * pMaxPrimitiveCounts,
+ VkAccelerationStructureBuildSizesInfoKHR * pSizeInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetAccelerationStructureBuildSizesKHR( device, buildType, pBuildInfo, pMaxPrimitiveCounts, pSizeInfo );
+ }
+
+ //=== VK_KHR_sampler_ycbcr_conversion ===
+
+ VkResult vkCreateSamplerYcbcrConversionKHR( VkDevice device,
+ const VkSamplerYcbcrConversionCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSamplerYcbcrConversion * pYcbcrConversion ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateSamplerYcbcrConversionKHR( device, pCreateInfo, pAllocator, pYcbcrConversion );
+ }
+
+ void vkDestroySamplerYcbcrConversionKHR( VkDevice device,
+ VkSamplerYcbcrConversion ycbcrConversion,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroySamplerYcbcrConversionKHR( device, ycbcrConversion, pAllocator );
+ }
+
+ //=== VK_KHR_bind_memory2 ===
+
+ VkResult vkBindBufferMemory2KHR( VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo * pBindInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBindBufferMemory2KHR( device, bindInfoCount, pBindInfos );
+ }
+
+ VkResult vkBindImageMemory2KHR( VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo * pBindInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBindImageMemory2KHR( device, bindInfoCount, pBindInfos );
+ }
+
+ //=== VK_EXT_image_drm_format_modifier ===
+
+ VkResult
+ vkGetImageDrmFormatModifierPropertiesEXT( VkDevice device, VkImage image, VkImageDrmFormatModifierPropertiesEXT * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetImageDrmFormatModifierPropertiesEXT( device, image, pProperties );
+ }
+
+ //=== VK_EXT_validation_cache ===
+
+ VkResult vkCreateValidationCacheEXT( VkDevice device,
+ const VkValidationCacheCreateInfoEXT * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkValidationCacheEXT * pValidationCache ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateValidationCacheEXT( device, pCreateInfo, pAllocator, pValidationCache );
+ }
+
+ void
+ vkDestroyValidationCacheEXT( VkDevice device, VkValidationCacheEXT validationCache, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyValidationCacheEXT( device, validationCache, pAllocator );
+ }
+
+ VkResult vkMergeValidationCachesEXT( VkDevice device,
+ VkValidationCacheEXT dstCache,
+ uint32_t srcCacheCount,
+ const VkValidationCacheEXT * pSrcCaches ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkMergeValidationCachesEXT( device, dstCache, srcCacheCount, pSrcCaches );
+ }
+
+ VkResult vkGetValidationCacheDataEXT( VkDevice device, VkValidationCacheEXT validationCache, size_t * pDataSize, void * pData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetValidationCacheDataEXT( device, validationCache, pDataSize, pData );
+ }
+
+ //=== VK_NV_shading_rate_image ===
+
+ void vkCmdBindShadingRateImageNV( VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBindShadingRateImageNV( commandBuffer, imageView, imageLayout );
+ }
+
+ void vkCmdSetViewportShadingRatePaletteNV( VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkShadingRatePaletteNV * pShadingRatePalettes ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetViewportShadingRatePaletteNV( commandBuffer, firstViewport, viewportCount, pShadingRatePalettes );
+ }
+
+ void vkCmdSetCoarseSampleOrderNV( VkCommandBuffer commandBuffer,
+ VkCoarseSampleOrderTypeNV sampleOrderType,
+ uint32_t customSampleOrderCount,
+ const VkCoarseSampleOrderCustomNV * pCustomSampleOrders ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetCoarseSampleOrderNV( commandBuffer, sampleOrderType, customSampleOrderCount, pCustomSampleOrders );
+ }
+
+ //=== VK_NV_ray_tracing ===
+
+ VkResult vkCreateAccelerationStructureNV( VkDevice device,
+ const VkAccelerationStructureCreateInfoNV * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkAccelerationStructureNV * pAccelerationStructure ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateAccelerationStructureNV( device, pCreateInfo, pAllocator, pAccelerationStructure );
+ }
+
+ void vkDestroyAccelerationStructureNV( VkDevice device,
+ VkAccelerationStructureNV accelerationStructure,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyAccelerationStructureNV( device, accelerationStructure, pAllocator );
+ }
+
+ void vkGetAccelerationStructureMemoryRequirementsNV( VkDevice device,
+ const VkAccelerationStructureMemoryRequirementsInfoNV * pInfo,
+ VkMemoryRequirements2KHR * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetAccelerationStructureMemoryRequirementsNV( device, pInfo, pMemoryRequirements );
+ }
+
+ VkResult vkBindAccelerationStructureMemoryNV( VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindAccelerationStructureMemoryInfoNV * pBindInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBindAccelerationStructureMemoryNV( device, bindInfoCount, pBindInfos );
+ }
+
+ void vkCmdBuildAccelerationStructureNV( VkCommandBuffer commandBuffer,
+ const VkAccelerationStructureInfoNV * pInfo,
+ VkBuffer instanceData,
+ VkDeviceSize instanceOffset,
+ VkBool32 update,
+ VkAccelerationStructureNV dst,
+ VkAccelerationStructureNV src,
+ VkBuffer scratch,
+ VkDeviceSize scratchOffset ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBuildAccelerationStructureNV( commandBuffer, pInfo, instanceData, instanceOffset, update, dst, src, scratch, scratchOffset );
+ }
+
+ void vkCmdCopyAccelerationStructureNV( VkCommandBuffer commandBuffer,
+ VkAccelerationStructureNV dst,
+ VkAccelerationStructureNV src,
+ VkCopyAccelerationStructureModeKHR mode ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyAccelerationStructureNV( commandBuffer, dst, src, mode );
+ }
+
+ void vkCmdTraceRaysNV( VkCommandBuffer commandBuffer,
+ VkBuffer raygenShaderBindingTableBuffer,
+ VkDeviceSize raygenShaderBindingOffset,
+ VkBuffer missShaderBindingTableBuffer,
+ VkDeviceSize missShaderBindingOffset,
+ VkDeviceSize missShaderBindingStride,
+ VkBuffer hitShaderBindingTableBuffer,
+ VkDeviceSize hitShaderBindingOffset,
+ VkDeviceSize hitShaderBindingStride,
+ VkBuffer callableShaderBindingTableBuffer,
+ VkDeviceSize callableShaderBindingOffset,
+ VkDeviceSize callableShaderBindingStride,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdTraceRaysNV( commandBuffer,
+ raygenShaderBindingTableBuffer,
+ raygenShaderBindingOffset,
+ missShaderBindingTableBuffer,
+ missShaderBindingOffset,
+ missShaderBindingStride,
+ hitShaderBindingTableBuffer,
+ hitShaderBindingOffset,
+ hitShaderBindingStride,
+ callableShaderBindingTableBuffer,
+ callableShaderBindingOffset,
+ callableShaderBindingStride,
+ width,
+ height,
+ depth );
+ }
+
+ VkResult vkCreateRayTracingPipelinesNV( VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkRayTracingPipelineCreateInfoNV * pCreateInfos,
+ const VkAllocationCallbacks * pAllocator,
+ VkPipeline * pPipelines ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateRayTracingPipelinesNV( device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines );
+ }
+
+ VkResult vkGetRayTracingShaderGroupHandlesNV(
+ VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void * pData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetRayTracingShaderGroupHandlesNV( device, pipeline, firstGroup, groupCount, dataSize, pData );
+ }
+
+ VkResult vkGetAccelerationStructureHandleNV( VkDevice device,
+ VkAccelerationStructureNV accelerationStructure,
+ size_t dataSize,
+ void * pData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetAccelerationStructureHandleNV( device, accelerationStructure, dataSize, pData );
+ }
+
+ void vkCmdWriteAccelerationStructuresPropertiesNV( VkCommandBuffer commandBuffer,
+ uint32_t accelerationStructureCount,
+ const VkAccelerationStructureNV * pAccelerationStructures,
+ VkQueryType queryType,
+ VkQueryPool queryPool,
+ uint32_t firstQuery ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdWriteAccelerationStructuresPropertiesNV(
+ commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery );
+ }
+
+ VkResult vkCompileDeferredNV( VkDevice device, VkPipeline pipeline, uint32_t shader ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCompileDeferredNV( device, pipeline, shader );
+ }
+
+ //=== VK_KHR_maintenance3 ===
+
+ void vkGetDescriptorSetLayoutSupportKHR( VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo * pCreateInfo,
+ VkDescriptorSetLayoutSupport * pSupport ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDescriptorSetLayoutSupportKHR( device, pCreateInfo, pSupport );
+ }
+
+ //=== VK_KHR_draw_indirect_count ===
+
+ void vkCmdDrawIndirectCountKHR( VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawIndirectCountKHR( commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride );
+ }
+
+ void vkCmdDrawIndexedIndirectCountKHR( VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawIndexedIndirectCountKHR( commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride );
+ }
+
+ //=== VK_EXT_external_memory_host ===
+
+ VkResult vkGetMemoryHostPointerPropertiesEXT( VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ const void * pHostPointer,
+ VkMemoryHostPointerPropertiesEXT * pMemoryHostPointerProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetMemoryHostPointerPropertiesEXT( device, handleType, pHostPointer, pMemoryHostPointerProperties );
+ }
+
+ //=== VK_AMD_buffer_marker ===
+
+ void vkCmdWriteBufferMarkerAMD( VkCommandBuffer commandBuffer,
+ VkPipelineStageFlagBits pipelineStage,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ uint32_t marker ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdWriteBufferMarkerAMD( commandBuffer, pipelineStage, dstBuffer, dstOffset, marker );
+ }
+
+ //=== VK_EXT_calibrated_timestamps ===
+
+ VkResult vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( VkPhysicalDevice physicalDevice,
+ uint32_t * pTimeDomainCount,
+ VkTimeDomainEXT * pTimeDomains ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( physicalDevice, pTimeDomainCount, pTimeDomains );
+ }
+
+ VkResult vkGetCalibratedTimestampsEXT( VkDevice device,
+ uint32_t timestampCount,
+ const VkCalibratedTimestampInfoEXT * pTimestampInfos,
+ uint64_t * pTimestamps,
+ uint64_t * pMaxDeviation ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetCalibratedTimestampsEXT( device, timestampCount, pTimestampInfos, pTimestamps, pMaxDeviation );
+ }
+
+ //=== VK_NV_mesh_shader ===
+
+ void vkCmdDrawMeshTasksNV( VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawMeshTasksNV( commandBuffer, taskCount, firstTask );
+ }
+
+ void vkCmdDrawMeshTasksIndirectNV( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawMeshTasksIndirectNV( commandBuffer, buffer, offset, drawCount, stride );
+ }
+
+ void vkCmdDrawMeshTasksIndirectCountNV( VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawMeshTasksIndirectCountNV( commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride );
+ }
+
+ //=== VK_NV_scissor_exclusive ===
+
+ void vkCmdSetExclusiveScissorNV( VkCommandBuffer commandBuffer,
+ uint32_t firstExclusiveScissor,
+ uint32_t exclusiveScissorCount,
+ const VkRect2D * pExclusiveScissors ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetExclusiveScissorNV( commandBuffer, firstExclusiveScissor, exclusiveScissorCount, pExclusiveScissors );
+ }
+
+ //=== VK_NV_device_diagnostic_checkpoints ===
+
+ void vkCmdSetCheckpointNV( VkCommandBuffer commandBuffer, const void * pCheckpointMarker ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetCheckpointNV( commandBuffer, pCheckpointMarker );
+ }
+
+ void vkGetQueueCheckpointDataNV( VkQueue queue, uint32_t * pCheckpointDataCount, VkCheckpointDataNV * pCheckpointData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetQueueCheckpointDataNV( queue, pCheckpointDataCount, pCheckpointData );
+ }
+
+ //=== VK_KHR_timeline_semaphore ===
+
+ VkResult vkGetSemaphoreCounterValueKHR( VkDevice device, VkSemaphore semaphore, uint64_t * pValue ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetSemaphoreCounterValueKHR( device, semaphore, pValue );
+ }
+
+ VkResult vkWaitSemaphoresKHR( VkDevice device, const VkSemaphoreWaitInfo * pWaitInfo, uint64_t timeout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkWaitSemaphoresKHR( device, pWaitInfo, timeout );
+ }
+
+ VkResult vkSignalSemaphoreKHR( VkDevice device, const VkSemaphoreSignalInfo * pSignalInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSignalSemaphoreKHR( device, pSignalInfo );
+ }
+
+ //=== VK_INTEL_performance_query ===
+
+ VkResult vkInitializePerformanceApiINTEL( VkDevice device, const VkInitializePerformanceApiInfoINTEL * pInitializeInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkInitializePerformanceApiINTEL( device, pInitializeInfo );
+ }
+
+ void vkUninitializePerformanceApiINTEL( VkDevice device ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkUninitializePerformanceApiINTEL( device );
+ }
+
+ VkResult vkCmdSetPerformanceMarkerINTEL( VkCommandBuffer commandBuffer, const VkPerformanceMarkerInfoINTEL * pMarkerInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetPerformanceMarkerINTEL( commandBuffer, pMarkerInfo );
+ }
+
+ VkResult vkCmdSetPerformanceStreamMarkerINTEL( VkCommandBuffer commandBuffer,
+ const VkPerformanceStreamMarkerInfoINTEL * pMarkerInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetPerformanceStreamMarkerINTEL( commandBuffer, pMarkerInfo );
+ }
+
+ VkResult vkCmdSetPerformanceOverrideINTEL( VkCommandBuffer commandBuffer, const VkPerformanceOverrideInfoINTEL * pOverrideInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetPerformanceOverrideINTEL( commandBuffer, pOverrideInfo );
+ }
+
+ VkResult vkAcquirePerformanceConfigurationINTEL( VkDevice device,
+ const VkPerformanceConfigurationAcquireInfoINTEL * pAcquireInfo,
+ VkPerformanceConfigurationINTEL * pConfiguration ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkAcquirePerformanceConfigurationINTEL( device, pAcquireInfo, pConfiguration );
+ }
+
+ VkResult vkReleasePerformanceConfigurationINTEL( VkDevice device, VkPerformanceConfigurationINTEL configuration ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkReleasePerformanceConfigurationINTEL( device, configuration );
+ }
+
+ VkResult vkQueueSetPerformanceConfigurationINTEL( VkQueue queue, VkPerformanceConfigurationINTEL configuration ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkQueueSetPerformanceConfigurationINTEL( queue, configuration );
+ }
+
+ VkResult
+ vkGetPerformanceParameterINTEL( VkDevice device, VkPerformanceParameterTypeINTEL parameter, VkPerformanceValueINTEL * pValue ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPerformanceParameterINTEL( device, parameter, pValue );
+ }
+
+ //=== VK_AMD_display_native_hdr ===
+
+ void vkSetLocalDimmingAMD( VkDevice device, VkSwapchainKHR swapChain, VkBool32 localDimmingEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSetLocalDimmingAMD( device, swapChain, localDimmingEnable );
+ }
+
+# if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_imagepipe_surface ===
+
+ VkResult vkCreateImagePipeSurfaceFUCHSIA( VkInstance instance,
+ const VkImagePipeSurfaceCreateInfoFUCHSIA * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateImagePipeSurfaceFUCHSIA( instance, pCreateInfo, pAllocator, pSurface );
+ }
+# endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+# if defined( VK_USE_PLATFORM_METAL_EXT )
+ //=== VK_EXT_metal_surface ===
+
+ VkResult vkCreateMetalSurfaceEXT( VkInstance instance,
+ const VkMetalSurfaceCreateInfoEXT * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateMetalSurfaceEXT( instance, pCreateInfo, pAllocator, pSurface );
+ }
+# endif /*VK_USE_PLATFORM_METAL_EXT*/
+
+ //=== VK_KHR_fragment_shading_rate ===
+
+ VkResult vkGetPhysicalDeviceFragmentShadingRatesKHR( VkPhysicalDevice physicalDevice,
+ uint32_t * pFragmentShadingRateCount,
+ VkPhysicalDeviceFragmentShadingRateKHR * pFragmentShadingRates ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceFragmentShadingRatesKHR( physicalDevice, pFragmentShadingRateCount, pFragmentShadingRates );
+ }
+
+ void vkCmdSetFragmentShadingRateKHR( VkCommandBuffer commandBuffer,
+ const VkExtent2D * pFragmentSize,
+ const VkFragmentShadingRateCombinerOpKHR combinerOps[2] ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetFragmentShadingRateKHR( commandBuffer, pFragmentSize, combinerOps );
+ }
+
+ //=== VK_EXT_buffer_device_address ===
+
+ VkDeviceAddress vkGetBufferDeviceAddressEXT( VkDevice device, const VkBufferDeviceAddressInfo * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetBufferDeviceAddressEXT( device, pInfo );
+ }
+
+ //=== VK_EXT_tooling_info ===
+
+ VkResult vkGetPhysicalDeviceToolPropertiesEXT( VkPhysicalDevice physicalDevice,
+ uint32_t * pToolCount,
+ VkPhysicalDeviceToolProperties * pToolProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceToolPropertiesEXT( physicalDevice, pToolCount, pToolProperties );
+ }
+
+ //=== VK_KHR_present_wait ===
+
+ VkResult vkWaitForPresentKHR( VkDevice device, VkSwapchainKHR swapchain, uint64_t presentId, uint64_t timeout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkWaitForPresentKHR( device, swapchain, presentId, timeout );
+ }
+
+ //=== VK_NV_cooperative_matrix ===
+
+ VkResult vkGetPhysicalDeviceCooperativeMatrixPropertiesNV( VkPhysicalDevice physicalDevice,
+ uint32_t * pPropertyCount,
+ VkCooperativeMatrixPropertiesNV * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceCooperativeMatrixPropertiesNV( physicalDevice, pPropertyCount, pProperties );
+ }
+
+ //=== VK_NV_coverage_reduction_mode ===
+
+ VkResult vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(
+ VkPhysicalDevice physicalDevice, uint32_t * pCombinationCount, VkFramebufferMixedSamplesCombinationNV * pCombinations ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV( physicalDevice, pCombinationCount, pCombinations );
+ }
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_EXT_full_screen_exclusive ===
+
+ VkResult vkGetPhysicalDeviceSurfacePresentModes2EXT( VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,
+ uint32_t * pPresentModeCount,
+ VkPresentModeKHR * pPresentModes ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceSurfacePresentModes2EXT( physicalDevice, pSurfaceInfo, pPresentModeCount, pPresentModes );
+ }
+
+ VkResult vkAcquireFullScreenExclusiveModeEXT( VkDevice device, VkSwapchainKHR swapchain ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkAcquireFullScreenExclusiveModeEXT( device, swapchain );
+ }
+
+ VkResult vkReleaseFullScreenExclusiveModeEXT( VkDevice device, VkSwapchainKHR swapchain ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkReleaseFullScreenExclusiveModeEXT( device, swapchain );
+ }
+
+ VkResult vkGetDeviceGroupSurfacePresentModes2EXT( VkDevice device,
+ const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,
+ VkDeviceGroupPresentModeFlagsKHR * pModes ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceGroupSurfacePresentModes2EXT( device, pSurfaceInfo, pModes );
+ }
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_EXT_headless_surface ===
+
+ VkResult vkCreateHeadlessSurfaceEXT( VkInstance instance,
+ const VkHeadlessSurfaceCreateInfoEXT * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateHeadlessSurfaceEXT( instance, pCreateInfo, pAllocator, pSurface );
+ }
+
+ //=== VK_KHR_buffer_device_address ===
+
+ VkDeviceAddress vkGetBufferDeviceAddressKHR( VkDevice device, const VkBufferDeviceAddressInfo * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetBufferDeviceAddressKHR( device, pInfo );
+ }
+
+ uint64_t vkGetBufferOpaqueCaptureAddressKHR( VkDevice device, const VkBufferDeviceAddressInfo * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetBufferOpaqueCaptureAddressKHR( device, pInfo );
+ }
+
+ uint64_t vkGetDeviceMemoryOpaqueCaptureAddressKHR( VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceMemoryOpaqueCaptureAddressKHR( device, pInfo );
+ }
+
+ //=== VK_EXT_line_rasterization ===
+
+ void vkCmdSetLineStippleEXT( VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetLineStippleEXT( commandBuffer, lineStippleFactor, lineStipplePattern );
+ }
+
+ //=== VK_EXT_host_query_reset ===
+
+ void vkResetQueryPoolEXT( VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkResetQueryPoolEXT( device, queryPool, firstQuery, queryCount );
+ }
+
+ //=== VK_EXT_extended_dynamic_state ===
+
+ void vkCmdSetCullModeEXT( VkCommandBuffer commandBuffer, VkCullModeFlags cullMode ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetCullModeEXT( commandBuffer, cullMode );
+ }
+
+ void vkCmdSetFrontFaceEXT( VkCommandBuffer commandBuffer, VkFrontFace frontFace ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetFrontFaceEXT( commandBuffer, frontFace );
+ }
+
+ void vkCmdSetPrimitiveTopologyEXT( VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetPrimitiveTopologyEXT( commandBuffer, primitiveTopology );
+ }
+
+ void vkCmdSetViewportWithCountEXT( VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport * pViewports ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetViewportWithCountEXT( commandBuffer, viewportCount, pViewports );
+ }
+
+ void vkCmdSetScissorWithCountEXT( VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D * pScissors ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetScissorWithCountEXT( commandBuffer, scissorCount, pScissors );
+ }
+
+ void vkCmdBindVertexBuffers2EXT( VkCommandBuffer commandBuffer,
+ uint32_t firstBinding,
+ uint32_t bindingCount,
+ const VkBuffer * pBuffers,
+ const VkDeviceSize * pOffsets,
+ const VkDeviceSize * pSizes,
+ const VkDeviceSize * pStrides ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBindVertexBuffers2EXT( commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes, pStrides );
+ }
+
+ void vkCmdSetDepthTestEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthTestEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthTestEnableEXT( commandBuffer, depthTestEnable );
+ }
+
+ void vkCmdSetDepthWriteEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthWriteEnableEXT( commandBuffer, depthWriteEnable );
+ }
+
+ void vkCmdSetDepthCompareOpEXT( VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthCompareOpEXT( commandBuffer, depthCompareOp );
+ }
+
+ void vkCmdSetDepthBoundsTestEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthBoundsTestEnableEXT( commandBuffer, depthBoundsTestEnable );
+ }
+
+ void vkCmdSetStencilTestEnableEXT( VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetStencilTestEnableEXT( commandBuffer, stencilTestEnable );
+ }
+
+ void vkCmdSetStencilOpEXT( VkCommandBuffer commandBuffer,
+ VkStencilFaceFlags faceMask,
+ VkStencilOp failOp,
+ VkStencilOp passOp,
+ VkStencilOp depthFailOp,
+ VkCompareOp compareOp ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetStencilOpEXT( commandBuffer, faceMask, failOp, passOp, depthFailOp, compareOp );
+ }
+
+ //=== VK_KHR_deferred_host_operations ===
+
+ VkResult vkCreateDeferredOperationKHR( VkDevice device,
+ const VkAllocationCallbacks * pAllocator,
+ VkDeferredOperationKHR * pDeferredOperation ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateDeferredOperationKHR( device, pAllocator, pDeferredOperation );
+ }
+
+ void vkDestroyDeferredOperationKHR( VkDevice device, VkDeferredOperationKHR operation, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyDeferredOperationKHR( device, operation, pAllocator );
+ }
+
+ uint32_t vkGetDeferredOperationMaxConcurrencyKHR( VkDevice device, VkDeferredOperationKHR operation ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeferredOperationMaxConcurrencyKHR( device, operation );
+ }
+
+ VkResult vkGetDeferredOperationResultKHR( VkDevice device, VkDeferredOperationKHR operation ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeferredOperationResultKHR( device, operation );
+ }
+
+ VkResult vkDeferredOperationJoinKHR( VkDevice device, VkDeferredOperationKHR operation ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDeferredOperationJoinKHR( device, operation );
+ }
+
+ //=== VK_KHR_pipeline_executable_properties ===
+
+ VkResult vkGetPipelineExecutablePropertiesKHR( VkDevice device,
+ const VkPipelineInfoKHR * pPipelineInfo,
+ uint32_t * pExecutableCount,
+ VkPipelineExecutablePropertiesKHR * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPipelineExecutablePropertiesKHR( device, pPipelineInfo, pExecutableCount, pProperties );
+ }
+
+ VkResult vkGetPipelineExecutableStatisticsKHR( VkDevice device,
+ const VkPipelineExecutableInfoKHR * pExecutableInfo,
+ uint32_t * pStatisticCount,
+ VkPipelineExecutableStatisticKHR * pStatistics ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPipelineExecutableStatisticsKHR( device, pExecutableInfo, pStatisticCount, pStatistics );
+ }
+
+ VkResult
+ vkGetPipelineExecutableInternalRepresentationsKHR( VkDevice device,
+ const VkPipelineExecutableInfoKHR * pExecutableInfo,
+ uint32_t * pInternalRepresentationCount,
+ VkPipelineExecutableInternalRepresentationKHR * pInternalRepresentations ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPipelineExecutableInternalRepresentationsKHR( device, pExecutableInfo, pInternalRepresentationCount, pInternalRepresentations );
+ }
+
+ //=== VK_NV_device_generated_commands ===
+
+ void vkGetGeneratedCommandsMemoryRequirementsNV( VkDevice device,
+ const VkGeneratedCommandsMemoryRequirementsInfoNV * pInfo,
+ VkMemoryRequirements2 * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetGeneratedCommandsMemoryRequirementsNV( device, pInfo, pMemoryRequirements );
+ }
+
+ void vkCmdPreprocessGeneratedCommandsNV( VkCommandBuffer commandBuffer, const VkGeneratedCommandsInfoNV * pGeneratedCommandsInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdPreprocessGeneratedCommandsNV( commandBuffer, pGeneratedCommandsInfo );
+ }
+
+ void vkCmdExecuteGeneratedCommandsNV( VkCommandBuffer commandBuffer,
+ VkBool32 isPreprocessed,
+ const VkGeneratedCommandsInfoNV * pGeneratedCommandsInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdExecuteGeneratedCommandsNV( commandBuffer, isPreprocessed, pGeneratedCommandsInfo );
+ }
+
+ void vkCmdBindPipelineShaderGroupNV( VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipeline pipeline,
+ uint32_t groupIndex ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBindPipelineShaderGroupNV( commandBuffer, pipelineBindPoint, pipeline, groupIndex );
+ }
+
+ VkResult vkCreateIndirectCommandsLayoutNV( VkDevice device,
+ const VkIndirectCommandsLayoutCreateInfoNV * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkIndirectCommandsLayoutNV * pIndirectCommandsLayout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateIndirectCommandsLayoutNV( device, pCreateInfo, pAllocator, pIndirectCommandsLayout );
+ }
+
+ void vkDestroyIndirectCommandsLayoutNV( VkDevice device,
+ VkIndirectCommandsLayoutNV indirectCommandsLayout,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyIndirectCommandsLayoutNV( device, indirectCommandsLayout, pAllocator );
+ }
+
+ //=== VK_EXT_acquire_drm_display ===
+
+ VkResult vkAcquireDrmDisplayEXT( VkPhysicalDevice physicalDevice, int32_t drmFd, VkDisplayKHR display ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkAcquireDrmDisplayEXT( physicalDevice, drmFd, display );
+ }
+
+ VkResult vkGetDrmDisplayEXT( VkPhysicalDevice physicalDevice, int32_t drmFd, uint32_t connectorId, VkDisplayKHR * display ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDrmDisplayEXT( physicalDevice, drmFd, connectorId, display );
+ }
+
+ //=== VK_EXT_private_data ===
+
+ VkResult vkCreatePrivateDataSlotEXT( VkDevice device,
+ const VkPrivateDataSlotCreateInfo * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkPrivateDataSlot * pPrivateDataSlot ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreatePrivateDataSlotEXT( device, pCreateInfo, pAllocator, pPrivateDataSlot );
+ }
+
+ void vkDestroyPrivateDataSlotEXT( VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyPrivateDataSlotEXT( device, privateDataSlot, pAllocator );
+ }
+
+ VkResult vkSetPrivateDataEXT( VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSetPrivateDataEXT( device, objectType, objectHandle, privateDataSlot, data );
+ }
+
+ void vkGetPrivateDataEXT( VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t * pData ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPrivateDataEXT( device, objectType, objectHandle, privateDataSlot, pData );
+ }
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_encode_queue ===
+
+ void vkCmdEncodeVideoKHR( VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR * pEncodeInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdEncodeVideoKHR( commandBuffer, pEncodeInfo );
+ }
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+# if defined( VK_USE_PLATFORM_METAL_EXT )
+ //=== VK_EXT_metal_objects ===
+
+ void vkExportMetalObjectsEXT( VkDevice device, VkExportMetalObjectsInfoEXT * pMetalObjectsInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkExportMetalObjectsEXT( device, pMetalObjectsInfo );
+ }
+# endif /*VK_USE_PLATFORM_METAL_EXT*/
+
+ //=== VK_KHR_synchronization2 ===
+
+ void vkCmdSetEvent2KHR( VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo * pDependencyInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetEvent2KHR( commandBuffer, event, pDependencyInfo );
+ }
+
+ void vkCmdResetEvent2KHR( VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdResetEvent2KHR( commandBuffer, event, stageMask );
+ }
+
+ void vkCmdWaitEvents2KHR( VkCommandBuffer commandBuffer,
+ uint32_t eventCount,
+ const VkEvent * pEvents,
+ const VkDependencyInfo * pDependencyInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdWaitEvents2KHR( commandBuffer, eventCount, pEvents, pDependencyInfos );
+ }
+
+ void vkCmdPipelineBarrier2KHR( VkCommandBuffer commandBuffer, const VkDependencyInfo * pDependencyInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdPipelineBarrier2KHR( commandBuffer, pDependencyInfo );
+ }
+
+ void vkCmdWriteTimestamp2KHR( VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdWriteTimestamp2KHR( commandBuffer, stage, queryPool, query );
+ }
+
+ VkResult vkQueueSubmit2KHR( VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 * pSubmits, VkFence fence ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkQueueSubmit2KHR( queue, submitCount, pSubmits, fence );
+ }
+
+ void vkCmdWriteBufferMarker2AMD(
+ VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdWriteBufferMarker2AMD( commandBuffer, stage, dstBuffer, dstOffset, marker );
+ }
+
+ void vkGetQueueCheckpointData2NV( VkQueue queue, uint32_t * pCheckpointDataCount, VkCheckpointData2NV * pCheckpointData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetQueueCheckpointData2NV( queue, pCheckpointDataCount, pCheckpointData );
+ }
+
+ //=== VK_NV_fragment_shading_rate_enums ===
+
+ void vkCmdSetFragmentShadingRateEnumNV( VkCommandBuffer commandBuffer,
+ VkFragmentShadingRateNV shadingRate,
+ const VkFragmentShadingRateCombinerOpKHR combinerOps[2] ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetFragmentShadingRateEnumNV( commandBuffer, shadingRate, combinerOps );
+ }
+
+ //=== VK_EXT_mesh_shader ===
+
+ void vkCmdDrawMeshTasksEXT( VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawMeshTasksEXT( commandBuffer, groupCountX, groupCountY, groupCountZ );
+ }
+
+ void vkCmdDrawMeshTasksIndirectEXT( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawMeshTasksIndirectEXT( commandBuffer, buffer, offset, drawCount, stride );
+ }
+
+ void vkCmdDrawMeshTasksIndirectCountEXT( VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawMeshTasksIndirectCountEXT( commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride );
+ }
+
+ //=== VK_KHR_copy_commands2 ===
+
+ void vkCmdCopyBuffer2KHR( VkCommandBuffer commandBuffer, const VkCopyBufferInfo2 * pCopyBufferInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyBuffer2KHR( commandBuffer, pCopyBufferInfo );
+ }
+
+ void vkCmdCopyImage2KHR( VkCommandBuffer commandBuffer, const VkCopyImageInfo2 * pCopyImageInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyImage2KHR( commandBuffer, pCopyImageInfo );
+ }
+
+ void vkCmdCopyBufferToImage2KHR( VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2 * pCopyBufferToImageInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyBufferToImage2KHR( commandBuffer, pCopyBufferToImageInfo );
+ }
+
+ void vkCmdCopyImageToBuffer2KHR( VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2 * pCopyImageToBufferInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyImageToBuffer2KHR( commandBuffer, pCopyImageToBufferInfo );
+ }
+
+ void vkCmdBlitImage2KHR( VkCommandBuffer commandBuffer, const VkBlitImageInfo2 * pBlitImageInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBlitImage2KHR( commandBuffer, pBlitImageInfo );
+ }
+
+ void vkCmdResolveImage2KHR( VkCommandBuffer commandBuffer, const VkResolveImageInfo2 * pResolveImageInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdResolveImage2KHR( commandBuffer, pResolveImageInfo );
+ }
+
+ //=== VK_EXT_image_compression_control ===
+
+ void vkGetImageSubresourceLayout2EXT( VkDevice device,
+ VkImage image,
+ const VkImageSubresource2EXT * pSubresource,
+ VkSubresourceLayout2EXT * pLayout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetImageSubresourceLayout2EXT( device, image, pSubresource, pLayout );
+ }
+
+ //=== VK_EXT_device_fault ===
+
+ VkResult vkGetDeviceFaultInfoEXT( VkDevice device, VkDeviceFaultCountsEXT * pFaultCounts, VkDeviceFaultInfoEXT * pFaultInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceFaultInfoEXT( device, pFaultCounts, pFaultInfo );
+ }
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_NV_acquire_winrt_display ===
+
+ VkResult vkAcquireWinrtDisplayNV( VkPhysicalDevice physicalDevice, VkDisplayKHR display ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkAcquireWinrtDisplayNV( physicalDevice, display );
+ }
+
+ VkResult vkGetWinrtDisplayNV( VkPhysicalDevice physicalDevice, uint32_t deviceRelativeId, VkDisplayKHR * pDisplay ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetWinrtDisplayNV( physicalDevice, deviceRelativeId, pDisplay );
+ }
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+# if defined( VK_USE_PLATFORM_DIRECTFB_EXT )
+ //=== VK_EXT_directfb_surface ===
+
+ VkResult vkCreateDirectFBSurfaceEXT( VkInstance instance,
+ const VkDirectFBSurfaceCreateInfoEXT * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateDirectFBSurfaceEXT( instance, pCreateInfo, pAllocator, pSurface );
+ }
+
+ VkBool32
+ vkGetPhysicalDeviceDirectFBPresentationSupportEXT( VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB * dfb ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceDirectFBPresentationSupportEXT( physicalDevice, queueFamilyIndex, dfb );
+ }
+# endif /*VK_USE_PLATFORM_DIRECTFB_EXT*/
+
+ //=== VK_KHR_ray_tracing_pipeline ===
+
+ void vkCmdTraceRaysKHR( VkCommandBuffer commandBuffer,
+ const VkStridedDeviceAddressRegionKHR * pRaygenShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR * pMissShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR * pHitShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR * pCallableShaderBindingTable,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdTraceRaysKHR(
+ commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable, pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth );
+ }
+
+ VkResult vkCreateRayTracingPipelinesKHR( VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkRayTracingPipelineCreateInfoKHR * pCreateInfos,
+ const VkAllocationCallbacks * pAllocator,
+ VkPipeline * pPipelines ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateRayTracingPipelinesKHR( device, deferredOperation, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines );
+ }
+
+ VkResult vkGetRayTracingShaderGroupHandlesKHR(
+ VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void * pData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetRayTracingShaderGroupHandlesKHR( device, pipeline, firstGroup, groupCount, dataSize, pData );
+ }
+
+ VkResult vkGetRayTracingCaptureReplayShaderGroupHandlesKHR(
+ VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void * pData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetRayTracingCaptureReplayShaderGroupHandlesKHR( device, pipeline, firstGroup, groupCount, dataSize, pData );
+ }
+
+ void vkCmdTraceRaysIndirectKHR( VkCommandBuffer commandBuffer,
+ const VkStridedDeviceAddressRegionKHR * pRaygenShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR * pMissShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR * pHitShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR * pCallableShaderBindingTable,
+ VkDeviceAddress indirectDeviceAddress ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdTraceRaysIndirectKHR(
+ commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable, pHitShaderBindingTable, pCallableShaderBindingTable, indirectDeviceAddress );
+ }
+
+ VkDeviceSize vkGetRayTracingShaderGroupStackSizeKHR( VkDevice device,
+ VkPipeline pipeline,
+ uint32_t group,
+ VkShaderGroupShaderKHR groupShader ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetRayTracingShaderGroupStackSizeKHR( device, pipeline, group, groupShader );
+ }
+
+ void vkCmdSetRayTracingPipelineStackSizeKHR( VkCommandBuffer commandBuffer, uint32_t pipelineStackSize ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetRayTracingPipelineStackSizeKHR( commandBuffer, pipelineStackSize );
+ }
+
+ //=== VK_EXT_vertex_input_dynamic_state ===
+
+ void vkCmdSetVertexInputEXT( VkCommandBuffer commandBuffer,
+ uint32_t vertexBindingDescriptionCount,
+ const VkVertexInputBindingDescription2EXT * pVertexBindingDescriptions,
+ uint32_t vertexAttributeDescriptionCount,
+ const VkVertexInputAttributeDescription2EXT * pVertexAttributeDescriptions ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetVertexInputEXT(
+ commandBuffer, vertexBindingDescriptionCount, pVertexBindingDescriptions, vertexAttributeDescriptionCount, pVertexAttributeDescriptions );
+ }
+
+# if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_external_memory ===
+
+ VkResult vkGetMemoryZirconHandleFUCHSIA( VkDevice device,
+ const VkMemoryGetZirconHandleInfoFUCHSIA * pGetZirconHandleInfo,
+ zx_handle_t * pZirconHandle ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetMemoryZirconHandleFUCHSIA( device, pGetZirconHandleInfo, pZirconHandle );
+ }
+
+ VkResult vkGetMemoryZirconHandlePropertiesFUCHSIA( VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ zx_handle_t zirconHandle,
+ VkMemoryZirconHandlePropertiesFUCHSIA * pMemoryZirconHandleProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetMemoryZirconHandlePropertiesFUCHSIA( device, handleType, zirconHandle, pMemoryZirconHandleProperties );
+ }
+# endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+# if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_external_semaphore ===
+
+ VkResult vkImportSemaphoreZirconHandleFUCHSIA( VkDevice device,
+ const VkImportSemaphoreZirconHandleInfoFUCHSIA * pImportSemaphoreZirconHandleInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkImportSemaphoreZirconHandleFUCHSIA( device, pImportSemaphoreZirconHandleInfo );
+ }
+
+ VkResult vkGetSemaphoreZirconHandleFUCHSIA( VkDevice device,
+ const VkSemaphoreGetZirconHandleInfoFUCHSIA * pGetZirconHandleInfo,
+ zx_handle_t * pZirconHandle ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetSemaphoreZirconHandleFUCHSIA( device, pGetZirconHandleInfo, pZirconHandle );
+ }
+# endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+# if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_buffer_collection ===
+
+ VkResult vkCreateBufferCollectionFUCHSIA( VkDevice device,
+ const VkBufferCollectionCreateInfoFUCHSIA * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkBufferCollectionFUCHSIA * pCollection ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateBufferCollectionFUCHSIA( device, pCreateInfo, pAllocator, pCollection );
+ }
+
+ VkResult vkSetBufferCollectionImageConstraintsFUCHSIA( VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ const VkImageConstraintsInfoFUCHSIA * pImageConstraintsInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSetBufferCollectionImageConstraintsFUCHSIA( device, collection, pImageConstraintsInfo );
+ }
+
+ VkResult vkSetBufferCollectionBufferConstraintsFUCHSIA( VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ const VkBufferConstraintsInfoFUCHSIA * pBufferConstraintsInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSetBufferCollectionBufferConstraintsFUCHSIA( device, collection, pBufferConstraintsInfo );
+ }
+
+ void vkDestroyBufferCollectionFUCHSIA( VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyBufferCollectionFUCHSIA( device, collection, pAllocator );
+ }
+
+ VkResult vkGetBufferCollectionPropertiesFUCHSIA( VkDevice device,
+ VkBufferCollectionFUCHSIA collection,
+ VkBufferCollectionPropertiesFUCHSIA * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetBufferCollectionPropertiesFUCHSIA( device, collection, pProperties );
+ }
+# endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+ //=== VK_HUAWEI_subpass_shading ===
+
+ VkResult
+ vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI( VkDevice device, VkRenderPass renderpass, VkExtent2D * pMaxWorkgroupSize ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI( device, renderpass, pMaxWorkgroupSize );
+ }
+
+ void vkCmdSubpassShadingHUAWEI( VkCommandBuffer commandBuffer ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSubpassShadingHUAWEI( commandBuffer );
+ }
+
+ //=== VK_HUAWEI_invocation_mask ===
+
+ void vkCmdBindInvocationMaskHUAWEI( VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBindInvocationMaskHUAWEI( commandBuffer, imageView, imageLayout );
+ }
+
+ //=== VK_NV_external_memory_rdma ===
+
+ VkResult vkGetMemoryRemoteAddressNV( VkDevice device,
+ const VkMemoryGetRemoteAddressInfoNV * pMemoryGetRemoteAddressInfo,
+ VkRemoteAddressNV * pAddress ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetMemoryRemoteAddressNV( device, pMemoryGetRemoteAddressInfo, pAddress );
+ }
+
+ //=== VK_EXT_pipeline_properties ===
+
+ VkResult
+ vkGetPipelinePropertiesEXT( VkDevice device, const VkPipelineInfoEXT * pPipelineInfo, VkBaseOutStructure * pPipelineProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPipelinePropertiesEXT( device, pPipelineInfo, pPipelineProperties );
+ }
+
+ //=== VK_EXT_extended_dynamic_state2 ===
+
+ void vkCmdSetPatchControlPointsEXT( VkCommandBuffer commandBuffer, uint32_t patchControlPoints ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetPatchControlPointsEXT( commandBuffer, patchControlPoints );
+ }
+
+ void vkCmdSetRasterizerDiscardEnableEXT( VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetRasterizerDiscardEnableEXT( commandBuffer, rasterizerDiscardEnable );
+ }
+
+ void vkCmdSetDepthBiasEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthBiasEnableEXT( commandBuffer, depthBiasEnable );
+ }
+
+ void vkCmdSetLogicOpEXT( VkCommandBuffer commandBuffer, VkLogicOp logicOp ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetLogicOpEXT( commandBuffer, logicOp );
+ }
+
+ void vkCmdSetPrimitiveRestartEnableEXT( VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetPrimitiveRestartEnableEXT( commandBuffer, primitiveRestartEnable );
+ }
+
+# if defined( VK_USE_PLATFORM_SCREEN_QNX )
+ //=== VK_QNX_screen_surface ===
+
+ VkResult vkCreateScreenSurfaceQNX( VkInstance instance,
+ const VkScreenSurfaceCreateInfoQNX * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkSurfaceKHR * pSurface ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateScreenSurfaceQNX( instance, pCreateInfo, pAllocator, pSurface );
+ }
+
+ VkBool32 vkGetPhysicalDeviceScreenPresentationSupportQNX( VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ struct _screen_window * window ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceScreenPresentationSupportQNX( physicalDevice, queueFamilyIndex, window );
+ }
+# endif /*VK_USE_PLATFORM_SCREEN_QNX*/
+
+ //=== VK_EXT_color_write_enable ===
+
+ void vkCmdSetColorWriteEnableEXT( VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkBool32 * pColorWriteEnables ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetColorWriteEnableEXT( commandBuffer, attachmentCount, pColorWriteEnables );
+ }
+
+ //=== VK_KHR_ray_tracing_maintenance1 ===
+
+ void vkCmdTraceRaysIndirect2KHR( VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdTraceRaysIndirect2KHR( commandBuffer, indirectDeviceAddress );
+ }
+
+ //=== VK_EXT_multi_draw ===
+
+ void vkCmdDrawMultiEXT( VkCommandBuffer commandBuffer,
+ uint32_t drawCount,
+ const VkMultiDrawInfoEXT * pVertexInfo,
+ uint32_t instanceCount,
+ uint32_t firstInstance,
+ uint32_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawMultiEXT( commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance, stride );
+ }
+
+ void vkCmdDrawMultiIndexedEXT( VkCommandBuffer commandBuffer,
+ uint32_t drawCount,
+ const VkMultiDrawIndexedInfoEXT * pIndexInfo,
+ uint32_t instanceCount,
+ uint32_t firstInstance,
+ uint32_t stride,
+ const int32_t * pVertexOffset ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdDrawMultiIndexedEXT( commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance, stride, pVertexOffset );
+ }
+
+ //=== VK_EXT_opacity_micromap ===
+
+ VkResult vkCreateMicromapEXT( VkDevice device,
+ const VkMicromapCreateInfoEXT * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkMicromapEXT * pMicromap ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateMicromapEXT( device, pCreateInfo, pAllocator, pMicromap );
+ }
+
+ void vkDestroyMicromapEXT( VkDevice device, VkMicromapEXT micromap, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyMicromapEXT( device, micromap, pAllocator );
+ }
+
+ void vkCmdBuildMicromapsEXT( VkCommandBuffer commandBuffer, uint32_t infoCount, const VkMicromapBuildInfoEXT * pInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdBuildMicromapsEXT( commandBuffer, infoCount, pInfos );
+ }
+
+ VkResult vkBuildMicromapsEXT( VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ uint32_t infoCount,
+ const VkMicromapBuildInfoEXT * pInfos ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBuildMicromapsEXT( device, deferredOperation, infoCount, pInfos );
+ }
+
+ VkResult vkCopyMicromapEXT( VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMicromapInfoEXT * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCopyMicromapEXT( device, deferredOperation, pInfo );
+ }
+
+ VkResult vkCopyMicromapToMemoryEXT( VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ const VkCopyMicromapToMemoryInfoEXT * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCopyMicromapToMemoryEXT( device, deferredOperation, pInfo );
+ }
+
+ VkResult vkCopyMemoryToMicromapEXT( VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ const VkCopyMemoryToMicromapInfoEXT * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCopyMemoryToMicromapEXT( device, deferredOperation, pInfo );
+ }
+
+ VkResult vkWriteMicromapsPropertiesEXT( VkDevice device,
+ uint32_t micromapCount,
+ const VkMicromapEXT * pMicromaps,
+ VkQueryType queryType,
+ size_t dataSize,
+ void * pData,
+ size_t stride ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkWriteMicromapsPropertiesEXT( device, micromapCount, pMicromaps, queryType, dataSize, pData, stride );
+ }
+
+ void vkCmdCopyMicromapEXT( VkCommandBuffer commandBuffer, const VkCopyMicromapInfoEXT * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyMicromapEXT( commandBuffer, pInfo );
+ }
+
+ void vkCmdCopyMicromapToMemoryEXT( VkCommandBuffer commandBuffer, const VkCopyMicromapToMemoryInfoEXT * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyMicromapToMemoryEXT( commandBuffer, pInfo );
+ }
+
+ void vkCmdCopyMemoryToMicromapEXT( VkCommandBuffer commandBuffer, const VkCopyMemoryToMicromapInfoEXT * pInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdCopyMemoryToMicromapEXT( commandBuffer, pInfo );
+ }
+
+ void vkCmdWriteMicromapsPropertiesEXT( VkCommandBuffer commandBuffer,
+ uint32_t micromapCount,
+ const VkMicromapEXT * pMicromaps,
+ VkQueryType queryType,
+ VkQueryPool queryPool,
+ uint32_t firstQuery ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdWriteMicromapsPropertiesEXT( commandBuffer, micromapCount, pMicromaps, queryType, queryPool, firstQuery );
+ }
+
+ void vkGetDeviceMicromapCompatibilityEXT( VkDevice device,
+ const VkMicromapVersionInfoEXT * pVersionInfo,
+ VkAccelerationStructureCompatibilityKHR * pCompatibility ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceMicromapCompatibilityEXT( device, pVersionInfo, pCompatibility );
+ }
+
+ void vkGetMicromapBuildSizesEXT( VkDevice device,
+ VkAccelerationStructureBuildTypeKHR buildType,
+ const VkMicromapBuildInfoEXT * pBuildInfo,
+ VkMicromapBuildSizesInfoEXT * pSizeInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetMicromapBuildSizesEXT( device, buildType, pBuildInfo, pSizeInfo );
+ }
+
+ //=== VK_EXT_pageable_device_local_memory ===
+
+ void vkSetDeviceMemoryPriorityEXT( VkDevice device, VkDeviceMemory memory, float priority ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkSetDeviceMemoryPriorityEXT( device, memory, priority );
+ }
+
+ //=== VK_KHR_maintenance4 ===
+
+ void vkGetDeviceBufferMemoryRequirementsKHR( VkDevice device,
+ const VkDeviceBufferMemoryRequirements * pInfo,
+ VkMemoryRequirements2 * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceBufferMemoryRequirementsKHR( device, pInfo, pMemoryRequirements );
+ }
+
+ void vkGetDeviceImageMemoryRequirementsKHR( VkDevice device,
+ const VkDeviceImageMemoryRequirements * pInfo,
+ VkMemoryRequirements2 * pMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceImageMemoryRequirementsKHR( device, pInfo, pMemoryRequirements );
+ }
+
+ void vkGetDeviceImageSparseMemoryRequirementsKHR( VkDevice device,
+ const VkDeviceImageMemoryRequirements * pInfo,
+ uint32_t * pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDeviceImageSparseMemoryRequirementsKHR( device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements );
+ }
+
+ //=== VK_VALVE_descriptor_set_host_mapping ===
+
+ void vkGetDescriptorSetLayoutHostMappingInfoVALVE( VkDevice device,
+ const VkDescriptorSetBindingReferenceVALVE * pBindingReference,
+ VkDescriptorSetLayoutHostMappingInfoVALVE * pHostMapping ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDescriptorSetLayoutHostMappingInfoVALVE( device, pBindingReference, pHostMapping );
+ }
+
+ void vkGetDescriptorSetHostMappingVALVE( VkDevice device, VkDescriptorSet descriptorSet, void ** ppData ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDescriptorSetHostMappingVALVE( device, descriptorSet, ppData );
+ }
+
+ //=== VK_EXT_extended_dynamic_state3 ===
+
+ void vkCmdSetTessellationDomainOriginEXT( VkCommandBuffer commandBuffer, VkTessellationDomainOrigin domainOrigin ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetTessellationDomainOriginEXT( commandBuffer, domainOrigin );
+ }
+
+ void vkCmdSetDepthClampEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthClampEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthClampEnableEXT( commandBuffer, depthClampEnable );
+ }
+
+ void vkCmdSetPolygonModeEXT( VkCommandBuffer commandBuffer, VkPolygonMode polygonMode ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetPolygonModeEXT( commandBuffer, polygonMode );
+ }
+
+ void vkCmdSetRasterizationSamplesEXT( VkCommandBuffer commandBuffer, VkSampleCountFlagBits rasterizationSamples ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetRasterizationSamplesEXT( commandBuffer, rasterizationSamples );
+ }
+
+ void vkCmdSetSampleMaskEXT( VkCommandBuffer commandBuffer, VkSampleCountFlagBits samples, const VkSampleMask * pSampleMask ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetSampleMaskEXT( commandBuffer, samples, pSampleMask );
+ }
+
+ void vkCmdSetAlphaToCoverageEnableEXT( VkCommandBuffer commandBuffer, VkBool32 alphaToCoverageEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetAlphaToCoverageEnableEXT( commandBuffer, alphaToCoverageEnable );
+ }
+
+ void vkCmdSetAlphaToOneEnableEXT( VkCommandBuffer commandBuffer, VkBool32 alphaToOneEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetAlphaToOneEnableEXT( commandBuffer, alphaToOneEnable );
+ }
+
+ void vkCmdSetLogicOpEnableEXT( VkCommandBuffer commandBuffer, VkBool32 logicOpEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetLogicOpEnableEXT( commandBuffer, logicOpEnable );
+ }
+
+ void vkCmdSetColorBlendEnableEXT( VkCommandBuffer commandBuffer,
+ uint32_t firstAttachment,
+ uint32_t attachmentCount,
+ const VkBool32 * pColorBlendEnables ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetColorBlendEnableEXT( commandBuffer, firstAttachment, attachmentCount, pColorBlendEnables );
+ }
+
+ void vkCmdSetColorBlendEquationEXT( VkCommandBuffer commandBuffer,
+ uint32_t firstAttachment,
+ uint32_t attachmentCount,
+ const VkColorBlendEquationEXT * pColorBlendEquations ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetColorBlendEquationEXT( commandBuffer, firstAttachment, attachmentCount, pColorBlendEquations );
+ }
+
+ void vkCmdSetColorWriteMaskEXT( VkCommandBuffer commandBuffer,
+ uint32_t firstAttachment,
+ uint32_t attachmentCount,
+ const VkColorComponentFlags * pColorWriteMasks ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetColorWriteMaskEXT( commandBuffer, firstAttachment, attachmentCount, pColorWriteMasks );
+ }
+
+ void vkCmdSetRasterizationStreamEXT( VkCommandBuffer commandBuffer, uint32_t rasterizationStream ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetRasterizationStreamEXT( commandBuffer, rasterizationStream );
+ }
+
+ void vkCmdSetConservativeRasterizationModeEXT( VkCommandBuffer commandBuffer,
+ VkConservativeRasterizationModeEXT conservativeRasterizationMode ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetConservativeRasterizationModeEXT( commandBuffer, conservativeRasterizationMode );
+ }
+
+ void vkCmdSetExtraPrimitiveOverestimationSizeEXT( VkCommandBuffer commandBuffer, float extraPrimitiveOverestimationSize ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetExtraPrimitiveOverestimationSizeEXT( commandBuffer, extraPrimitiveOverestimationSize );
+ }
+
+ void vkCmdSetDepthClipEnableEXT( VkCommandBuffer commandBuffer, VkBool32 depthClipEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthClipEnableEXT( commandBuffer, depthClipEnable );
+ }
+
+ void vkCmdSetSampleLocationsEnableEXT( VkCommandBuffer commandBuffer, VkBool32 sampleLocationsEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetSampleLocationsEnableEXT( commandBuffer, sampleLocationsEnable );
+ }
+
+ void vkCmdSetColorBlendAdvancedEXT( VkCommandBuffer commandBuffer,
+ uint32_t firstAttachment,
+ uint32_t attachmentCount,
+ const VkColorBlendAdvancedEXT * pColorBlendAdvanced ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetColorBlendAdvancedEXT( commandBuffer, firstAttachment, attachmentCount, pColorBlendAdvanced );
+ }
+
+ void vkCmdSetProvokingVertexModeEXT( VkCommandBuffer commandBuffer, VkProvokingVertexModeEXT provokingVertexMode ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetProvokingVertexModeEXT( commandBuffer, provokingVertexMode );
+ }
+
+ void vkCmdSetLineRasterizationModeEXT( VkCommandBuffer commandBuffer, VkLineRasterizationModeEXT lineRasterizationMode ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetLineRasterizationModeEXT( commandBuffer, lineRasterizationMode );
+ }
+
+ void vkCmdSetLineStippleEnableEXT( VkCommandBuffer commandBuffer, VkBool32 stippledLineEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetLineStippleEnableEXT( commandBuffer, stippledLineEnable );
+ }
+
+ void vkCmdSetDepthClipNegativeOneToOneEXT( VkCommandBuffer commandBuffer, VkBool32 negativeOneToOne ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetDepthClipNegativeOneToOneEXT( commandBuffer, negativeOneToOne );
+ }
+
+ void vkCmdSetViewportWScalingEnableNV( VkCommandBuffer commandBuffer, VkBool32 viewportWScalingEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetViewportWScalingEnableNV( commandBuffer, viewportWScalingEnable );
+ }
+
+ void vkCmdSetViewportSwizzleNV( VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkViewportSwizzleNV * pViewportSwizzles ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetViewportSwizzleNV( commandBuffer, firstViewport, viewportCount, pViewportSwizzles );
+ }
+
+ void vkCmdSetCoverageToColorEnableNV( VkCommandBuffer commandBuffer, VkBool32 coverageToColorEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetCoverageToColorEnableNV( commandBuffer, coverageToColorEnable );
+ }
+
+ void vkCmdSetCoverageToColorLocationNV( VkCommandBuffer commandBuffer, uint32_t coverageToColorLocation ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetCoverageToColorLocationNV( commandBuffer, coverageToColorLocation );
+ }
+
+ void vkCmdSetCoverageModulationModeNV( VkCommandBuffer commandBuffer, VkCoverageModulationModeNV coverageModulationMode ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetCoverageModulationModeNV( commandBuffer, coverageModulationMode );
+ }
+
+ void vkCmdSetCoverageModulationTableEnableNV( VkCommandBuffer commandBuffer, VkBool32 coverageModulationTableEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetCoverageModulationTableEnableNV( commandBuffer, coverageModulationTableEnable );
+ }
+
+ void vkCmdSetCoverageModulationTableNV( VkCommandBuffer commandBuffer,
+ uint32_t coverageModulationTableCount,
+ const float * pCoverageModulationTable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetCoverageModulationTableNV( commandBuffer, coverageModulationTableCount, pCoverageModulationTable );
+ }
+
+ void vkCmdSetShadingRateImageEnableNV( VkCommandBuffer commandBuffer, VkBool32 shadingRateImageEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetShadingRateImageEnableNV( commandBuffer, shadingRateImageEnable );
+ }
+
+ void vkCmdSetRepresentativeFragmentTestEnableNV( VkCommandBuffer commandBuffer, VkBool32 representativeFragmentTestEnable ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetRepresentativeFragmentTestEnableNV( commandBuffer, representativeFragmentTestEnable );
+ }
+
+ void vkCmdSetCoverageReductionModeNV( VkCommandBuffer commandBuffer, VkCoverageReductionModeNV coverageReductionMode ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdSetCoverageReductionModeNV( commandBuffer, coverageReductionMode );
+ }
+
+ //=== VK_EXT_shader_module_identifier ===
+
+ void vkGetShaderModuleIdentifierEXT( VkDevice device, VkShaderModule shaderModule, VkShaderModuleIdentifierEXT * pIdentifier ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetShaderModuleIdentifierEXT( device, shaderModule, pIdentifier );
+ }
+
+ void vkGetShaderModuleCreateInfoIdentifierEXT( VkDevice device,
+ const VkShaderModuleCreateInfo * pCreateInfo,
+ VkShaderModuleIdentifierEXT * pIdentifier ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetShaderModuleCreateInfoIdentifierEXT( device, pCreateInfo, pIdentifier );
+ }
+
+ //=== VK_NV_optical_flow ===
+
+ VkResult vkGetPhysicalDeviceOpticalFlowImageFormatsNV( VkPhysicalDevice physicalDevice,
+ const VkOpticalFlowImageFormatInfoNV * pOpticalFlowImageFormatInfo,
+ uint32_t * pFormatCount,
+ VkOpticalFlowImageFormatPropertiesNV * pImageFormatProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetPhysicalDeviceOpticalFlowImageFormatsNV( physicalDevice, pOpticalFlowImageFormatInfo, pFormatCount, pImageFormatProperties );
+ }
+
+ VkResult vkCreateOpticalFlowSessionNV( VkDevice device,
+ const VkOpticalFlowSessionCreateInfoNV * pCreateInfo,
+ const VkAllocationCallbacks * pAllocator,
+ VkOpticalFlowSessionNV * pSession ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCreateOpticalFlowSessionNV( device, pCreateInfo, pAllocator, pSession );
+ }
+
+ void vkDestroyOpticalFlowSessionNV( VkDevice device, VkOpticalFlowSessionNV session, const VkAllocationCallbacks * pAllocator ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkDestroyOpticalFlowSessionNV( device, session, pAllocator );
+ }
+
+ VkResult vkBindOpticalFlowSessionImageNV( VkDevice device,
+ VkOpticalFlowSessionNV session,
+ VkOpticalFlowSessionBindingPointNV bindingPoint,
+ VkImageView view,
+ VkImageLayout layout ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkBindOpticalFlowSessionImageNV( device, session, bindingPoint, view, layout );
+ }
+
+ void vkCmdOpticalFlowExecuteNV( VkCommandBuffer commandBuffer,
+ VkOpticalFlowSessionNV session,
+ const VkOpticalFlowExecuteInfoNV * pExecuteInfo ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkCmdOpticalFlowExecuteNV( commandBuffer, session, pExecuteInfo );
+ }
+
+ //=== VK_QCOM_tile_properties ===
+
+ VkResult vkGetFramebufferTilePropertiesQCOM( VkDevice device,
+ VkFramebuffer framebuffer,
+ uint32_t * pPropertiesCount,
+ VkTilePropertiesQCOM * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetFramebufferTilePropertiesQCOM( device, framebuffer, pPropertiesCount, pProperties );
+ }
+
+ VkResult vkGetDynamicRenderingTilePropertiesQCOM( VkDevice device,
+ const VkRenderingInfo * pRenderingInfo,
+ VkTilePropertiesQCOM * pProperties ) const VULKAN_HPP_NOEXCEPT
+ {
+ return ::vkGetDynamicRenderingTilePropertiesQCOM( device, pRenderingInfo, pProperties );
+ }
+ };
+#endif
+
+ class DispatchLoaderDynamic;
+#if !defined( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC )
+# if defined( VK_NO_PROTOTYPES )
+# define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
+# else
+# define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 0
+# endif
+#endif
+
+#if !defined( VULKAN_HPP_STORAGE_API )
+# if defined( VULKAN_HPP_STORAGE_SHARED )
+# if defined( _MSC_VER )
+# if defined( VULKAN_HPP_STORAGE_SHARED_EXPORT )
+# define VULKAN_HPP_STORAGE_API __declspec( dllexport )
+# else
+# define VULKAN_HPP_STORAGE_API __declspec( dllimport )
+# endif
+# elif defined( __clang__ ) || defined( __GNUC__ )
+# if defined( VULKAN_HPP_STORAGE_SHARED_EXPORT )
+# define VULKAN_HPP_STORAGE_API __attribute__( ( visibility( "default" ) ) )
+# else
+# define VULKAN_HPP_STORAGE_API
+# endif
+# else
+# define VULKAN_HPP_STORAGE_API
+# pragma warning Unknown import / export semantics
+# endif
+# else
+# define VULKAN_HPP_STORAGE_API
+# endif
+#endif
+
+#if !defined( VULKAN_HPP_DEFAULT_DISPATCHER )
+# if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1
+# define VULKAN_HPP_DEFAULT_DISPATCHER ::VULKAN_HPP_NAMESPACE::defaultDispatchLoaderDynamic
+# define VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE \
+ namespace VULKAN_HPP_NAMESPACE \
+ { \
+ VULKAN_HPP_STORAGE_API DispatchLoaderDynamic defaultDispatchLoaderDynamic; \
+ }
+ extern VULKAN_HPP_STORAGE_API DispatchLoaderDynamic defaultDispatchLoaderDynamic;
+# else
+ static inline ::VULKAN_HPP_NAMESPACE::DispatchLoaderStatic & getDispatchLoaderStatic()
+ {
+ static ::VULKAN_HPP_NAMESPACE::DispatchLoaderStatic dls;
+ return dls;
+ }
+# define VULKAN_HPP_DEFAULT_DISPATCHER ::VULKAN_HPP_NAMESPACE::getDispatchLoaderStatic()
+# define VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
+# endif
+#endif
+
+#if !defined( VULKAN_HPP_DEFAULT_DISPATCHER_TYPE )
+# if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1
+# define VULKAN_HPP_DEFAULT_DISPATCHER_TYPE ::VULKAN_HPP_NAMESPACE::DispatchLoaderDynamic
+# else
+# define VULKAN_HPP_DEFAULT_DISPATCHER_TYPE ::VULKAN_HPP_NAMESPACE::DispatchLoaderStatic
+# endif
+#endif
+
+#if defined( VULKAN_HPP_NO_DEFAULT_DISPATCHER )
+# define VULKAN_HPP_DEFAULT_ARGUMENT_ASSIGNMENT
+# define VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT
+# define VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT
+#else
+# define VULKAN_HPP_DEFAULT_ARGUMENT_ASSIGNMENT = {}
+# define VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT = nullptr
+# define VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT = VULKAN_HPP_DEFAULT_DISPATCHER
+#endif
+
+#if !defined( VULKAN_HPP_NO_SMART_HANDLE )
+ struct AllocationCallbacks;
+
+ template <typename OwnerType, typename Dispatch>
+ class ObjectDestroy
+ {
+ public:
+ ObjectDestroy() = default;
+
+ ObjectDestroy( OwnerType owner,
+ Optional<const AllocationCallbacks> allocationCallbacks VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT,
+ Dispatch const & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) VULKAN_HPP_NOEXCEPT
+ : m_owner( owner )
+ , m_allocationCallbacks( allocationCallbacks )
+ , m_dispatch( &dispatch )
+ {
+ }
+
+ OwnerType getOwner() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_owner;
+ }
+ Optional<const AllocationCallbacks> getAllocator() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_allocationCallbacks;
+ }
+
+ protected:
+ template <typename T>
+ void destroy( T t ) VULKAN_HPP_NOEXCEPT
+ {
+ VULKAN_HPP_ASSERT( m_owner && m_dispatch );
+ m_owner.destroy( t, m_allocationCallbacks, *m_dispatch );
+ }
+
+ private:
+ OwnerType m_owner = {};
+ Optional<const AllocationCallbacks> m_allocationCallbacks = nullptr;
+ Dispatch const * m_dispatch = nullptr;
+ };
+
+ class NoParent;
+
+ template <typename Dispatch>
+ class ObjectDestroy<NoParent, Dispatch>
+ {
+ public:
+ ObjectDestroy() = default;
+
+ ObjectDestroy( Optional<const AllocationCallbacks> allocationCallbacks,
+ Dispatch const & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) VULKAN_HPP_NOEXCEPT
+ : m_allocationCallbacks( allocationCallbacks )
+ , m_dispatch( &dispatch )
+ {
+ }
+
+ Optional<const AllocationCallbacks> getAllocator() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_allocationCallbacks;
+ }
+
+ protected:
+ template <typename T>
+ void destroy( T t ) VULKAN_HPP_NOEXCEPT
+ {
+ VULKAN_HPP_ASSERT( m_dispatch );
+ t.destroy( m_allocationCallbacks, *m_dispatch );
+ }
+
+ private:
+ Optional<const AllocationCallbacks> m_allocationCallbacks = nullptr;
+ Dispatch const * m_dispatch = nullptr;
+ };
+
+ template <typename OwnerType, typename Dispatch>
+ class ObjectFree
+ {
+ public:
+ ObjectFree() = default;
+
+ ObjectFree( OwnerType owner,
+ Optional<const AllocationCallbacks> allocationCallbacks VULKAN_HPP_DEFAULT_ARGUMENT_NULLPTR_ASSIGNMENT,
+ Dispatch const & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) VULKAN_HPP_NOEXCEPT
+ : m_owner( owner )
+ , m_allocationCallbacks( allocationCallbacks )
+ , m_dispatch( &dispatch )
+ {
+ }
+
+ OwnerType getOwner() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_owner;
+ }
+
+ Optional<const AllocationCallbacks> getAllocator() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_allocationCallbacks;
+ }
+
+ protected:
+ template <typename T>
+ void destroy( T t ) VULKAN_HPP_NOEXCEPT
+ {
+ VULKAN_HPP_ASSERT( m_owner && m_dispatch );
+ ( m_owner.free )( t, m_allocationCallbacks, *m_dispatch );
+ }
+
+ private:
+ OwnerType m_owner = {};
+ Optional<const AllocationCallbacks> m_allocationCallbacks = nullptr;
+ Dispatch const * m_dispatch = nullptr;
+ };
+
+ template <typename OwnerType, typename Dispatch>
+ class ObjectRelease
+ {
+ public:
+ ObjectRelease() = default;
+
+ ObjectRelease( OwnerType owner, Dispatch const & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) VULKAN_HPP_NOEXCEPT
+ : m_owner( owner )
+ , m_dispatch( &dispatch )
+ {
+ }
+
+ OwnerType getOwner() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_owner;
+ }
+
+ protected:
+ template <typename T>
+ void destroy( T t ) VULKAN_HPP_NOEXCEPT
+ {
+ VULKAN_HPP_ASSERT( m_owner && m_dispatch );
+ m_owner.release( t, *m_dispatch );
+ }
+
+ private:
+ OwnerType m_owner = {};
+ Dispatch const * m_dispatch = nullptr;
+ };
+
+ template <typename OwnerType, typename PoolType, typename Dispatch>
+ class PoolFree
+ {
+ public:
+ PoolFree() = default;
+
+ PoolFree( OwnerType owner, PoolType pool, Dispatch const & dispatch VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) VULKAN_HPP_NOEXCEPT
+ : m_owner( owner )
+ , m_pool( pool )
+ , m_dispatch( &dispatch )
+ {
+ }
+
+ OwnerType getOwner() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_owner;
+ }
+ PoolType getPool() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_pool;
+ }
+
+ protected:
+ template <typename T>
+ void destroy( T t ) VULKAN_HPP_NOEXCEPT
+ {
+ ( m_owner.free )( m_pool, t, *m_dispatch );
+ }
+
+ private:
+ OwnerType m_owner = OwnerType();
+ PoolType m_pool = PoolType();
+ Dispatch const * m_dispatch = nullptr;
+ };
+
+#endif // !VULKAN_HPP_NO_SMART_HANDLE
+
+ //==================
+ //=== BASE TYPEs ===
+ //==================
+
+ using Bool32 = uint32_t;
+ using DeviceAddress = uint64_t;
+ using DeviceSize = uint64_t;
+ using RemoteAddressNV = void *;
+ using SampleMask = uint32_t;
+
+} // namespace VULKAN_HPP_NAMESPACE
+
+#include <vulkan/vulkan_enums.hpp>
+#if !defined( VULKAN_HPP_NO_TO_STRING )
+# include <vulkan/vulkan_to_string.hpp>
+#endif
+
+#ifndef VULKAN_HPP_NO_EXCEPTIONS
+namespace std
+{
+ template <>
+ struct is_error_code_enum<VULKAN_HPP_NAMESPACE::Result> : public true_type
+ {
+ };
+} // namespace std
+#endif
+
+namespace VULKAN_HPP_NAMESPACE
+{
+#ifndef VULKAN_HPP_NO_EXCEPTIONS
+ class ErrorCategoryImpl : public std::error_category
+ {
+ public:
+ virtual const char * name() const VULKAN_HPP_NOEXCEPT override
+ {
+ return VULKAN_HPP_NAMESPACE_STRING "::Result";
+ }
+ virtual std::string message( int ev ) const override
+ {
+# if defined( VULKAN_HPP_NO_TO_STRING )
+ return std::to_string( ev );
+# else
+ return VULKAN_HPP_NAMESPACE::to_string( static_cast<VULKAN_HPP_NAMESPACE::Result>( ev ) );
+# endif
+ }
+ };
+
+ class Error
+ {
+ public:
+ Error() VULKAN_HPP_NOEXCEPT = default;
+ Error( const Error & ) VULKAN_HPP_NOEXCEPT = default;
+ virtual ~Error() VULKAN_HPP_NOEXCEPT = default;
+
+ virtual const char * what() const VULKAN_HPP_NOEXCEPT = 0;
+ };
+
+ class LogicError
+ : public Error
+ , public std::logic_error
+ {
+ public:
+ explicit LogicError( const std::string & what ) : Error(), std::logic_error( what ) {}
+ explicit LogicError( char const * what ) : Error(), std::logic_error( what ) {}
+
+ virtual const char * what() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::logic_error::what();
+ }
+ };
+
+ class SystemError
+ : public Error
+ , public std::system_error
+ {
+ public:
+ SystemError( std::error_code ec ) : Error(), std::system_error( ec ) {}
+ SystemError( std::error_code ec, std::string const & what ) : Error(), std::system_error( ec, what ) {}
+ SystemError( std::error_code ec, char const * what ) : Error(), std::system_error( ec, what ) {}
+ SystemError( int ev, std::error_category const & ecat ) : Error(), std::system_error( ev, ecat ) {}
+ SystemError( int ev, std::error_category const & ecat, std::string const & what ) : Error(), std::system_error( ev, ecat, what ) {}
+ SystemError( int ev, std::error_category const & ecat, char const * what ) : Error(), std::system_error( ev, ecat, what ) {}
+
+ virtual const char * what() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::system_error::what();
+ }
+ };
+
+ VULKAN_HPP_INLINE const std::error_category & errorCategory() VULKAN_HPP_NOEXCEPT
+ {
+ static ErrorCategoryImpl instance;
+ return instance;
+ }
+
+ VULKAN_HPP_INLINE std::error_code make_error_code( Result e ) VULKAN_HPP_NOEXCEPT
+ {
+ return std::error_code( static_cast<int>( e ), errorCategory() );
+ }
+
+ VULKAN_HPP_INLINE std::error_condition make_error_condition( Result e ) VULKAN_HPP_NOEXCEPT
+ {
+ return std::error_condition( static_cast<int>( e ), errorCategory() );
+ }
+
+ class OutOfHostMemoryError : public SystemError
+ {
+ public:
+ OutOfHostMemoryError( std::string const & message ) : SystemError( make_error_code( Result::eErrorOutOfHostMemory ), message ) {}
+ OutOfHostMemoryError( char const * message ) : SystemError( make_error_code( Result::eErrorOutOfHostMemory ), message ) {}
+ };
+
+ class OutOfDeviceMemoryError : public SystemError
+ {
+ public:
+ OutOfDeviceMemoryError( std::string const & message ) : SystemError( make_error_code( Result::eErrorOutOfDeviceMemory ), message ) {}
+ OutOfDeviceMemoryError( char const * message ) : SystemError( make_error_code( Result::eErrorOutOfDeviceMemory ), message ) {}
+ };
+
+ class InitializationFailedError : public SystemError
+ {
+ public:
+ InitializationFailedError( std::string const & message ) : SystemError( make_error_code( Result::eErrorInitializationFailed ), message ) {}
+ InitializationFailedError( char const * message ) : SystemError( make_error_code( Result::eErrorInitializationFailed ), message ) {}
+ };
+
+ class DeviceLostError : public SystemError
+ {
+ public:
+ DeviceLostError( std::string const & message ) : SystemError( make_error_code( Result::eErrorDeviceLost ), message ) {}
+ DeviceLostError( char const * message ) : SystemError( make_error_code( Result::eErrorDeviceLost ), message ) {}
+ };
+
+ class MemoryMapFailedError : public SystemError
+ {
+ public:
+ MemoryMapFailedError( std::string const & message ) : SystemError( make_error_code( Result::eErrorMemoryMapFailed ), message ) {}
+ MemoryMapFailedError( char const * message ) : SystemError( make_error_code( Result::eErrorMemoryMapFailed ), message ) {}
+ };
+
+ class LayerNotPresentError : public SystemError
+ {
+ public:
+ LayerNotPresentError( std::string const & message ) : SystemError( make_error_code( Result::eErrorLayerNotPresent ), message ) {}
+ LayerNotPresentError( char const * message ) : SystemError( make_error_code( Result::eErrorLayerNotPresent ), message ) {}
+ };
+
+ class ExtensionNotPresentError : public SystemError
+ {
+ public:
+ ExtensionNotPresentError( std::string const & message ) : SystemError( make_error_code( Result::eErrorExtensionNotPresent ), message ) {}
+ ExtensionNotPresentError( char const * message ) : SystemError( make_error_code( Result::eErrorExtensionNotPresent ), message ) {}
+ };
+
+ class FeatureNotPresentError : public SystemError
+ {
+ public:
+ FeatureNotPresentError( std::string const & message ) : SystemError( make_error_code( Result::eErrorFeatureNotPresent ), message ) {}
+ FeatureNotPresentError( char const * message ) : SystemError( make_error_code( Result::eErrorFeatureNotPresent ), message ) {}
+ };
+
+ class IncompatibleDriverError : public SystemError
+ {
+ public:
+ IncompatibleDriverError( std::string const & message ) : SystemError( make_error_code( Result::eErrorIncompatibleDriver ), message ) {}
+ IncompatibleDriverError( char const * message ) : SystemError( make_error_code( Result::eErrorIncompatibleDriver ), message ) {}
+ };
+
+ class TooManyObjectsError : public SystemError
+ {
+ public:
+ TooManyObjectsError( std::string const & message ) : SystemError( make_error_code( Result::eErrorTooManyObjects ), message ) {}
+ TooManyObjectsError( char const * message ) : SystemError( make_error_code( Result::eErrorTooManyObjects ), message ) {}
+ };
+
+ class FormatNotSupportedError : public SystemError
+ {
+ public:
+ FormatNotSupportedError( std::string const & message ) : SystemError( make_error_code( Result::eErrorFormatNotSupported ), message ) {}
+ FormatNotSupportedError( char const * message ) : SystemError( make_error_code( Result::eErrorFormatNotSupported ), message ) {}
+ };
+
+ class FragmentedPoolError : public SystemError
+ {
+ public:
+ FragmentedPoolError( std::string const & message ) : SystemError( make_error_code( Result::eErrorFragmentedPool ), message ) {}
+ FragmentedPoolError( char const * message ) : SystemError( make_error_code( Result::eErrorFragmentedPool ), message ) {}
+ };
+
+ class UnknownError : public SystemError
+ {
+ public:
+ UnknownError( std::string const & message ) : SystemError( make_error_code( Result::eErrorUnknown ), message ) {}
+ UnknownError( char const * message ) : SystemError( make_error_code( Result::eErrorUnknown ), message ) {}
+ };
+
+ class OutOfPoolMemoryError : public SystemError
+ {
+ public:
+ OutOfPoolMemoryError( std::string const & message ) : SystemError( make_error_code( Result::eErrorOutOfPoolMemory ), message ) {}
+ OutOfPoolMemoryError( char const * message ) : SystemError( make_error_code( Result::eErrorOutOfPoolMemory ), message ) {}
+ };
+
+ class InvalidExternalHandleError : public SystemError
+ {
+ public:
+ InvalidExternalHandleError( std::string const & message ) : SystemError( make_error_code( Result::eErrorInvalidExternalHandle ), message ) {}
+ InvalidExternalHandleError( char const * message ) : SystemError( make_error_code( Result::eErrorInvalidExternalHandle ), message ) {}
+ };
+
+ class FragmentationError : public SystemError
+ {
+ public:
+ FragmentationError( std::string const & message ) : SystemError( make_error_code( Result::eErrorFragmentation ), message ) {}
+ FragmentationError( char const * message ) : SystemError( make_error_code( Result::eErrorFragmentation ), message ) {}
+ };
+
+ class InvalidOpaqueCaptureAddressError : public SystemError
+ {
+ public:
+ InvalidOpaqueCaptureAddressError( std::string const & message ) : SystemError( make_error_code( Result::eErrorInvalidOpaqueCaptureAddress ), message ) {}
+ InvalidOpaqueCaptureAddressError( char const * message ) : SystemError( make_error_code( Result::eErrorInvalidOpaqueCaptureAddress ), message ) {}
+ };
+
+ class SurfaceLostKHRError : public SystemError
+ {
+ public:
+ SurfaceLostKHRError( std::string const & message ) : SystemError( make_error_code( Result::eErrorSurfaceLostKHR ), message ) {}
+ SurfaceLostKHRError( char const * message ) : SystemError( make_error_code( Result::eErrorSurfaceLostKHR ), message ) {}
+ };
+
+ class NativeWindowInUseKHRError : public SystemError
+ {
+ public:
+ NativeWindowInUseKHRError( std::string const & message ) : SystemError( make_error_code( Result::eErrorNativeWindowInUseKHR ), message ) {}
+ NativeWindowInUseKHRError( char const * message ) : SystemError( make_error_code( Result::eErrorNativeWindowInUseKHR ), message ) {}
+ };
+
+ class OutOfDateKHRError : public SystemError
+ {
+ public:
+ OutOfDateKHRError( std::string const & message ) : SystemError( make_error_code( Result::eErrorOutOfDateKHR ), message ) {}
+ OutOfDateKHRError( char const * message ) : SystemError( make_error_code( Result::eErrorOutOfDateKHR ), message ) {}
+ };
+
+ class IncompatibleDisplayKHRError : public SystemError
+ {
+ public:
+ IncompatibleDisplayKHRError( std::string const & message ) : SystemError( make_error_code( Result::eErrorIncompatibleDisplayKHR ), message ) {}
+ IncompatibleDisplayKHRError( char const * message ) : SystemError( make_error_code( Result::eErrorIncompatibleDisplayKHR ), message ) {}
+ };
+
+ class ValidationFailedEXTError : public SystemError
+ {
+ public:
+ ValidationFailedEXTError( std::string const & message ) : SystemError( make_error_code( Result::eErrorValidationFailedEXT ), message ) {}
+ ValidationFailedEXTError( char const * message ) : SystemError( make_error_code( Result::eErrorValidationFailedEXT ), message ) {}
+ };
+
+ class InvalidShaderNVError : public SystemError
+ {
+ public:
+ InvalidShaderNVError( std::string const & message ) : SystemError( make_error_code( Result::eErrorInvalidShaderNV ), message ) {}
+ InvalidShaderNVError( char const * message ) : SystemError( make_error_code( Result::eErrorInvalidShaderNV ), message ) {}
+ };
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ class ImageUsageNotSupportedKHRError : public SystemError
+ {
+ public:
+ ImageUsageNotSupportedKHRError( std::string const & message ) : SystemError( make_error_code( Result::eErrorImageUsageNotSupportedKHR ), message ) {}
+ ImageUsageNotSupportedKHRError( char const * message ) : SystemError( make_error_code( Result::eErrorImageUsageNotSupportedKHR ), message ) {}
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ class VideoPictureLayoutNotSupportedKHRError : public SystemError
+ {
+ public:
+ VideoPictureLayoutNotSupportedKHRError( std::string const & message )
+ : SystemError( make_error_code( Result::eErrorVideoPictureLayoutNotSupportedKHR ), message )
+ {
+ }
+ VideoPictureLayoutNotSupportedKHRError( char const * message ) : SystemError( make_error_code( Result::eErrorVideoPictureLayoutNotSupportedKHR ), message )
+ {
+ }
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ class VideoProfileOperationNotSupportedKHRError : public SystemError
+ {
+ public:
+ VideoProfileOperationNotSupportedKHRError( std::string const & message )
+ : SystemError( make_error_code( Result::eErrorVideoProfileOperationNotSupportedKHR ), message )
+ {
+ }
+ VideoProfileOperationNotSupportedKHRError( char const * message )
+ : SystemError( make_error_code( Result::eErrorVideoProfileOperationNotSupportedKHR ), message )
+ {
+ }
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ class VideoProfileFormatNotSupportedKHRError : public SystemError
+ {
+ public:
+ VideoProfileFormatNotSupportedKHRError( std::string const & message )
+ : SystemError( make_error_code( Result::eErrorVideoProfileFormatNotSupportedKHR ), message )
+ {
+ }
+ VideoProfileFormatNotSupportedKHRError( char const * message ) : SystemError( make_error_code( Result::eErrorVideoProfileFormatNotSupportedKHR ), message )
+ {
+ }
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ class VideoProfileCodecNotSupportedKHRError : public SystemError
+ {
+ public:
+ VideoProfileCodecNotSupportedKHRError( std::string const & message )
+ : SystemError( make_error_code( Result::eErrorVideoProfileCodecNotSupportedKHR ), message )
+ {
+ }
+ VideoProfileCodecNotSupportedKHRError( char const * message ) : SystemError( make_error_code( Result::eErrorVideoProfileCodecNotSupportedKHR ), message ) {}
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ class VideoStdVersionNotSupportedKHRError : public SystemError
+ {
+ public:
+ VideoStdVersionNotSupportedKHRError( std::string const & message ) : SystemError( make_error_code( Result::eErrorVideoStdVersionNotSupportedKHR ), message )
+ {
+ }
+ VideoStdVersionNotSupportedKHRError( char const * message ) : SystemError( make_error_code( Result::eErrorVideoStdVersionNotSupportedKHR ), message ) {}
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+ class InvalidDrmFormatModifierPlaneLayoutEXTError : public SystemError
+ {
+ public:
+ InvalidDrmFormatModifierPlaneLayoutEXTError( std::string const & message )
+ : SystemError( make_error_code( Result::eErrorInvalidDrmFormatModifierPlaneLayoutEXT ), message )
+ {
+ }
+ InvalidDrmFormatModifierPlaneLayoutEXTError( char const * message )
+ : SystemError( make_error_code( Result::eErrorInvalidDrmFormatModifierPlaneLayoutEXT ), message )
+ {
+ }
+ };
+
+ class NotPermittedKHRError : public SystemError
+ {
+ public:
+ NotPermittedKHRError( std::string const & message ) : SystemError( make_error_code( Result::eErrorNotPermittedKHR ), message ) {}
+ NotPermittedKHRError( char const * message ) : SystemError( make_error_code( Result::eErrorNotPermittedKHR ), message ) {}
+ };
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ class FullScreenExclusiveModeLostEXTError : public SystemError
+ {
+ public:
+ FullScreenExclusiveModeLostEXTError( std::string const & message ) : SystemError( make_error_code( Result::eErrorFullScreenExclusiveModeLostEXT ), message )
+ {
+ }
+ FullScreenExclusiveModeLostEXTError( char const * message ) : SystemError( make_error_code( Result::eErrorFullScreenExclusiveModeLostEXT ), message ) {}
+ };
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ class CompressionExhaustedEXTError : public SystemError
+ {
+ public:
+ CompressionExhaustedEXTError( std::string const & message ) : SystemError( make_error_code( Result::eErrorCompressionExhaustedEXT ), message ) {}
+ CompressionExhaustedEXTError( char const * message ) : SystemError( make_error_code( Result::eErrorCompressionExhaustedEXT ), message ) {}
+ };
+
+ namespace
+ {
+ [[noreturn]] void throwResultException( Result result, char const * message )
+ {
+ switch ( result )
+ {
+ case Result::eErrorOutOfHostMemory: throw OutOfHostMemoryError( message );
+ case Result::eErrorOutOfDeviceMemory: throw OutOfDeviceMemoryError( message );
+ case Result::eErrorInitializationFailed: throw InitializationFailedError( message );
+ case Result::eErrorDeviceLost: throw DeviceLostError( message );
+ case Result::eErrorMemoryMapFailed: throw MemoryMapFailedError( message );
+ case Result::eErrorLayerNotPresent: throw LayerNotPresentError( message );
+ case Result::eErrorExtensionNotPresent: throw ExtensionNotPresentError( message );
+ case Result::eErrorFeatureNotPresent: throw FeatureNotPresentError( message );
+ case Result::eErrorIncompatibleDriver: throw IncompatibleDriverError( message );
+ case Result::eErrorTooManyObjects: throw TooManyObjectsError( message );
+ case Result::eErrorFormatNotSupported: throw FormatNotSupportedError( message );
+ case Result::eErrorFragmentedPool: throw FragmentedPoolError( message );
+ case Result::eErrorUnknown: throw UnknownError( message );
+ case Result::eErrorOutOfPoolMemory: throw OutOfPoolMemoryError( message );
+ case Result::eErrorInvalidExternalHandle: throw InvalidExternalHandleError( message );
+ case Result::eErrorFragmentation: throw FragmentationError( message );
+ case Result::eErrorInvalidOpaqueCaptureAddress: throw InvalidOpaqueCaptureAddressError( message );
+ case Result::eErrorSurfaceLostKHR: throw SurfaceLostKHRError( message );
+ case Result::eErrorNativeWindowInUseKHR: throw NativeWindowInUseKHRError( message );
+ case Result::eErrorOutOfDateKHR: throw OutOfDateKHRError( message );
+ case Result::eErrorIncompatibleDisplayKHR: throw IncompatibleDisplayKHRError( message );
+ case Result::eErrorValidationFailedEXT: throw ValidationFailedEXTError( message );
+ case Result::eErrorInvalidShaderNV: throw InvalidShaderNVError( message );
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ case Result::eErrorImageUsageNotSupportedKHR: throw ImageUsageNotSupportedKHRError( message );
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ case Result::eErrorVideoPictureLayoutNotSupportedKHR: throw VideoPictureLayoutNotSupportedKHRError( message );
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ case Result::eErrorVideoProfileOperationNotSupportedKHR: throw VideoProfileOperationNotSupportedKHRError( message );
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ case Result::eErrorVideoProfileFormatNotSupportedKHR: throw VideoProfileFormatNotSupportedKHRError( message );
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ case Result::eErrorVideoProfileCodecNotSupportedKHR: throw VideoProfileCodecNotSupportedKHRError( message );
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ case Result::eErrorVideoStdVersionNotSupportedKHR: throw VideoStdVersionNotSupportedKHRError( message );
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+ case Result::eErrorInvalidDrmFormatModifierPlaneLayoutEXT: throw InvalidDrmFormatModifierPlaneLayoutEXTError( message );
+ case Result::eErrorNotPermittedKHR: throw NotPermittedKHRError( message );
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ case Result::eErrorFullScreenExclusiveModeLostEXT: throw FullScreenExclusiveModeLostEXTError( message );
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+ case Result::eErrorCompressionExhaustedEXT: throw CompressionExhaustedEXTError( message );
+ default: throw SystemError( make_error_code( result ) );
+ }
+ }
+ } // namespace
+#endif
+
+ template <typename T>
+ void ignore( T const & ) VULKAN_HPP_NOEXCEPT
+ {
+ }
+
+ template <typename T>
+ struct ResultValue
+ {
+#ifdef VULKAN_HPP_HAS_NOEXCEPT
+ ResultValue( Result r, T & v ) VULKAN_HPP_NOEXCEPT( VULKAN_HPP_NOEXCEPT( T( v ) ) )
+#else
+ ResultValue( Result r, T & v )
+#endif
+ : result( r ), value( v )
+ {
+ }
+
+#ifdef VULKAN_HPP_HAS_NOEXCEPT
+ ResultValue( Result r, T && v ) VULKAN_HPP_NOEXCEPT( VULKAN_HPP_NOEXCEPT( T( std::move( v ) ) ) )
+#else
+ ResultValue( Result r, T && v )
+#endif
+ : result( r ), value( std::move( v ) )
+ {
+ }
+
+ Result result;
+ T value;
+
+ operator std::tuple<Result &, T &>() VULKAN_HPP_NOEXCEPT
+ {
+ return std::tuple<Result &, T &>( result, value );
+ }
+ };
+
+#if !defined( VULKAN_HPP_NO_SMART_HANDLE )
+ template <typename Type, typename Dispatch>
+ struct ResultValue<UniqueHandle<Type, Dispatch>>
+ {
+# ifdef VULKAN_HPP_HAS_NOEXCEPT
+ ResultValue( Result r, UniqueHandle<Type, Dispatch> && v ) VULKAN_HPP_NOEXCEPT
+# else
+ ResultValue( Result r, UniqueHandle<Type, Dispatch> && v )
+# endif
+ : result( r )
+ , value( std::move( v ) )
+ {
+ }
+
+ std::tuple<Result, UniqueHandle<Type, Dispatch>> asTuple()
+ {
+ return std::make_tuple( result, std::move( value ) );
+ }
+
+ Result result;
+ UniqueHandle<Type, Dispatch> value;
+ };
+
+ template <typename Type, typename Dispatch>
+ struct ResultValue<std::vector<UniqueHandle<Type, Dispatch>>>
+ {
+# ifdef VULKAN_HPP_HAS_NOEXCEPT
+ ResultValue( Result r, std::vector<UniqueHandle<Type, Dispatch>> && v ) VULKAN_HPP_NOEXCEPT
+# else
+ ResultValue( Result r, std::vector<UniqueHandle<Type, Dispatch>> && v )
+# endif
+ : result( r )
+ , value( std::move( v ) )
+ {
+ }
+
+ std::tuple<Result, std::vector<UniqueHandle<Type, Dispatch>>> asTuple()
+ {
+ return std::make_tuple( result, std::move( value ) );
+ }
+
+ Result result;
+ std::vector<UniqueHandle<Type, Dispatch>> value;
+ };
+#endif
+
+ template <typename T>
+ struct ResultValueType
+ {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+ typedef ResultValue<T> type;
+#else
+ typedef T type;
+#endif
+ };
+
+ template <>
+ struct ResultValueType<void>
+ {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+ typedef Result type;
+#else
+ typedef void type;
+#endif
+ };
+
+ VULKAN_HPP_INLINE typename ResultValueType<void>::type createResultValueType( Result result )
+ {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+ return result;
+#else
+ ignore( result );
+#endif
+ }
+
+ template <typename T>
+ VULKAN_HPP_INLINE typename ResultValueType<T>::type createResultValueType( Result result, T & data )
+ {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+ return ResultValue<T>( result, data );
+#else
+ ignore( result );
+ return data;
+#endif
+ }
+
+ template <typename T>
+ VULKAN_HPP_INLINE typename ResultValueType<T>::type createResultValueType( Result result, T && data )
+ {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+ return ResultValue<T>( result, std::move( data ) );
+#else
+ ignore( result );
+ return std::move( data );
+#endif
+ }
+
+ VULKAN_HPP_INLINE void resultCheck( Result result, char const * message )
+ {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+ ignore( result ); // just in case VULKAN_HPP_ASSERT_ON_RESULT is empty
+ ignore( message );
+ VULKAN_HPP_ASSERT_ON_RESULT( result == Result::eSuccess );
+#else
+ if ( result != Result::eSuccess )
+ {
+ throwResultException( result, message );
+ }
+#endif
+ }
+
+ VULKAN_HPP_INLINE void resultCheck( Result result, char const * message, std::initializer_list<Result> successCodes )
+ {
+#ifdef VULKAN_HPP_NO_EXCEPTIONS
+ ignore( result ); // just in case VULKAN_HPP_ASSERT_ON_RESULT is empty
+ ignore( message );
+ ignore( successCodes ); // just in case VULKAN_HPP_ASSERT_ON_RESULT is empty
+ VULKAN_HPP_ASSERT_ON_RESULT( std::find( successCodes.begin(), successCodes.end(), result ) != successCodes.end() );
+#else
+ if ( std::find( successCodes.begin(), successCodes.end(), result ) == successCodes.end() )
+ {
+ throwResultException( result, message );
+ }
+#endif
+ }
+} // namespace VULKAN_HPP_NAMESPACE
+
+// clang-format off
+#include <vulkan/vulkan_handles.hpp>
+#include <vulkan/vulkan_structs.hpp>
+#include <vulkan/vulkan_funcs.hpp>
+// clang-format on
+
+namespace VULKAN_HPP_NAMESPACE
+{
+#if !defined( VULKAN_HPP_DISABLE_ENHANCED_MODE )
+
+ //=======================
+ //=== STRUCTS EXTENDS ===
+ //=======================
+
+ //=== VK_VERSION_1_0 ===
+ template <>
+ struct StructExtends<ShaderModuleCreateInfo, PipelineShaderStageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_VERSION_1_1 ===
+ template <>
+ struct StructExtends<PhysicalDeviceSubgroupProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevice16BitStorageFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevice16BitStorageFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MemoryDedicatedRequirements, MemoryRequirements2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MemoryDedicatedAllocateInfo, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MemoryAllocateFlagsInfo, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DeviceGroupRenderPassBeginInfo, RenderPassBeginInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DeviceGroupRenderPassBeginInfo, RenderingInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DeviceGroupCommandBufferBeginInfo, CommandBufferBeginInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DeviceGroupSubmitInfo, SubmitInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DeviceGroupBindSparseInfo, BindSparseInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<BindBufferMemoryDeviceGroupInfo, BindBufferMemoryInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<BindImageMemoryDeviceGroupInfo, BindImageMemoryInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DeviceGroupDeviceCreateInfo, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFeatures2, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePointClippingProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<RenderPassInputAttachmentAspectCreateInfo, RenderPassCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageViewUsageCreateInfo, ImageViewCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineTessellationDomainOriginStateCreateInfo, PipelineTessellationStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<RenderPassMultiviewCreateInfo, RenderPassCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMultiviewFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMultiviewFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMultiviewProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVariablePointersFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVariablePointersFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceProtectedMemoryFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceProtectedMemoryFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceProtectedMemoryProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ProtectedSubmitInfo, SubmitInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SamplerYcbcrConversionInfo, SamplerCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SamplerYcbcrConversionInfo, ImageViewCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<BindImagePlaneMemoryInfo, BindImageMemoryInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImagePlaneMemoryRequirementsInfo, ImageMemoryRequirementsInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSamplerYcbcrConversionFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSamplerYcbcrConversionFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SamplerYcbcrConversionImageFormatProperties, ImageFormatProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceExternalImageFormatInfo, PhysicalDeviceImageFormatInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExternalImageFormatProperties, ImageFormatProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceIDProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExternalMemoryImageCreateInfo, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExternalMemoryBufferCreateInfo, BufferCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMemoryAllocateInfo, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportFenceCreateInfo, FenceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportSemaphoreCreateInfo, SemaphoreCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMaintenance3Properties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderDrawParametersFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderDrawParametersFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_VERSION_1_2 ===
+ template <>
+ struct StructExtends<PhysicalDeviceVulkan11Features, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVulkan11Features, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVulkan11Properties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVulkan12Features, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVulkan12Features, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVulkan12Properties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageFormatListCreateInfo, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageFormatListCreateInfo, SwapchainCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageFormatListCreateInfo, PhysicalDeviceImageFormatInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevice8BitStorageFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevice8BitStorageFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDriverProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderAtomicInt64Features, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderAtomicInt64Features, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderFloat16Int8Features, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderFloat16Int8Features, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFloatControlsProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DescriptorSetLayoutBindingFlagsCreateInfo, DescriptorSetLayoutCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDescriptorIndexingFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDescriptorIndexingFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDescriptorIndexingProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DescriptorSetVariableDescriptorCountAllocateInfo, DescriptorSetAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DescriptorSetVariableDescriptorCountLayoutSupport, DescriptorSetLayoutSupport>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SubpassDescriptionDepthStencilResolve, SubpassDescription2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDepthStencilResolveProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceScalarBlockLayoutFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceScalarBlockLayoutFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageStencilUsageCreateInfo, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageStencilUsageCreateInfo, PhysicalDeviceImageFormatInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SamplerReductionModeCreateInfo, SamplerCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSamplerFilterMinmaxProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVulkanMemoryModelFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVulkanMemoryModelFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImagelessFramebufferFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImagelessFramebufferFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<FramebufferAttachmentsCreateInfo, FramebufferCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<RenderPassAttachmentBeginInfo, RenderPassBeginInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceUniformBufferStandardLayoutFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceUniformBufferStandardLayoutFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderSubgroupExtendedTypesFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderSubgroupExtendedTypesFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSeparateDepthStencilLayoutsFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSeparateDepthStencilLayoutsFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<AttachmentReferenceStencilLayout, AttachmentReference2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<AttachmentDescriptionStencilLayout, AttachmentDescription2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceHostQueryResetFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceHostQueryResetFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceTimelineSemaphoreFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceTimelineSemaphoreFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceTimelineSemaphoreProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SemaphoreTypeCreateInfo, SemaphoreCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SemaphoreTypeCreateInfo, PhysicalDeviceExternalSemaphoreInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<TimelineSemaphoreSubmitInfo, SubmitInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<TimelineSemaphoreSubmitInfo, BindSparseInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceBufferDeviceAddressFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceBufferDeviceAddressFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<BufferOpaqueCaptureAddressCreateInfo, BufferCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MemoryOpaqueCaptureAddressAllocateInfo, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_VERSION_1_3 ===
+ template <>
+ struct StructExtends<PhysicalDeviceVulkan13Features, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVulkan13Features, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVulkan13Properties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineCreationFeedbackCreateInfo, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineCreationFeedbackCreateInfo, ComputePipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineCreationFeedbackCreateInfo, RayTracingPipelineCreateInfoNV>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineCreationFeedbackCreateInfo, RayTracingPipelineCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderTerminateInvocationFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderTerminateInvocationFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderDemoteToHelperInvocationFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderDemoteToHelperInvocationFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePrivateDataFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePrivateDataFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DevicePrivateDataCreateInfo, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePipelineCreationCacheControlFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePipelineCreationCacheControlFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MemoryBarrier2, SubpassDependency2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSynchronization2Features, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSynchronization2Features, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceZeroInitializeWorkgroupMemoryFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceZeroInitializeWorkgroupMemoryFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImageRobustnessFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImageRobustnessFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSubgroupSizeControlFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSubgroupSizeControlFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSubgroupSizeControlProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineShaderStageRequiredSubgroupSizeCreateInfo, PipelineShaderStageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceInlineUniformBlockFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceInlineUniformBlockFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceInlineUniformBlockProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<WriteDescriptorSetInlineUniformBlock, WriteDescriptorSet>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DescriptorPoolInlineUniformBlockCreateInfo, DescriptorPoolCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceTextureCompressionASTCHDRFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceTextureCompressionASTCHDRFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineRenderingCreateInfo, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDynamicRenderingFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDynamicRenderingFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<CommandBufferInheritanceRenderingInfo, CommandBufferInheritanceInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderIntegerDotProductFeatures, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderIntegerDotProductFeatures, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderIntegerDotProductProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceTexelBufferAlignmentProperties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<FormatProperties3, FormatProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMaintenance4Features, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMaintenance4Features, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMaintenance4Properties, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_swapchain ===
+ template <>
+ struct StructExtends<ImageSwapchainCreateInfoKHR, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<BindImageMemorySwapchainInfoKHR, BindImageMemoryInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DeviceGroupPresentInfoKHR, PresentInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DeviceGroupSwapchainCreateInfoKHR, SwapchainCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_display_swapchain ===
+ template <>
+ struct StructExtends<DisplayPresentInfoKHR, PresentInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_debug_report ===
+ template <>
+ struct StructExtends<DebugReportCallbackCreateInfoEXT, InstanceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_AMD_rasterization_order ===
+ template <>
+ struct StructExtends<PipelineRasterizationStateRasterizationOrderAMD, PipelineRasterizationStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_queue ===
+ template <>
+ struct StructExtends<QueueFamilyQueryResultStatusPropertiesKHR, QueueFamilyProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<QueueFamilyVideoPropertiesKHR, QueueFamilyProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoProfileInfoKHR, QueryPoolCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoProfileListInfoKHR, PhysicalDeviceImageFormatInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoProfileListInfoKHR, PhysicalDeviceVideoFormatInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoProfileListInfoKHR, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoProfileListInfoKHR, BufferCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_decode_queue ===
+ template <>
+ struct StructExtends<VideoDecodeCapabilitiesKHR, VideoCapabilitiesKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeUsageInfoKHR, VideoProfileInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeUsageInfoKHR, QueryPoolCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+ //=== VK_NV_dedicated_allocation ===
+ template <>
+ struct StructExtends<DedicatedAllocationImageCreateInfoNV, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DedicatedAllocationBufferCreateInfoNV, BufferCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DedicatedAllocationMemoryAllocateInfoNV, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_transform_feedback ===
+ template <>
+ struct StructExtends<PhysicalDeviceTransformFeedbackFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceTransformFeedbackFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceTransformFeedbackPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineRasterizationStateStreamCreateInfoEXT, PipelineRasterizationStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_EXT_video_encode_h264 ===
+ template <>
+ struct StructExtends<VideoEncodeH264CapabilitiesEXT, VideoCapabilitiesKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH264SessionParametersCreateInfoEXT, VideoSessionParametersCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH264SessionParametersAddInfoEXT, VideoSessionParametersUpdateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH264VclFrameInfoEXT, VideoEncodeInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH264EmitPictureParametersInfoEXT, VideoEncodeInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH264ProfileInfoEXT, VideoProfileInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH264ProfileInfoEXT, QueryPoolCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH264RateControlInfoEXT, VideoCodingControlInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH264RateControlLayerInfoEXT, VideoCodingControlInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH264RateControlLayerInfoEXT, VideoEncodeRateControlLayerInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_EXT_video_encode_h265 ===
+ template <>
+ struct StructExtends<VideoEncodeH265CapabilitiesEXT, VideoCapabilitiesKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH265SessionParametersCreateInfoEXT, VideoSessionParametersCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH265SessionParametersAddInfoEXT, VideoSessionParametersUpdateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH265VclFrameInfoEXT, VideoEncodeInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH265EmitPictureParametersInfoEXT, VideoEncodeInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH265ProfileInfoEXT, VideoProfileInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH265ProfileInfoEXT, QueryPoolCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH265RateControlInfoEXT, VideoCodingControlInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH265RateControlLayerInfoEXT, VideoCodingControlInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeH265RateControlLayerInfoEXT, VideoEncodeRateControlLayerInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_EXT_video_decode_h264 ===
+ template <>
+ struct StructExtends<VideoDecodeH264ProfileInfoEXT, VideoProfileInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH264ProfileInfoEXT, QueryPoolCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH264CapabilitiesEXT, VideoCapabilitiesKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH264SessionParametersCreateInfoEXT, VideoSessionParametersCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH264SessionParametersAddInfoEXT, VideoSessionParametersUpdateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH264PictureInfoEXT, VideoDecodeInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH264DpbSlotInfoEXT, VideoReferenceSlotInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+ //=== VK_AMD_texture_gather_bias_lod ===
+ template <>
+ struct StructExtends<TextureLODGatherFormatPropertiesAMD, ImageFormatProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_dynamic_rendering ===
+ template <>
+ struct StructExtends<RenderingFragmentShadingRateAttachmentInfoKHR, RenderingInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<RenderingFragmentDensityMapAttachmentInfoEXT, RenderingInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<AttachmentSampleCountInfoAMD, CommandBufferInheritanceInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<AttachmentSampleCountInfoAMD, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MultiviewPerViewAttributesInfoNVX, CommandBufferInheritanceInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MultiviewPerViewAttributesInfoNVX, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MultiviewPerViewAttributesInfoNVX, RenderingInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_corner_sampled_image ===
+ template <>
+ struct StructExtends<PhysicalDeviceCornerSampledImageFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceCornerSampledImageFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_external_memory ===
+ template <>
+ struct StructExtends<ExternalMemoryImageCreateInfoNV, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMemoryAllocateInfoNV, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_NV_external_memory_win32 ===
+ template <>
+ struct StructExtends<ImportMemoryWin32HandleInfoNV, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMemoryWin32HandleInfoNV, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_NV_win32_keyed_mutex ===
+ template <>
+ struct StructExtends<Win32KeyedMutexAcquireReleaseInfoNV, SubmitInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<Win32KeyedMutexAcquireReleaseInfoNV, SubmitInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_EXT_validation_flags ===
+ template <>
+ struct StructExtends<ValidationFlagsEXT, InstanceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_astc_decode_mode ===
+ template <>
+ struct StructExtends<ImageViewASTCDecodeModeEXT, ImageViewCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceASTCDecodeFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceASTCDecodeFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_pipeline_robustness ===
+ template <>
+ struct StructExtends<PhysicalDevicePipelineRobustnessFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePipelineRobustnessFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePipelineRobustnessPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineRobustnessCreateInfoEXT, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineRobustnessCreateInfoEXT, ComputePipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineRobustnessCreateInfoEXT, PipelineShaderStageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineRobustnessCreateInfoEXT, RayTracingPipelineCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_memory_win32 ===
+ template <>
+ struct StructExtends<ImportMemoryWin32HandleInfoKHR, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMemoryWin32HandleInfoKHR, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_memory_fd ===
+ template <>
+ struct StructExtends<ImportMemoryFdInfoKHR, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_win32_keyed_mutex ===
+ template <>
+ struct StructExtends<Win32KeyedMutexAcquireReleaseInfoKHR, SubmitInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<Win32KeyedMutexAcquireReleaseInfoKHR, SubmitInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_semaphore_win32 ===
+ template <>
+ struct StructExtends<ExportSemaphoreWin32HandleInfoKHR, SemaphoreCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<D3D12FenceSubmitInfoKHR, SubmitInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_push_descriptor ===
+ template <>
+ struct StructExtends<PhysicalDevicePushDescriptorPropertiesKHR, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_conditional_rendering ===
+ template <>
+ struct StructExtends<PhysicalDeviceConditionalRenderingFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceConditionalRenderingFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<CommandBufferInheritanceConditionalRenderingInfoEXT, CommandBufferInheritanceInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_incremental_present ===
+ template <>
+ struct StructExtends<PresentRegionsKHR, PresentInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_clip_space_w_scaling ===
+ template <>
+ struct StructExtends<PipelineViewportWScalingStateCreateInfoNV, PipelineViewportStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_display_control ===
+ template <>
+ struct StructExtends<SwapchainCounterCreateInfoEXT, SwapchainCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_GOOGLE_display_timing ===
+ template <>
+ struct StructExtends<PresentTimesInfoGOOGLE, PresentInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NVX_multiview_per_view_attributes ===
+ template <>
+ struct StructExtends<PhysicalDeviceMultiviewPerViewAttributesPropertiesNVX, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_viewport_swizzle ===
+ template <>
+ struct StructExtends<PipelineViewportSwizzleStateCreateInfoNV, PipelineViewportStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_discard_rectangles ===
+ template <>
+ struct StructExtends<PhysicalDeviceDiscardRectanglePropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineDiscardRectangleStateCreateInfoEXT, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_conservative_rasterization ===
+ template <>
+ struct StructExtends<PhysicalDeviceConservativeRasterizationPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineRasterizationConservativeStateCreateInfoEXT, PipelineRasterizationStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_depth_clip_enable ===
+ template <>
+ struct StructExtends<PhysicalDeviceDepthClipEnableFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDepthClipEnableFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineRasterizationDepthClipStateCreateInfoEXT, PipelineRasterizationStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_shared_presentable_image ===
+ template <>
+ struct StructExtends<SharedPresentSurfaceCapabilitiesKHR, SurfaceCapabilities2KHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_fence_win32 ===
+ template <>
+ struct StructExtends<ExportFenceWin32HandleInfoKHR, FenceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_performance_query ===
+ template <>
+ struct StructExtends<PhysicalDevicePerformanceQueryFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePerformanceQueryFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePerformanceQueryPropertiesKHR, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<QueryPoolPerformanceCreateInfoKHR, QueryPoolCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PerformanceQuerySubmitInfoKHR, SubmitInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PerformanceQuerySubmitInfoKHR, SubmitInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_debug_utils ===
+ template <>
+ struct StructExtends<DebugUtilsMessengerCreateInfoEXT, InstanceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DebugUtilsObjectNameInfoEXT, PipelineShaderStageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_USE_PLATFORM_ANDROID_KHR )
+ //=== VK_ANDROID_external_memory_android_hardware_buffer ===
+ template <>
+ struct StructExtends<AndroidHardwareBufferUsageANDROID, ImageFormatProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<AndroidHardwareBufferFormatPropertiesANDROID, AndroidHardwareBufferPropertiesANDROID>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImportAndroidHardwareBufferInfoANDROID, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExternalFormatANDROID, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExternalFormatANDROID, SamplerYcbcrConversionCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<AndroidHardwareBufferFormatProperties2ANDROID, AndroidHardwareBufferPropertiesANDROID>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+ //=== VK_EXT_sample_locations ===
+ template <>
+ struct StructExtends<SampleLocationsInfoEXT, ImageMemoryBarrier>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SampleLocationsInfoEXT, ImageMemoryBarrier2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<RenderPassSampleLocationsBeginInfoEXT, RenderPassBeginInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineSampleLocationsStateCreateInfoEXT, PipelineMultisampleStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSampleLocationsPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_blend_operation_advanced ===
+ template <>
+ struct StructExtends<PhysicalDeviceBlendOperationAdvancedFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceBlendOperationAdvancedFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceBlendOperationAdvancedPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineColorBlendAdvancedStateCreateInfoEXT, PipelineColorBlendStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_fragment_coverage_to_color ===
+ template <>
+ struct StructExtends<PipelineCoverageToColorStateCreateInfoNV, PipelineMultisampleStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_acceleration_structure ===
+ template <>
+ struct StructExtends<WriteDescriptorSetAccelerationStructureKHR, WriteDescriptorSet>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceAccelerationStructureFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceAccelerationStructureFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceAccelerationStructurePropertiesKHR, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_framebuffer_mixed_samples ===
+ template <>
+ struct StructExtends<PipelineCoverageModulationStateCreateInfoNV, PipelineMultisampleStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_shader_sm_builtins ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderSMBuiltinsPropertiesNV, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderSMBuiltinsFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderSMBuiltinsFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_image_drm_format_modifier ===
+ template <>
+ struct StructExtends<DrmFormatModifierPropertiesListEXT, FormatProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImageDrmFormatModifierInfoEXT, PhysicalDeviceImageFormatInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageDrmFormatModifierListCreateInfoEXT, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageDrmFormatModifierExplicitCreateInfoEXT, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DrmFormatModifierPropertiesList2EXT, FormatProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_validation_cache ===
+ template <>
+ struct StructExtends<ShaderModuleValidationCacheCreateInfoEXT, ShaderModuleCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ShaderModuleValidationCacheCreateInfoEXT, PipelineShaderStageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_portability_subset ===
+ template <>
+ struct StructExtends<PhysicalDevicePortabilitySubsetFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePortabilitySubsetFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePortabilitySubsetPropertiesKHR, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+ //=== VK_NV_shading_rate_image ===
+ template <>
+ struct StructExtends<PipelineViewportShadingRateImageStateCreateInfoNV, PipelineViewportStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShadingRateImageFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShadingRateImageFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShadingRateImagePropertiesNV, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineViewportCoarseSampleOrderStateCreateInfoNV, PipelineViewportStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_ray_tracing ===
+ template <>
+ struct StructExtends<WriteDescriptorSetAccelerationStructureNV, WriteDescriptorSet>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRayTracingPropertiesNV, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_representative_fragment_test ===
+ template <>
+ struct StructExtends<PhysicalDeviceRepresentativeFragmentTestFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRepresentativeFragmentTestFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineRepresentativeFragmentTestStateCreateInfoNV, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_filter_cubic ===
+ template <>
+ struct StructExtends<PhysicalDeviceImageViewImageFormatInfoEXT, PhysicalDeviceImageFormatInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<FilterCubicImageViewImageFormatPropertiesEXT, ImageFormatProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_external_memory_host ===
+ template <>
+ struct StructExtends<ImportMemoryHostPointerInfoEXT, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceExternalMemoryHostPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_shader_clock ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderClockFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderClockFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_AMD_pipeline_compiler_control ===
+ template <>
+ struct StructExtends<PipelineCompilerControlCreateInfoAMD, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineCompilerControlCreateInfoAMD, ComputePipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_AMD_shader_core_properties ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderCorePropertiesAMD, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_EXT_video_decode_h265 ===
+ template <>
+ struct StructExtends<VideoDecodeH265ProfileInfoEXT, VideoProfileInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH265ProfileInfoEXT, QueryPoolCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH265CapabilitiesEXT, VideoCapabilitiesKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH265SessionParametersCreateInfoEXT, VideoSessionParametersCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH265SessionParametersAddInfoEXT, VideoSessionParametersUpdateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH265PictureInfoEXT, VideoDecodeInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoDecodeH265DpbSlotInfoEXT, VideoReferenceSlotInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+ //=== VK_KHR_global_priority ===
+ template <>
+ struct StructExtends<DeviceQueueGlobalPriorityCreateInfoKHR, DeviceQueueCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceGlobalPriorityQueryFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceGlobalPriorityQueryFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<QueueFamilyGlobalPriorityPropertiesKHR, QueueFamilyProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_AMD_memory_overallocation_behavior ===
+ template <>
+ struct StructExtends<DeviceMemoryOverallocationCreateInfoAMD, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_vertex_attribute_divisor ===
+ template <>
+ struct StructExtends<PhysicalDeviceVertexAttributeDivisorPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineVertexInputDivisorStateCreateInfoEXT, PipelineVertexInputStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVertexAttributeDivisorFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVertexAttributeDivisorFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_USE_PLATFORM_GGP )
+ //=== VK_GGP_frame_token ===
+ template <>
+ struct StructExtends<PresentFrameTokenGGP, PresentInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_GGP*/
+
+ //=== VK_NV_compute_shader_derivatives ===
+ template <>
+ struct StructExtends<PhysicalDeviceComputeShaderDerivativesFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceComputeShaderDerivativesFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_mesh_shader ===
+ template <>
+ struct StructExtends<PhysicalDeviceMeshShaderFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMeshShaderFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMeshShaderPropertiesNV, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_shader_image_footprint ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderImageFootprintFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderImageFootprintFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_scissor_exclusive ===
+ template <>
+ struct StructExtends<PipelineViewportExclusiveScissorStateCreateInfoNV, PipelineViewportStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceExclusiveScissorFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceExclusiveScissorFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_device_diagnostic_checkpoints ===
+ template <>
+ struct StructExtends<QueueFamilyCheckpointPropertiesNV, QueueFamilyProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_INTEL_shader_integer_functions2 ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderIntegerFunctions2FeaturesINTEL, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderIntegerFunctions2FeaturesINTEL, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_INTEL_performance_query ===
+ template <>
+ struct StructExtends<QueryPoolPerformanceQueryCreateInfoINTEL, QueryPoolCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_pci_bus_info ===
+ template <>
+ struct StructExtends<PhysicalDevicePCIBusInfoPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_AMD_display_native_hdr ===
+ template <>
+ struct StructExtends<DisplayNativeHdrSurfaceCapabilitiesAMD, SurfaceCapabilities2KHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SwapchainDisplayNativeHdrCreateInfoAMD, SwapchainCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_fragment_density_map ===
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentDensityMapFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentDensityMapFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentDensityMapPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<RenderPassFragmentDensityMapCreateInfoEXT, RenderPassCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<RenderPassFragmentDensityMapCreateInfoEXT, RenderPassCreateInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_fragment_shading_rate ===
+ template <>
+ struct StructExtends<FragmentShadingRateAttachmentInfoKHR, SubpassDescription2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineFragmentShadingRateStateCreateInfoKHR, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentShadingRateFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentShadingRateFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentShadingRatePropertiesKHR, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_AMD_shader_core_properties2 ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderCoreProperties2AMD, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_AMD_device_coherent_memory ===
+ template <>
+ struct StructExtends<PhysicalDeviceCoherentMemoryFeaturesAMD, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceCoherentMemoryFeaturesAMD, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_shader_image_atomic_int64 ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderImageAtomicInt64FeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderImageAtomicInt64FeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_memory_budget ===
+ template <>
+ struct StructExtends<PhysicalDeviceMemoryBudgetPropertiesEXT, PhysicalDeviceMemoryProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_memory_priority ===
+ template <>
+ struct StructExtends<PhysicalDeviceMemoryPriorityFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMemoryPriorityFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MemoryPriorityAllocateInfoEXT, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_surface_protected_capabilities ===
+ template <>
+ struct StructExtends<SurfaceProtectedCapabilitiesKHR, SurfaceCapabilities2KHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_dedicated_allocation_image_aliasing ===
+ template <>
+ struct StructExtends<PhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_buffer_device_address ===
+ template <>
+ struct StructExtends<PhysicalDeviceBufferDeviceAddressFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceBufferDeviceAddressFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<BufferDeviceAddressCreateInfoEXT, BufferCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_validation_features ===
+ template <>
+ struct StructExtends<ValidationFeaturesEXT, InstanceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_present_wait ===
+ template <>
+ struct StructExtends<PhysicalDevicePresentWaitFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePresentWaitFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_cooperative_matrix ===
+ template <>
+ struct StructExtends<PhysicalDeviceCooperativeMatrixFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceCooperativeMatrixFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceCooperativeMatrixPropertiesNV, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_coverage_reduction_mode ===
+ template <>
+ struct StructExtends<PhysicalDeviceCoverageReductionModeFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceCoverageReductionModeFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineCoverageReductionStateCreateInfoNV, PipelineMultisampleStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_fragment_shader_interlock ===
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentShaderInterlockFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentShaderInterlockFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_ycbcr_image_arrays ===
+ template <>
+ struct StructExtends<PhysicalDeviceYcbcrImageArraysFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceYcbcrImageArraysFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_provoking_vertex ===
+ template <>
+ struct StructExtends<PhysicalDeviceProvokingVertexFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceProvokingVertexFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceProvokingVertexPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineRasterizationProvokingVertexStateCreateInfoEXT, PipelineRasterizationStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_EXT_full_screen_exclusive ===
+ template <>
+ struct StructExtends<SurfaceFullScreenExclusiveInfoEXT, PhysicalDeviceSurfaceInfo2KHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SurfaceFullScreenExclusiveInfoEXT, SwapchainCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SurfaceCapabilitiesFullScreenExclusiveEXT, SurfaceCapabilities2KHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SurfaceFullScreenExclusiveWin32InfoEXT, PhysicalDeviceSurfaceInfo2KHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SurfaceFullScreenExclusiveWin32InfoEXT, SwapchainCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_EXT_line_rasterization ===
+ template <>
+ struct StructExtends<PhysicalDeviceLineRasterizationFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceLineRasterizationFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceLineRasterizationPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineRasterizationLineStateCreateInfoEXT, PipelineRasterizationStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_shader_atomic_float ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderAtomicFloatFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderAtomicFloatFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_index_type_uint8 ===
+ template <>
+ struct StructExtends<PhysicalDeviceIndexTypeUint8FeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceIndexTypeUint8FeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_extended_dynamic_state ===
+ template <>
+ struct StructExtends<PhysicalDeviceExtendedDynamicStateFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceExtendedDynamicStateFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_pipeline_executable_properties ===
+ template <>
+ struct StructExtends<PhysicalDevicePipelineExecutablePropertiesFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePipelineExecutablePropertiesFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_shader_atomic_float2 ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderAtomicFloat2FeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderAtomicFloat2FeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_device_generated_commands ===
+ template <>
+ struct StructExtends<PhysicalDeviceDeviceGeneratedCommandsPropertiesNV, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDeviceGeneratedCommandsFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDeviceGeneratedCommandsFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<GraphicsPipelineShaderGroupsCreateInfoNV, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_inherited_viewport_scissor ===
+ template <>
+ struct StructExtends<PhysicalDeviceInheritedViewportScissorFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceInheritedViewportScissorFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<CommandBufferInheritanceViewportScissorInfoNV, CommandBufferInheritanceInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_texel_buffer_alignment ===
+ template <>
+ struct StructExtends<PhysicalDeviceTexelBufferAlignmentFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceTexelBufferAlignmentFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_QCOM_render_pass_transform ===
+ template <>
+ struct StructExtends<RenderPassTransformBeginInfoQCOM, RenderPassBeginInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<CommandBufferInheritanceRenderPassTransformInfoQCOM, CommandBufferInheritanceInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_device_memory_report ===
+ template <>
+ struct StructExtends<PhysicalDeviceDeviceMemoryReportFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDeviceMemoryReportFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DeviceDeviceMemoryReportCreateInfoEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_robustness2 ===
+ template <>
+ struct StructExtends<PhysicalDeviceRobustness2FeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRobustness2FeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRobustness2PropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_custom_border_color ===
+ template <>
+ struct StructExtends<SamplerCustomBorderColorCreateInfoEXT, SamplerCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceCustomBorderColorPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceCustomBorderColorFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceCustomBorderColorFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_pipeline_library ===
+ template <>
+ struct StructExtends<PipelineLibraryCreateInfoKHR, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_present_barrier ===
+ template <>
+ struct StructExtends<PhysicalDevicePresentBarrierFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePresentBarrierFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SurfaceCapabilitiesPresentBarrierNV, SurfaceCapabilities2KHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SwapchainPresentBarrierCreateInfoNV, SwapchainCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_present_id ===
+ template <>
+ struct StructExtends<PresentIdKHR, PresentInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePresentIdFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePresentIdFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_encode_queue ===
+ template <>
+ struct StructExtends<VideoEncodeCapabilitiesKHR, VideoCapabilitiesKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeUsageInfoKHR, VideoProfileInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeUsageInfoKHR, QueryPoolCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeRateControlInfoKHR, VideoCodingControlInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<VideoEncodeRateControlLayerInfoKHR, VideoCodingControlInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+ //=== VK_NV_device_diagnostics_config ===
+ template <>
+ struct StructExtends<PhysicalDeviceDiagnosticsConfigFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDiagnosticsConfigFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DeviceDiagnosticsConfigCreateInfoNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_USE_PLATFORM_METAL_EXT )
+ //=== VK_EXT_metal_objects ===
+ template <>
+ struct StructExtends<ExportMetalObjectCreateInfoEXT, InstanceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalObjectCreateInfoEXT, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalObjectCreateInfoEXT, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalObjectCreateInfoEXT, ImageViewCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalObjectCreateInfoEXT, BufferViewCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalObjectCreateInfoEXT, SemaphoreCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalObjectCreateInfoEXT, EventCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalDeviceInfoEXT, ExportMetalObjectsInfoEXT>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalCommandQueueInfoEXT, ExportMetalObjectsInfoEXT>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalBufferInfoEXT, ExportMetalObjectsInfoEXT>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImportMetalBufferInfoEXT, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalTextureInfoEXT, ExportMetalObjectsInfoEXT>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImportMetalTextureInfoEXT, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalIOSurfaceInfoEXT, ExportMetalObjectsInfoEXT>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImportMetalIOSurfaceInfoEXT, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ExportMetalSharedEventInfoEXT, ExportMetalObjectsInfoEXT>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImportMetalSharedEventInfoEXT, SemaphoreCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImportMetalSharedEventInfoEXT, EventCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_METAL_EXT*/
+
+ //=== VK_KHR_synchronization2 ===
+ template <>
+ struct StructExtends<QueueFamilyCheckpointProperties2NV, QueueFamilyProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_graphics_pipeline_library ===
+ template <>
+ struct StructExtends<PhysicalDeviceGraphicsPipelineLibraryFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceGraphicsPipelineLibraryFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceGraphicsPipelineLibraryPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<GraphicsPipelineLibraryCreateInfoEXT, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_AMD_shader_early_and_late_fragment_tests ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_fragment_shader_barycentric ===
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentShaderBarycentricFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentShaderBarycentricFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentShaderBarycentricPropertiesKHR, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_shader_subgroup_uniform_control_flow ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_fragment_shading_rate_enums ===
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentShadingRateEnumsFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentShadingRateEnumsFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentShadingRateEnumsPropertiesNV, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineFragmentShadingRateEnumStateCreateInfoNV, GraphicsPipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_ray_tracing_motion_blur ===
+ template <>
+ struct StructExtends<AccelerationStructureGeometryMotionTrianglesDataNV, AccelerationStructureGeometryTrianglesDataKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<AccelerationStructureMotionInfoNV, AccelerationStructureCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRayTracingMotionBlurFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRayTracingMotionBlurFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_mesh_shader ===
+ template <>
+ struct StructExtends<PhysicalDeviceMeshShaderFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMeshShaderFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMeshShaderPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_ycbcr_2plane_444_formats ===
+ template <>
+ struct StructExtends<PhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_fragment_density_map2 ===
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentDensityMap2FeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentDensityMap2FeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentDensityMap2PropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_QCOM_rotated_copy_commands ===
+ template <>
+ struct StructExtends<CopyCommandTransformInfoQCOM, BufferImageCopy2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<CopyCommandTransformInfoQCOM, ImageBlit2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_workgroup_memory_explicit_layout ===
+ template <>
+ struct StructExtends<PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_image_compression_control ===
+ template <>
+ struct StructExtends<PhysicalDeviceImageCompressionControlFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImageCompressionControlFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageCompressionControlEXT, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageCompressionControlEXT, SwapchainCreateInfoKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageCompressionControlEXT, PhysicalDeviceImageFormatInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageCompressionPropertiesEXT, ImageFormatProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageCompressionPropertiesEXT, SurfaceFormat2KHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageCompressionPropertiesEXT, SubresourceLayout2EXT>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_attachment_feedback_loop_layout ===
+ template <>
+ struct StructExtends<PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_4444_formats ===
+ template <>
+ struct StructExtends<PhysicalDevice4444FormatsFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevice4444FormatsFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_device_fault ===
+ template <>
+ struct StructExtends<PhysicalDeviceFaultFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFaultFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_rgba10x6_formats ===
+ template <>
+ struct StructExtends<PhysicalDeviceRGBA10X6FormatsFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRGBA10X6FormatsFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_ray_tracing_pipeline ===
+ template <>
+ struct StructExtends<PhysicalDeviceRayTracingPipelineFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRayTracingPipelineFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRayTracingPipelinePropertiesKHR, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_ray_query ===
+ template <>
+ struct StructExtends<PhysicalDeviceRayQueryFeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRayQueryFeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_vertex_input_dynamic_state ===
+ template <>
+ struct StructExtends<PhysicalDeviceVertexInputDynamicStateFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceVertexInputDynamicStateFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_physical_device_drm ===
+ template <>
+ struct StructExtends<PhysicalDeviceDrmPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_device_address_binding_report ===
+ template <>
+ struct StructExtends<PhysicalDeviceAddressBindingReportFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceAddressBindingReportFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<DeviceAddressBindingCallbackDataEXT, DebugUtilsMessengerCallbackDataEXT>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_depth_clip_control ===
+ template <>
+ struct StructExtends<PhysicalDeviceDepthClipControlFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDepthClipControlFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineViewportDepthClipControlCreateInfoEXT, PipelineViewportStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_primitive_topology_list_restart ===
+ template <>
+ struct StructExtends<PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+# if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_external_memory ===
+ template <>
+ struct StructExtends<ImportMemoryZirconHandleInfoFUCHSIA, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+# if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_buffer_collection ===
+ template <>
+ struct StructExtends<ImportMemoryBufferCollectionFUCHSIA, MemoryAllocateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<BufferCollectionImageCreateInfoFUCHSIA, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<BufferCollectionBufferCreateInfoFUCHSIA, BufferCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+# endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+ //=== VK_HUAWEI_subpass_shading ===
+ template <>
+ struct StructExtends<SubpassShadingPipelineCreateInfoHUAWEI, ComputePipelineCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSubpassShadingFeaturesHUAWEI, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSubpassShadingFeaturesHUAWEI, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSubpassShadingPropertiesHUAWEI, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_HUAWEI_invocation_mask ===
+ template <>
+ struct StructExtends<PhysicalDeviceInvocationMaskFeaturesHUAWEI, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceInvocationMaskFeaturesHUAWEI, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_external_memory_rdma ===
+ template <>
+ struct StructExtends<PhysicalDeviceExternalMemoryRDMAFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceExternalMemoryRDMAFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_pipeline_properties ===
+ template <>
+ struct StructExtends<PhysicalDevicePipelinePropertiesFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePipelinePropertiesFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_multisampled_render_to_single_sampled ===
+ template <>
+ struct StructExtends<PhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SubpassResolvePerformanceQueryEXT, FormatProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MultisampledRenderToSingleSampledInfoEXT, SubpassDescription2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MultisampledRenderToSingleSampledInfoEXT, RenderingInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_extended_dynamic_state2 ===
+ template <>
+ struct StructExtends<PhysicalDeviceExtendedDynamicState2FeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceExtendedDynamicState2FeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_color_write_enable ===
+ template <>
+ struct StructExtends<PhysicalDeviceColorWriteEnableFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceColorWriteEnableFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineColorWriteCreateInfoEXT, PipelineColorBlendStateCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_primitives_generated_query ===
+ template <>
+ struct StructExtends<PhysicalDevicePrimitivesGeneratedQueryFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePrimitivesGeneratedQueryFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_KHR_ray_tracing_maintenance1 ===
+ template <>
+ struct StructExtends<PhysicalDeviceRayTracingMaintenance1FeaturesKHR, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRayTracingMaintenance1FeaturesKHR, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_image_view_min_lod ===
+ template <>
+ struct StructExtends<PhysicalDeviceImageViewMinLodFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImageViewMinLodFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<ImageViewMinLodCreateInfoEXT, ImageViewCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_multi_draw ===
+ template <>
+ struct StructExtends<PhysicalDeviceMultiDrawFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMultiDrawFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMultiDrawPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_image_2d_view_of_3d ===
+ template <>
+ struct StructExtends<PhysicalDeviceImage2DViewOf3DFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImage2DViewOf3DFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_opacity_micromap ===
+ template <>
+ struct StructExtends<PhysicalDeviceOpacityMicromapFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceOpacityMicromapFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceOpacityMicromapPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<AccelerationStructureTrianglesOpacityMicromapEXT, AccelerationStructureGeometryTrianglesDataKHR>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_border_color_swizzle ===
+ template <>
+ struct StructExtends<PhysicalDeviceBorderColorSwizzleFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceBorderColorSwizzleFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SamplerBorderColorComponentMappingCreateInfoEXT, SamplerCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_pageable_device_local_memory ===
+ template <>
+ struct StructExtends<PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_VALVE_descriptor_set_host_mapping ===
+ template <>
+ struct StructExtends<PhysicalDeviceDescriptorSetHostMappingFeaturesVALVE, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDescriptorSetHostMappingFeaturesVALVE, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_depth_clamp_zero_one ===
+ template <>
+ struct StructExtends<PhysicalDeviceDepthClampZeroOneFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceDepthClampZeroOneFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_non_seamless_cube_map ===
+ template <>
+ struct StructExtends<PhysicalDeviceNonSeamlessCubeMapFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceNonSeamlessCubeMapFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_QCOM_fragment_density_map_offset ===
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<SubpassFragmentDensityMapOffsetEndInfoQCOM, SubpassEndInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_linear_color_attachment ===
+ template <>
+ struct StructExtends<PhysicalDeviceLinearColorAttachmentFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceLinearColorAttachmentFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_image_compression_control_swapchain ===
+ template <>
+ struct StructExtends<PhysicalDeviceImageCompressionControlSwapchainFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImageCompressionControlSwapchainFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_QCOM_image_processing ===
+ template <>
+ struct StructExtends<ImageViewSampleWeightCreateInfoQCOM, ImageViewCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImageProcessingFeaturesQCOM, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImageProcessingFeaturesQCOM, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceImageProcessingPropertiesQCOM, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_extended_dynamic_state3 ===
+ template <>
+ struct StructExtends<PhysicalDeviceExtendedDynamicState3FeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceExtendedDynamicState3FeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceExtendedDynamicState3PropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_subpass_merge_feedback ===
+ template <>
+ struct StructExtends<PhysicalDeviceSubpassMergeFeedbackFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceSubpassMergeFeedbackFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<RenderPassCreationControlEXT, RenderPassCreateInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<RenderPassCreationControlEXT, SubpassDescription2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<RenderPassCreationFeedbackCreateInfoEXT, RenderPassCreateInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<RenderPassSubpassFeedbackCreateInfoEXT, SubpassDescription2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_shader_module_identifier ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderModuleIdentifierFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderModuleIdentifierFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderModuleIdentifierPropertiesEXT, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PipelineShaderStageModuleIdentifierCreateInfoEXT, PipelineShaderStageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_rasterization_order_attachment_access ===
+ template <>
+ struct StructExtends<PhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_NV_optical_flow ===
+ template <>
+ struct StructExtends<PhysicalDeviceOpticalFlowFeaturesNV, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceOpticalFlowFeaturesNV, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceOpticalFlowPropertiesNV, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<OpticalFlowImageFormatInfoNV, PhysicalDeviceImageFormatInfo2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<OpticalFlowImageFormatInfoNV, ImageCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<OpticalFlowSessionCreatePrivateDataInfoNV, OpticalFlowSessionCreateInfoNV>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_legacy_dithering ===
+ template <>
+ struct StructExtends<PhysicalDeviceLegacyDitheringFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceLegacyDitheringFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_pipeline_protected_access ===
+ template <>
+ struct StructExtends<PhysicalDevicePipelineProtectedAccessFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDevicePipelineProtectedAccessFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_QCOM_tile_properties ===
+ template <>
+ struct StructExtends<PhysicalDeviceTilePropertiesFeaturesQCOM, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceTilePropertiesFeaturesQCOM, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_SEC_amigo_profiling ===
+ template <>
+ struct StructExtends<PhysicalDeviceAmigoProfilingFeaturesSEC, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceAmigoProfilingFeaturesSEC, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<AmigoProfilingSubmitInfoSEC, SubmitInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_EXT_mutable_descriptor_type ===
+ template <>
+ struct StructExtends<PhysicalDeviceMutableDescriptorTypeFeaturesEXT, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceMutableDescriptorTypeFeaturesEXT, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MutableDescriptorTypeCreateInfoEXT, DescriptorSetLayoutCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<MutableDescriptorTypeCreateInfoEXT, DescriptorPoolCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ //=== VK_ARM_shader_core_builtins ===
+ template <>
+ struct StructExtends<PhysicalDeviceShaderCoreBuiltinsFeaturesARM, PhysicalDeviceFeatures2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderCoreBuiltinsFeaturesARM, DeviceCreateInfo>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+ template <>
+ struct StructExtends<PhysicalDeviceShaderCoreBuiltinsPropertiesARM, PhysicalDeviceProperties2>
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+#endif // VULKAN_HPP_DISABLE_ENHANCED_MODE
+
+#if VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL
+ class DynamicLoader
+ {
+ public:
+# ifdef VULKAN_HPP_NO_EXCEPTIONS
+ DynamicLoader( std::string const & vulkanLibraryName = {} ) VULKAN_HPP_NOEXCEPT
+# else
+ DynamicLoader( std::string const & vulkanLibraryName = {} )
+# endif
+ {
+ if ( !vulkanLibraryName.empty() )
+ {
+# if defined( __unix__ ) || defined( __APPLE__ ) || defined( __QNXNTO__ ) || defined( __Fuchsia__ )
+ m_library = dlopen( vulkanLibraryName.c_str(), RTLD_NOW | RTLD_LOCAL );
+# elif defined( _WIN32 )
+ m_library = ::LoadLibraryA( vulkanLibraryName.c_str() );
+# else
+# error unsupported platform
+# endif
+ }
+ else
+ {
+# if defined( __unix__ ) || defined( __QNXNTO__ ) || defined( __Fuchsia__ )
+ m_library = dlopen( "libvulkan.so", RTLD_NOW | RTLD_LOCAL );
+ if ( m_library == nullptr )
+ {
+ m_library = dlopen( "libvulkan.so.1", RTLD_NOW | RTLD_LOCAL );
+ }
+# elif defined( __APPLE__ )
+ m_library = dlopen( "libvulkan.dylib", RTLD_NOW | RTLD_LOCAL );
+# elif defined( _WIN32 )
+ m_library = ::LoadLibraryA( "vulkan-1.dll" );
+# else
+# error unsupported platform
+# endif
+ }
+
+# ifndef VULKAN_HPP_NO_EXCEPTIONS
+ if ( m_library == nullptr )
+ {
+ // NOTE there should be an InitializationFailedError, but msvc insists on the symbol does not exist within the scope of this function.
+ throw std::runtime_error( "Failed to load vulkan library!" );
+ }
+# endif
+ }
+
+ DynamicLoader( DynamicLoader const & ) = delete;
+
+ DynamicLoader( DynamicLoader && other ) VULKAN_HPP_NOEXCEPT : m_library( other.m_library )
+ {
+ other.m_library = nullptr;
+ }
+
+ DynamicLoader & operator=( DynamicLoader const & ) = delete;
+
+ DynamicLoader & operator=( DynamicLoader && other ) VULKAN_HPP_NOEXCEPT
+ {
+ std::swap( m_library, other.m_library );
+ return *this;
+ }
+
+ ~DynamicLoader() VULKAN_HPP_NOEXCEPT
+ {
+ if ( m_library )
+ {
+# if defined( __unix__ ) || defined( __APPLE__ ) || defined( __QNXNTO__ ) || defined( __Fuchsia__ )
+ dlclose( m_library );
+# elif defined( _WIN32 )
+ ::FreeLibrary( m_library );
+# else
+# error unsupported platform
+# endif
+ }
+ }
+
+ template <typename T>
+ T getProcAddress( const char * function ) const VULKAN_HPP_NOEXCEPT
+ {
+# if defined( __unix__ ) || defined( __APPLE__ ) || defined( __QNXNTO__ ) || defined( __Fuchsia__ )
+ return (T)dlsym( m_library, function );
+# elif defined( _WIN32 )
+ return ( T )::GetProcAddress( m_library, function );
+# else
+# error unsupported platform
+# endif
+ }
+
+ bool success() const VULKAN_HPP_NOEXCEPT
+ {
+ return m_library != nullptr;
+ }
+
+ private:
+# if defined( __unix__ ) || defined( __APPLE__ ) || defined( __QNXNTO__ ) || defined( __Fuchsia__ )
+ void * m_library;
+# elif defined( _WIN32 )
+ ::HINSTANCE m_library;
+# else
+# error unsupported platform
+# endif
+ };
+#endif
+
+ using PFN_dummy = void ( * )();
+
+ class DispatchLoaderDynamic : public DispatchLoaderBase
+ {
+ public:
+ //=== VK_VERSION_1_0 ===
+ PFN_vkCreateInstance vkCreateInstance = 0;
+ PFN_vkDestroyInstance vkDestroyInstance = 0;
+ PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices = 0;
+ PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures = 0;
+ PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties = 0;
+ PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties = 0;
+ PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties = 0;
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties = 0;
+ PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties = 0;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = 0;
+ PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr = 0;
+ PFN_vkCreateDevice vkCreateDevice = 0;
+ PFN_vkDestroyDevice vkDestroyDevice = 0;
+ PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties = 0;
+ PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties = 0;
+ PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties = 0;
+ PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties = 0;
+ PFN_vkGetDeviceQueue vkGetDeviceQueue = 0;
+ PFN_vkQueueSubmit vkQueueSubmit = 0;
+ PFN_vkQueueWaitIdle vkQueueWaitIdle = 0;
+ PFN_vkDeviceWaitIdle vkDeviceWaitIdle = 0;
+ PFN_vkAllocateMemory vkAllocateMemory = 0;
+ PFN_vkFreeMemory vkFreeMemory = 0;
+ PFN_vkMapMemory vkMapMemory = 0;
+ PFN_vkUnmapMemory vkUnmapMemory = 0;
+ PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges = 0;
+ PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges = 0;
+ PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment = 0;
+ PFN_vkBindBufferMemory vkBindBufferMemory = 0;
+ PFN_vkBindImageMemory vkBindImageMemory = 0;
+ PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements = 0;
+ PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements = 0;
+ PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements = 0;
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties = 0;
+ PFN_vkQueueBindSparse vkQueueBindSparse = 0;
+ PFN_vkCreateFence vkCreateFence = 0;
+ PFN_vkDestroyFence vkDestroyFence = 0;
+ PFN_vkResetFences vkResetFences = 0;
+ PFN_vkGetFenceStatus vkGetFenceStatus = 0;
+ PFN_vkWaitForFences vkWaitForFences = 0;
+ PFN_vkCreateSemaphore vkCreateSemaphore = 0;
+ PFN_vkDestroySemaphore vkDestroySemaphore = 0;
+ PFN_vkCreateEvent vkCreateEvent = 0;
+ PFN_vkDestroyEvent vkDestroyEvent = 0;
+ PFN_vkGetEventStatus vkGetEventStatus = 0;
+ PFN_vkSetEvent vkSetEvent = 0;
+ PFN_vkResetEvent vkResetEvent = 0;
+ PFN_vkCreateQueryPool vkCreateQueryPool = 0;
+ PFN_vkDestroyQueryPool vkDestroyQueryPool = 0;
+ PFN_vkGetQueryPoolResults vkGetQueryPoolResults = 0;
+ PFN_vkCreateBuffer vkCreateBuffer = 0;
+ PFN_vkDestroyBuffer vkDestroyBuffer = 0;
+ PFN_vkCreateBufferView vkCreateBufferView = 0;
+ PFN_vkDestroyBufferView vkDestroyBufferView = 0;
+ PFN_vkCreateImage vkCreateImage = 0;
+ PFN_vkDestroyImage vkDestroyImage = 0;
+ PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout = 0;
+ PFN_vkCreateImageView vkCreateImageView = 0;
+ PFN_vkDestroyImageView vkDestroyImageView = 0;
+ PFN_vkCreateShaderModule vkCreateShaderModule = 0;
+ PFN_vkDestroyShaderModule vkDestroyShaderModule = 0;
+ PFN_vkCreatePipelineCache vkCreatePipelineCache = 0;
+ PFN_vkDestroyPipelineCache vkDestroyPipelineCache = 0;
+ PFN_vkGetPipelineCacheData vkGetPipelineCacheData = 0;
+ PFN_vkMergePipelineCaches vkMergePipelineCaches = 0;
+ PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines = 0;
+ PFN_vkCreateComputePipelines vkCreateComputePipelines = 0;
+ PFN_vkDestroyPipeline vkDestroyPipeline = 0;
+ PFN_vkCreatePipelineLayout vkCreatePipelineLayout = 0;
+ PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout = 0;
+ PFN_vkCreateSampler vkCreateSampler = 0;
+ PFN_vkDestroySampler vkDestroySampler = 0;
+ PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout = 0;
+ PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout = 0;
+ PFN_vkCreateDescriptorPool vkCreateDescriptorPool = 0;
+ PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool = 0;
+ PFN_vkResetDescriptorPool vkResetDescriptorPool = 0;
+ PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets = 0;
+ PFN_vkFreeDescriptorSets vkFreeDescriptorSets = 0;
+ PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets = 0;
+ PFN_vkCreateFramebuffer vkCreateFramebuffer = 0;
+ PFN_vkDestroyFramebuffer vkDestroyFramebuffer = 0;
+ PFN_vkCreateRenderPass vkCreateRenderPass = 0;
+ PFN_vkDestroyRenderPass vkDestroyRenderPass = 0;
+ PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity = 0;
+ PFN_vkCreateCommandPool vkCreateCommandPool = 0;
+ PFN_vkDestroyCommandPool vkDestroyCommandPool = 0;
+ PFN_vkResetCommandPool vkResetCommandPool = 0;
+ PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers = 0;
+ PFN_vkFreeCommandBuffers vkFreeCommandBuffers = 0;
+ PFN_vkBeginCommandBuffer vkBeginCommandBuffer = 0;
+ PFN_vkEndCommandBuffer vkEndCommandBuffer = 0;
+ PFN_vkResetCommandBuffer vkResetCommandBuffer = 0;
+ PFN_vkCmdBindPipeline vkCmdBindPipeline = 0;
+ PFN_vkCmdSetViewport vkCmdSetViewport = 0;
+ PFN_vkCmdSetScissor vkCmdSetScissor = 0;
+ PFN_vkCmdSetLineWidth vkCmdSetLineWidth = 0;
+ PFN_vkCmdSetDepthBias vkCmdSetDepthBias = 0;
+ PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants = 0;
+ PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds = 0;
+ PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask = 0;
+ PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask = 0;
+ PFN_vkCmdSetStencilReference vkCmdSetStencilReference = 0;
+ PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets = 0;
+ PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer = 0;
+ PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers = 0;
+ PFN_vkCmdDraw vkCmdDraw = 0;
+ PFN_vkCmdDrawIndexed vkCmdDrawIndexed = 0;
+ PFN_vkCmdDrawIndirect vkCmdDrawIndirect = 0;
+ PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect = 0;
+ PFN_vkCmdDispatch vkCmdDispatch = 0;
+ PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect = 0;
+ PFN_vkCmdCopyBuffer vkCmdCopyBuffer = 0;
+ PFN_vkCmdCopyImage vkCmdCopyImage = 0;
+ PFN_vkCmdBlitImage vkCmdBlitImage = 0;
+ PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage = 0;
+ PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer = 0;
+ PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer = 0;
+ PFN_vkCmdFillBuffer vkCmdFillBuffer = 0;
+ PFN_vkCmdClearColorImage vkCmdClearColorImage = 0;
+ PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage = 0;
+ PFN_vkCmdClearAttachments vkCmdClearAttachments = 0;
+ PFN_vkCmdResolveImage vkCmdResolveImage = 0;
+ PFN_vkCmdSetEvent vkCmdSetEvent = 0;
+ PFN_vkCmdResetEvent vkCmdResetEvent = 0;
+ PFN_vkCmdWaitEvents vkCmdWaitEvents = 0;
+ PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier = 0;
+ PFN_vkCmdBeginQuery vkCmdBeginQuery = 0;
+ PFN_vkCmdEndQuery vkCmdEndQuery = 0;
+ PFN_vkCmdResetQueryPool vkCmdResetQueryPool = 0;
+ PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp = 0;
+ PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults = 0;
+ PFN_vkCmdPushConstants vkCmdPushConstants = 0;
+ PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass = 0;
+ PFN_vkCmdNextSubpass vkCmdNextSubpass = 0;
+ PFN_vkCmdEndRenderPass vkCmdEndRenderPass = 0;
+ PFN_vkCmdExecuteCommands vkCmdExecuteCommands = 0;
+
+ //=== VK_VERSION_1_1 ===
+ PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion = 0;
+ PFN_vkBindBufferMemory2 vkBindBufferMemory2 = 0;
+ PFN_vkBindImageMemory2 vkBindImageMemory2 = 0;
+ PFN_vkGetDeviceGroupPeerMemoryFeatures vkGetDeviceGroupPeerMemoryFeatures = 0;
+ PFN_vkCmdSetDeviceMask vkCmdSetDeviceMask = 0;
+ PFN_vkCmdDispatchBase vkCmdDispatchBase = 0;
+ PFN_vkEnumeratePhysicalDeviceGroups vkEnumeratePhysicalDeviceGroups = 0;
+ PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2 = 0;
+ PFN_vkGetBufferMemoryRequirements2 vkGetBufferMemoryRequirements2 = 0;
+ PFN_vkGetImageSparseMemoryRequirements2 vkGetImageSparseMemoryRequirements2 = 0;
+ PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2 = 0;
+ PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2 = 0;
+ PFN_vkGetPhysicalDeviceFormatProperties2 vkGetPhysicalDeviceFormatProperties2 = 0;
+ PFN_vkGetPhysicalDeviceImageFormatProperties2 vkGetPhysicalDeviceImageFormatProperties2 = 0;
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties2 vkGetPhysicalDeviceQueueFamilyProperties2 = 0;
+ PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2 = 0;
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 vkGetPhysicalDeviceSparseImageFormatProperties2 = 0;
+ PFN_vkTrimCommandPool vkTrimCommandPool = 0;
+ PFN_vkGetDeviceQueue2 vkGetDeviceQueue2 = 0;
+ PFN_vkCreateSamplerYcbcrConversion vkCreateSamplerYcbcrConversion = 0;
+ PFN_vkDestroySamplerYcbcrConversion vkDestroySamplerYcbcrConversion = 0;
+ PFN_vkCreateDescriptorUpdateTemplate vkCreateDescriptorUpdateTemplate = 0;
+ PFN_vkDestroyDescriptorUpdateTemplate vkDestroyDescriptorUpdateTemplate = 0;
+ PFN_vkUpdateDescriptorSetWithTemplate vkUpdateDescriptorSetWithTemplate = 0;
+ PFN_vkGetPhysicalDeviceExternalBufferProperties vkGetPhysicalDeviceExternalBufferProperties = 0;
+ PFN_vkGetPhysicalDeviceExternalFenceProperties vkGetPhysicalDeviceExternalFenceProperties = 0;
+ PFN_vkGetPhysicalDeviceExternalSemaphoreProperties vkGetPhysicalDeviceExternalSemaphoreProperties = 0;
+ PFN_vkGetDescriptorSetLayoutSupport vkGetDescriptorSetLayoutSupport = 0;
+
+ //=== VK_VERSION_1_2 ===
+ PFN_vkCmdDrawIndirectCount vkCmdDrawIndirectCount = 0;
+ PFN_vkCmdDrawIndexedIndirectCount vkCmdDrawIndexedIndirectCount = 0;
+ PFN_vkCreateRenderPass2 vkCreateRenderPass2 = 0;
+ PFN_vkCmdBeginRenderPass2 vkCmdBeginRenderPass2 = 0;
+ PFN_vkCmdNextSubpass2 vkCmdNextSubpass2 = 0;
+ PFN_vkCmdEndRenderPass2 vkCmdEndRenderPass2 = 0;
+ PFN_vkResetQueryPool vkResetQueryPool = 0;
+ PFN_vkGetSemaphoreCounterValue vkGetSemaphoreCounterValue = 0;
+ PFN_vkWaitSemaphores vkWaitSemaphores = 0;
+ PFN_vkSignalSemaphore vkSignalSemaphore = 0;
+ PFN_vkGetBufferDeviceAddress vkGetBufferDeviceAddress = 0;
+ PFN_vkGetBufferOpaqueCaptureAddress vkGetBufferOpaqueCaptureAddress = 0;
+ PFN_vkGetDeviceMemoryOpaqueCaptureAddress vkGetDeviceMemoryOpaqueCaptureAddress = 0;
+
+ //=== VK_VERSION_1_3 ===
+ PFN_vkGetPhysicalDeviceToolProperties vkGetPhysicalDeviceToolProperties = 0;
+ PFN_vkCreatePrivateDataSlot vkCreatePrivateDataSlot = 0;
+ PFN_vkDestroyPrivateDataSlot vkDestroyPrivateDataSlot = 0;
+ PFN_vkSetPrivateData vkSetPrivateData = 0;
+ PFN_vkGetPrivateData vkGetPrivateData = 0;
+ PFN_vkCmdSetEvent2 vkCmdSetEvent2 = 0;
+ PFN_vkCmdResetEvent2 vkCmdResetEvent2 = 0;
+ PFN_vkCmdWaitEvents2 vkCmdWaitEvents2 = 0;
+ PFN_vkCmdPipelineBarrier2 vkCmdPipelineBarrier2 = 0;
+ PFN_vkCmdWriteTimestamp2 vkCmdWriteTimestamp2 = 0;
+ PFN_vkQueueSubmit2 vkQueueSubmit2 = 0;
+ PFN_vkCmdCopyBuffer2 vkCmdCopyBuffer2 = 0;
+ PFN_vkCmdCopyImage2 vkCmdCopyImage2 = 0;
+ PFN_vkCmdCopyBufferToImage2 vkCmdCopyBufferToImage2 = 0;
+ PFN_vkCmdCopyImageToBuffer2 vkCmdCopyImageToBuffer2 = 0;
+ PFN_vkCmdBlitImage2 vkCmdBlitImage2 = 0;
+ PFN_vkCmdResolveImage2 vkCmdResolveImage2 = 0;
+ PFN_vkCmdBeginRendering vkCmdBeginRendering = 0;
+ PFN_vkCmdEndRendering vkCmdEndRendering = 0;
+ PFN_vkCmdSetCullMode vkCmdSetCullMode = 0;
+ PFN_vkCmdSetFrontFace vkCmdSetFrontFace = 0;
+ PFN_vkCmdSetPrimitiveTopology vkCmdSetPrimitiveTopology = 0;
+ PFN_vkCmdSetViewportWithCount vkCmdSetViewportWithCount = 0;
+ PFN_vkCmdSetScissorWithCount vkCmdSetScissorWithCount = 0;
+ PFN_vkCmdBindVertexBuffers2 vkCmdBindVertexBuffers2 = 0;
+ PFN_vkCmdSetDepthTestEnable vkCmdSetDepthTestEnable = 0;
+ PFN_vkCmdSetDepthWriteEnable vkCmdSetDepthWriteEnable = 0;
+ PFN_vkCmdSetDepthCompareOp vkCmdSetDepthCompareOp = 0;
+ PFN_vkCmdSetDepthBoundsTestEnable vkCmdSetDepthBoundsTestEnable = 0;
+ PFN_vkCmdSetStencilTestEnable vkCmdSetStencilTestEnable = 0;
+ PFN_vkCmdSetStencilOp vkCmdSetStencilOp = 0;
+ PFN_vkCmdSetRasterizerDiscardEnable vkCmdSetRasterizerDiscardEnable = 0;
+ PFN_vkCmdSetDepthBiasEnable vkCmdSetDepthBiasEnable = 0;
+ PFN_vkCmdSetPrimitiveRestartEnable vkCmdSetPrimitiveRestartEnable = 0;
+ PFN_vkGetDeviceBufferMemoryRequirements vkGetDeviceBufferMemoryRequirements = 0;
+ PFN_vkGetDeviceImageMemoryRequirements vkGetDeviceImageMemoryRequirements = 0;
+ PFN_vkGetDeviceImageSparseMemoryRequirements vkGetDeviceImageSparseMemoryRequirements = 0;
+
+ //=== VK_KHR_surface ===
+ PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR = 0;
+ PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR = 0;
+ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR = 0;
+ PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR = 0;
+ PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR = 0;
+
+ //=== VK_KHR_swapchain ===
+ PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR = 0;
+ PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR = 0;
+ PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR = 0;
+ PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR = 0;
+ PFN_vkQueuePresentKHR vkQueuePresentKHR = 0;
+ PFN_vkGetDeviceGroupPresentCapabilitiesKHR vkGetDeviceGroupPresentCapabilitiesKHR = 0;
+ PFN_vkGetDeviceGroupSurfacePresentModesKHR vkGetDeviceGroupSurfacePresentModesKHR = 0;
+ PFN_vkGetPhysicalDevicePresentRectanglesKHR vkGetPhysicalDevicePresentRectanglesKHR = 0;
+ PFN_vkAcquireNextImage2KHR vkAcquireNextImage2KHR = 0;
+
+ //=== VK_KHR_display ===
+ PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR = 0;
+ PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR = 0;
+ PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR = 0;
+ PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR = 0;
+ PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR = 0;
+ PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR = 0;
+ PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR = 0;
+
+ //=== VK_KHR_display_swapchain ===
+ PFN_vkCreateSharedSwapchainsKHR vkCreateSharedSwapchainsKHR = 0;
+
+#if defined( VK_USE_PLATFORM_XLIB_KHR )
+ //=== VK_KHR_xlib_surface ===
+ PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR = 0;
+ PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR = 0;
+#else
+ PFN_dummy vkCreateXlibSurfaceKHR_placeholder = 0;
+ PFN_dummy vkGetPhysicalDeviceXlibPresentationSupportKHR_placeholder = 0;
+#endif /*VK_USE_PLATFORM_XLIB_KHR*/
+
+#if defined( VK_USE_PLATFORM_XCB_KHR )
+ //=== VK_KHR_xcb_surface ===
+ PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR = 0;
+ PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR = 0;
+#else
+ PFN_dummy vkCreateXcbSurfaceKHR_placeholder = 0;
+ PFN_dummy vkGetPhysicalDeviceXcbPresentationSupportKHR_placeholder = 0;
+#endif /*VK_USE_PLATFORM_XCB_KHR*/
+
+#if defined( VK_USE_PLATFORM_WAYLAND_KHR )
+ //=== VK_KHR_wayland_surface ===
+ PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR = 0;
+ PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR = 0;
+#else
+ PFN_dummy vkCreateWaylandSurfaceKHR_placeholder = 0;
+ PFN_dummy vkGetPhysicalDeviceWaylandPresentationSupportKHR_placeholder = 0;
+#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+
+#if defined( VK_USE_PLATFORM_ANDROID_KHR )
+ //=== VK_KHR_android_surface ===
+ PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR = 0;
+#else
+ PFN_dummy vkCreateAndroidSurfaceKHR_placeholder = 0;
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_win32_surface ===
+ PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR = 0;
+ PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR = 0;
+#else
+ PFN_dummy vkCreateWin32SurfaceKHR_placeholder = 0;
+ PFN_dummy vkGetPhysicalDeviceWin32PresentationSupportKHR_placeholder = 0;
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_EXT_debug_report ===
+ PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = 0;
+ PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT = 0;
+ PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT = 0;
+
+ //=== VK_EXT_debug_marker ===
+ PFN_vkDebugMarkerSetObjectTagEXT vkDebugMarkerSetObjectTagEXT = 0;
+ PFN_vkDebugMarkerSetObjectNameEXT vkDebugMarkerSetObjectNameEXT = 0;
+ PFN_vkCmdDebugMarkerBeginEXT vkCmdDebugMarkerBeginEXT = 0;
+ PFN_vkCmdDebugMarkerEndEXT vkCmdDebugMarkerEndEXT = 0;
+ PFN_vkCmdDebugMarkerInsertEXT vkCmdDebugMarkerInsertEXT = 0;
+
+#if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_queue ===
+ PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR vkGetPhysicalDeviceVideoCapabilitiesKHR = 0;
+ PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR vkGetPhysicalDeviceVideoFormatPropertiesKHR = 0;
+ PFN_vkCreateVideoSessionKHR vkCreateVideoSessionKHR = 0;
+ PFN_vkDestroyVideoSessionKHR vkDestroyVideoSessionKHR = 0;
+ PFN_vkGetVideoSessionMemoryRequirementsKHR vkGetVideoSessionMemoryRequirementsKHR = 0;
+ PFN_vkBindVideoSessionMemoryKHR vkBindVideoSessionMemoryKHR = 0;
+ PFN_vkCreateVideoSessionParametersKHR vkCreateVideoSessionParametersKHR = 0;
+ PFN_vkUpdateVideoSessionParametersKHR vkUpdateVideoSessionParametersKHR = 0;
+ PFN_vkDestroyVideoSessionParametersKHR vkDestroyVideoSessionParametersKHR = 0;
+ PFN_vkCmdBeginVideoCodingKHR vkCmdBeginVideoCodingKHR = 0;
+ PFN_vkCmdEndVideoCodingKHR vkCmdEndVideoCodingKHR = 0;
+ PFN_vkCmdControlVideoCodingKHR vkCmdControlVideoCodingKHR = 0;
+#else
+ PFN_dummy vkGetPhysicalDeviceVideoCapabilitiesKHR_placeholder = 0;
+ PFN_dummy vkGetPhysicalDeviceVideoFormatPropertiesKHR_placeholder = 0;
+ PFN_dummy vkCreateVideoSessionKHR_placeholder = 0;
+ PFN_dummy vkDestroyVideoSessionKHR_placeholder = 0;
+ PFN_dummy vkGetVideoSessionMemoryRequirementsKHR_placeholder = 0;
+ PFN_dummy vkBindVideoSessionMemoryKHR_placeholder = 0;
+ PFN_dummy vkCreateVideoSessionParametersKHR_placeholder = 0;
+ PFN_dummy vkUpdateVideoSessionParametersKHR_placeholder = 0;
+ PFN_dummy vkDestroyVideoSessionParametersKHR_placeholder = 0;
+ PFN_dummy vkCmdBeginVideoCodingKHR_placeholder = 0;
+ PFN_dummy vkCmdEndVideoCodingKHR_placeholder = 0;
+ PFN_dummy vkCmdControlVideoCodingKHR_placeholder = 0;
+#endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+#if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_decode_queue ===
+ PFN_vkCmdDecodeVideoKHR vkCmdDecodeVideoKHR = 0;
+#else
+ PFN_dummy vkCmdDecodeVideoKHR_placeholder = 0;
+#endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+ //=== VK_EXT_transform_feedback ===
+ PFN_vkCmdBindTransformFeedbackBuffersEXT vkCmdBindTransformFeedbackBuffersEXT = 0;
+ PFN_vkCmdBeginTransformFeedbackEXT vkCmdBeginTransformFeedbackEXT = 0;
+ PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT = 0;
+ PFN_vkCmdBeginQueryIndexedEXT vkCmdBeginQueryIndexedEXT = 0;
+ PFN_vkCmdEndQueryIndexedEXT vkCmdEndQueryIndexedEXT = 0;
+ PFN_vkCmdDrawIndirectByteCountEXT vkCmdDrawIndirectByteCountEXT = 0;
+
+ //=== VK_NVX_binary_import ===
+ PFN_vkCreateCuModuleNVX vkCreateCuModuleNVX = 0;
+ PFN_vkCreateCuFunctionNVX vkCreateCuFunctionNVX = 0;
+ PFN_vkDestroyCuModuleNVX vkDestroyCuModuleNVX = 0;
+ PFN_vkDestroyCuFunctionNVX vkDestroyCuFunctionNVX = 0;
+ PFN_vkCmdCuLaunchKernelNVX vkCmdCuLaunchKernelNVX = 0;
+
+ //=== VK_NVX_image_view_handle ===
+ PFN_vkGetImageViewHandleNVX vkGetImageViewHandleNVX = 0;
+ PFN_vkGetImageViewAddressNVX vkGetImageViewAddressNVX = 0;
+
+ //=== VK_AMD_draw_indirect_count ===
+ PFN_vkCmdDrawIndirectCountAMD vkCmdDrawIndirectCountAMD = 0;
+ PFN_vkCmdDrawIndexedIndirectCountAMD vkCmdDrawIndexedIndirectCountAMD = 0;
+
+ //=== VK_AMD_shader_info ===
+ PFN_vkGetShaderInfoAMD vkGetShaderInfoAMD = 0;
+
+ //=== VK_KHR_dynamic_rendering ===
+ PFN_vkCmdBeginRenderingKHR vkCmdBeginRenderingKHR = 0;
+ PFN_vkCmdEndRenderingKHR vkCmdEndRenderingKHR = 0;
+
+#if defined( VK_USE_PLATFORM_GGP )
+ //=== VK_GGP_stream_descriptor_surface ===
+ PFN_vkCreateStreamDescriptorSurfaceGGP vkCreateStreamDescriptorSurfaceGGP = 0;
+#else
+ PFN_dummy vkCreateStreamDescriptorSurfaceGGP_placeholder = 0;
+#endif /*VK_USE_PLATFORM_GGP*/
+
+ //=== VK_NV_external_memory_capabilities ===
+ PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV vkGetPhysicalDeviceExternalImageFormatPropertiesNV = 0;
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_NV_external_memory_win32 ===
+ PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV = 0;
+#else
+ PFN_dummy vkGetMemoryWin32HandleNV_placeholder = 0;
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_get_physical_device_properties2 ===
+ PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR = 0;
+ PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = 0;
+ PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR = 0;
+ PFN_vkGetPhysicalDeviceImageFormatProperties2KHR vkGetPhysicalDeviceImageFormatProperties2KHR = 0;
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR = 0;
+ PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR = 0;
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR vkGetPhysicalDeviceSparseImageFormatProperties2KHR = 0;
+
+ //=== VK_KHR_device_group ===
+ PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR vkGetDeviceGroupPeerMemoryFeaturesKHR = 0;
+ PFN_vkCmdSetDeviceMaskKHR vkCmdSetDeviceMaskKHR = 0;
+ PFN_vkCmdDispatchBaseKHR vkCmdDispatchBaseKHR = 0;
+
+#if defined( VK_USE_PLATFORM_VI_NN )
+ //=== VK_NN_vi_surface ===
+ PFN_vkCreateViSurfaceNN vkCreateViSurfaceNN = 0;
+#else
+ PFN_dummy vkCreateViSurfaceNN_placeholder = 0;
+#endif /*VK_USE_PLATFORM_VI_NN*/
+
+ //=== VK_KHR_maintenance1 ===
+ PFN_vkTrimCommandPoolKHR vkTrimCommandPoolKHR = 0;
+
+ //=== VK_KHR_device_group_creation ===
+ PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR = 0;
+
+ //=== VK_KHR_external_memory_capabilities ===
+ PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR vkGetPhysicalDeviceExternalBufferPropertiesKHR = 0;
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_memory_win32 ===
+ PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32HandleKHR = 0;
+ PFN_vkGetMemoryWin32HandlePropertiesKHR vkGetMemoryWin32HandlePropertiesKHR = 0;
+#else
+ PFN_dummy vkGetMemoryWin32HandleKHR_placeholder = 0;
+ PFN_dummy vkGetMemoryWin32HandlePropertiesKHR_placeholder = 0;
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_memory_fd ===
+ PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR = 0;
+ PFN_vkGetMemoryFdPropertiesKHR vkGetMemoryFdPropertiesKHR = 0;
+
+ //=== VK_KHR_external_semaphore_capabilities ===
+ PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR vkGetPhysicalDeviceExternalSemaphorePropertiesKHR = 0;
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_semaphore_win32 ===
+ PFN_vkImportSemaphoreWin32HandleKHR vkImportSemaphoreWin32HandleKHR = 0;
+ PFN_vkGetSemaphoreWin32HandleKHR vkGetSemaphoreWin32HandleKHR = 0;
+#else
+ PFN_dummy vkImportSemaphoreWin32HandleKHR_placeholder = 0;
+ PFN_dummy vkGetSemaphoreWin32HandleKHR_placeholder = 0;
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_semaphore_fd ===
+ PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR = 0;
+ PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR = 0;
+
+ //=== VK_KHR_push_descriptor ===
+ PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR = 0;
+ PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR = 0;
+
+ //=== VK_EXT_conditional_rendering ===
+ PFN_vkCmdBeginConditionalRenderingEXT vkCmdBeginConditionalRenderingEXT = 0;
+ PFN_vkCmdEndConditionalRenderingEXT vkCmdEndConditionalRenderingEXT = 0;
+
+ //=== VK_KHR_descriptor_update_template ===
+ PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR = 0;
+ PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR = 0;
+ PFN_vkUpdateDescriptorSetWithTemplateKHR vkUpdateDescriptorSetWithTemplateKHR = 0;
+
+ //=== VK_NV_clip_space_w_scaling ===
+ PFN_vkCmdSetViewportWScalingNV vkCmdSetViewportWScalingNV = 0;
+
+ //=== VK_EXT_direct_mode_display ===
+ PFN_vkReleaseDisplayEXT vkReleaseDisplayEXT = 0;
+
+#if defined( VK_USE_PLATFORM_XLIB_XRANDR_EXT )
+ //=== VK_EXT_acquire_xlib_display ===
+ PFN_vkAcquireXlibDisplayEXT vkAcquireXlibDisplayEXT = 0;
+ PFN_vkGetRandROutputDisplayEXT vkGetRandROutputDisplayEXT = 0;
+#else
+ PFN_dummy vkAcquireXlibDisplayEXT_placeholder = 0;
+ PFN_dummy vkGetRandROutputDisplayEXT_placeholder = 0;
+#endif /*VK_USE_PLATFORM_XLIB_XRANDR_EXT*/
+
+ //=== VK_EXT_display_surface_counter ===
+ PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT vkGetPhysicalDeviceSurfaceCapabilities2EXT = 0;
+
+ //=== VK_EXT_display_control ===
+ PFN_vkDisplayPowerControlEXT vkDisplayPowerControlEXT = 0;
+ PFN_vkRegisterDeviceEventEXT vkRegisterDeviceEventEXT = 0;
+ PFN_vkRegisterDisplayEventEXT vkRegisterDisplayEventEXT = 0;
+ PFN_vkGetSwapchainCounterEXT vkGetSwapchainCounterEXT = 0;
+
+ //=== VK_GOOGLE_display_timing ===
+ PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE = 0;
+ PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE = 0;
+
+ //=== VK_EXT_discard_rectangles ===
+ PFN_vkCmdSetDiscardRectangleEXT vkCmdSetDiscardRectangleEXT = 0;
+
+ //=== VK_EXT_hdr_metadata ===
+ PFN_vkSetHdrMetadataEXT vkSetHdrMetadataEXT = 0;
+
+ //=== VK_KHR_create_renderpass2 ===
+ PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = 0;
+ PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR = 0;
+ PFN_vkCmdNextSubpass2KHR vkCmdNextSubpass2KHR = 0;
+ PFN_vkCmdEndRenderPass2KHR vkCmdEndRenderPass2KHR = 0;
+
+ //=== VK_KHR_shared_presentable_image ===
+ PFN_vkGetSwapchainStatusKHR vkGetSwapchainStatusKHR = 0;
+
+ //=== VK_KHR_external_fence_capabilities ===
+ PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR vkGetPhysicalDeviceExternalFencePropertiesKHR = 0;
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_fence_win32 ===
+ PFN_vkImportFenceWin32HandleKHR vkImportFenceWin32HandleKHR = 0;
+ PFN_vkGetFenceWin32HandleKHR vkGetFenceWin32HandleKHR = 0;
+#else
+ PFN_dummy vkImportFenceWin32HandleKHR_placeholder = 0;
+ PFN_dummy vkGetFenceWin32HandleKHR_placeholder = 0;
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_fence_fd ===
+ PFN_vkImportFenceFdKHR vkImportFenceFdKHR = 0;
+ PFN_vkGetFenceFdKHR vkGetFenceFdKHR = 0;
+
+ //=== VK_KHR_performance_query ===
+ PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR = 0;
+ PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR = 0;
+ PFN_vkAcquireProfilingLockKHR vkAcquireProfilingLockKHR = 0;
+ PFN_vkReleaseProfilingLockKHR vkReleaseProfilingLockKHR = 0;
+
+ //=== VK_KHR_get_surface_capabilities2 ===
+ PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR = 0;
+ PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR = 0;
+
+ //=== VK_KHR_get_display_properties2 ===
+ PFN_vkGetPhysicalDeviceDisplayProperties2KHR vkGetPhysicalDeviceDisplayProperties2KHR = 0;
+ PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR vkGetPhysicalDeviceDisplayPlaneProperties2KHR = 0;
+ PFN_vkGetDisplayModeProperties2KHR vkGetDisplayModeProperties2KHR = 0;
+ PFN_vkGetDisplayPlaneCapabilities2KHR vkGetDisplayPlaneCapabilities2KHR = 0;
+
+#if defined( VK_USE_PLATFORM_IOS_MVK )
+ //=== VK_MVK_ios_surface ===
+ PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK = 0;
+#else
+ PFN_dummy vkCreateIOSSurfaceMVK_placeholder = 0;
+#endif /*VK_USE_PLATFORM_IOS_MVK*/
+
+#if defined( VK_USE_PLATFORM_MACOS_MVK )
+ //=== VK_MVK_macos_surface ===
+ PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK = 0;
+#else
+ PFN_dummy vkCreateMacOSSurfaceMVK_placeholder = 0;
+#endif /*VK_USE_PLATFORM_MACOS_MVK*/
+
+ //=== VK_EXT_debug_utils ===
+ PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT = 0;
+ PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT = 0;
+ PFN_vkQueueBeginDebugUtilsLabelEXT vkQueueBeginDebugUtilsLabelEXT = 0;
+ PFN_vkQueueEndDebugUtilsLabelEXT vkQueueEndDebugUtilsLabelEXT = 0;
+ PFN_vkQueueInsertDebugUtilsLabelEXT vkQueueInsertDebugUtilsLabelEXT = 0;
+ PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT = 0;
+ PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT = 0;
+ PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT = 0;
+ PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT = 0;
+ PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT = 0;
+ PFN_vkSubmitDebugUtilsMessageEXT vkSubmitDebugUtilsMessageEXT = 0;
+
+#if defined( VK_USE_PLATFORM_ANDROID_KHR )
+ //=== VK_ANDROID_external_memory_android_hardware_buffer ===
+ PFN_vkGetAndroidHardwareBufferPropertiesANDROID vkGetAndroidHardwareBufferPropertiesANDROID = 0;
+ PFN_vkGetMemoryAndroidHardwareBufferANDROID vkGetMemoryAndroidHardwareBufferANDROID = 0;
+#else
+ PFN_dummy vkGetAndroidHardwareBufferPropertiesANDROID_placeholder = 0;
+ PFN_dummy vkGetMemoryAndroidHardwareBufferANDROID_placeholder = 0;
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+ //=== VK_EXT_sample_locations ===
+ PFN_vkCmdSetSampleLocationsEXT vkCmdSetSampleLocationsEXT = 0;
+ PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT vkGetPhysicalDeviceMultisamplePropertiesEXT = 0;
+
+ //=== VK_KHR_get_memory_requirements2 ===
+ PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR = 0;
+ PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR = 0;
+ PFN_vkGetImageSparseMemoryRequirements2KHR vkGetImageSparseMemoryRequirements2KHR = 0;
+
+ //=== VK_KHR_acceleration_structure ===
+ PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR = 0;
+ PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR = 0;
+ PFN_vkCmdBuildAccelerationStructuresKHR vkCmdBuildAccelerationStructuresKHR = 0;
+ PFN_vkCmdBuildAccelerationStructuresIndirectKHR vkCmdBuildAccelerationStructuresIndirectKHR = 0;
+ PFN_vkBuildAccelerationStructuresKHR vkBuildAccelerationStructuresKHR = 0;
+ PFN_vkCopyAccelerationStructureKHR vkCopyAccelerationStructureKHR = 0;
+ PFN_vkCopyAccelerationStructureToMemoryKHR vkCopyAccelerationStructureToMemoryKHR = 0;
+ PFN_vkCopyMemoryToAccelerationStructureKHR vkCopyMemoryToAccelerationStructureKHR = 0;
+ PFN_vkWriteAccelerationStructuresPropertiesKHR vkWriteAccelerationStructuresPropertiesKHR = 0;
+ PFN_vkCmdCopyAccelerationStructureKHR vkCmdCopyAccelerationStructureKHR = 0;
+ PFN_vkCmdCopyAccelerationStructureToMemoryKHR vkCmdCopyAccelerationStructureToMemoryKHR = 0;
+ PFN_vkCmdCopyMemoryToAccelerationStructureKHR vkCmdCopyMemoryToAccelerationStructureKHR = 0;
+ PFN_vkGetAccelerationStructureDeviceAddressKHR vkGetAccelerationStructureDeviceAddressKHR = 0;
+ PFN_vkCmdWriteAccelerationStructuresPropertiesKHR vkCmdWriteAccelerationStructuresPropertiesKHR = 0;
+ PFN_vkGetDeviceAccelerationStructureCompatibilityKHR vkGetDeviceAccelerationStructureCompatibilityKHR = 0;
+ PFN_vkGetAccelerationStructureBuildSizesKHR vkGetAccelerationStructureBuildSizesKHR = 0;
+
+ //=== VK_KHR_sampler_ycbcr_conversion ===
+ PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionKHR = 0;
+ PFN_vkDestroySamplerYcbcrConversionKHR vkDestroySamplerYcbcrConversionKHR = 0;
+
+ //=== VK_KHR_bind_memory2 ===
+ PFN_vkBindBufferMemory2KHR vkBindBufferMemory2KHR = 0;
+ PFN_vkBindImageMemory2KHR vkBindImageMemory2KHR = 0;
+
+ //=== VK_EXT_image_drm_format_modifier ===
+ PFN_vkGetImageDrmFormatModifierPropertiesEXT vkGetImageDrmFormatModifierPropertiesEXT = 0;
+
+ //=== VK_EXT_validation_cache ===
+ PFN_vkCreateValidationCacheEXT vkCreateValidationCacheEXT = 0;
+ PFN_vkDestroyValidationCacheEXT vkDestroyValidationCacheEXT = 0;
+ PFN_vkMergeValidationCachesEXT vkMergeValidationCachesEXT = 0;
+ PFN_vkGetValidationCacheDataEXT vkGetValidationCacheDataEXT = 0;
+
+ //=== VK_NV_shading_rate_image ===
+ PFN_vkCmdBindShadingRateImageNV vkCmdBindShadingRateImageNV = 0;
+ PFN_vkCmdSetViewportShadingRatePaletteNV vkCmdSetViewportShadingRatePaletteNV = 0;
+ PFN_vkCmdSetCoarseSampleOrderNV vkCmdSetCoarseSampleOrderNV = 0;
+
+ //=== VK_NV_ray_tracing ===
+ PFN_vkCreateAccelerationStructureNV vkCreateAccelerationStructureNV = 0;
+ PFN_vkDestroyAccelerationStructureNV vkDestroyAccelerationStructureNV = 0;
+ PFN_vkGetAccelerationStructureMemoryRequirementsNV vkGetAccelerationStructureMemoryRequirementsNV = 0;
+ PFN_vkBindAccelerationStructureMemoryNV vkBindAccelerationStructureMemoryNV = 0;
+ PFN_vkCmdBuildAccelerationStructureNV vkCmdBuildAccelerationStructureNV = 0;
+ PFN_vkCmdCopyAccelerationStructureNV vkCmdCopyAccelerationStructureNV = 0;
+ PFN_vkCmdTraceRaysNV vkCmdTraceRaysNV = 0;
+ PFN_vkCreateRayTracingPipelinesNV vkCreateRayTracingPipelinesNV = 0;
+ PFN_vkGetRayTracingShaderGroupHandlesNV vkGetRayTracingShaderGroupHandlesNV = 0;
+ PFN_vkGetAccelerationStructureHandleNV vkGetAccelerationStructureHandleNV = 0;
+ PFN_vkCmdWriteAccelerationStructuresPropertiesNV vkCmdWriteAccelerationStructuresPropertiesNV = 0;
+ PFN_vkCompileDeferredNV vkCompileDeferredNV = 0;
+
+ //=== VK_KHR_maintenance3 ===
+ PFN_vkGetDescriptorSetLayoutSupportKHR vkGetDescriptorSetLayoutSupportKHR = 0;
+
+ //=== VK_KHR_draw_indirect_count ===
+ PFN_vkCmdDrawIndirectCountKHR vkCmdDrawIndirectCountKHR = 0;
+ PFN_vkCmdDrawIndexedIndirectCountKHR vkCmdDrawIndexedIndirectCountKHR = 0;
+
+ //=== VK_EXT_external_memory_host ===
+ PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesEXT = 0;
+
+ //=== VK_AMD_buffer_marker ===
+ PFN_vkCmdWriteBufferMarkerAMD vkCmdWriteBufferMarkerAMD = 0;
+
+ //=== VK_EXT_calibrated_timestamps ===
+ PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT vkGetPhysicalDeviceCalibrateableTimeDomainsEXT = 0;
+ PFN_vkGetCalibratedTimestampsEXT vkGetCalibratedTimestampsEXT = 0;
+
+ //=== VK_NV_mesh_shader ===
+ PFN_vkCmdDrawMeshTasksNV vkCmdDrawMeshTasksNV = 0;
+ PFN_vkCmdDrawMeshTasksIndirectNV vkCmdDrawMeshTasksIndirectNV = 0;
+ PFN_vkCmdDrawMeshTasksIndirectCountNV vkCmdDrawMeshTasksIndirectCountNV = 0;
+
+ //=== VK_NV_scissor_exclusive ===
+ PFN_vkCmdSetExclusiveScissorNV vkCmdSetExclusiveScissorNV = 0;
+
+ //=== VK_NV_device_diagnostic_checkpoints ===
+ PFN_vkCmdSetCheckpointNV vkCmdSetCheckpointNV = 0;
+ PFN_vkGetQueueCheckpointDataNV vkGetQueueCheckpointDataNV = 0;
+
+ //=== VK_KHR_timeline_semaphore ===
+ PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR = 0;
+ PFN_vkWaitSemaphoresKHR vkWaitSemaphoresKHR = 0;
+ PFN_vkSignalSemaphoreKHR vkSignalSemaphoreKHR = 0;
+
+ //=== VK_INTEL_performance_query ===
+ PFN_vkInitializePerformanceApiINTEL vkInitializePerformanceApiINTEL = 0;
+ PFN_vkUninitializePerformanceApiINTEL vkUninitializePerformanceApiINTEL = 0;
+ PFN_vkCmdSetPerformanceMarkerINTEL vkCmdSetPerformanceMarkerINTEL = 0;
+ PFN_vkCmdSetPerformanceStreamMarkerINTEL vkCmdSetPerformanceStreamMarkerINTEL = 0;
+ PFN_vkCmdSetPerformanceOverrideINTEL vkCmdSetPerformanceOverrideINTEL = 0;
+ PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL = 0;
+ PFN_vkReleasePerformanceConfigurationINTEL vkReleasePerformanceConfigurationINTEL = 0;
+ PFN_vkQueueSetPerformanceConfigurationINTEL vkQueueSetPerformanceConfigurationINTEL = 0;
+ PFN_vkGetPerformanceParameterINTEL vkGetPerformanceParameterINTEL = 0;
+
+ //=== VK_AMD_display_native_hdr ===
+ PFN_vkSetLocalDimmingAMD vkSetLocalDimmingAMD = 0;
+
+#if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_imagepipe_surface ===
+ PFN_vkCreateImagePipeSurfaceFUCHSIA vkCreateImagePipeSurfaceFUCHSIA = 0;
+#else
+ PFN_dummy vkCreateImagePipeSurfaceFUCHSIA_placeholder = 0;
+#endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+#if defined( VK_USE_PLATFORM_METAL_EXT )
+ //=== VK_EXT_metal_surface ===
+ PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT = 0;
+#else
+ PFN_dummy vkCreateMetalSurfaceEXT_placeholder = 0;
+#endif /*VK_USE_PLATFORM_METAL_EXT*/
+
+ //=== VK_KHR_fragment_shading_rate ===
+ PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR vkGetPhysicalDeviceFragmentShadingRatesKHR = 0;
+ PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR = 0;
+
+ //=== VK_EXT_buffer_device_address ===
+ PFN_vkGetBufferDeviceAddressEXT vkGetBufferDeviceAddressEXT = 0;
+
+ //=== VK_EXT_tooling_info ===
+ PFN_vkGetPhysicalDeviceToolPropertiesEXT vkGetPhysicalDeviceToolPropertiesEXT = 0;
+
+ //=== VK_KHR_present_wait ===
+ PFN_vkWaitForPresentKHR vkWaitForPresentKHR = 0;
+
+ //=== VK_NV_cooperative_matrix ===
+ PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV vkGetPhysicalDeviceCooperativeMatrixPropertiesNV = 0;
+
+ //=== VK_NV_coverage_reduction_mode ===
+ PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV = 0;
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_EXT_full_screen_exclusive ===
+ PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT vkGetPhysicalDeviceSurfacePresentModes2EXT = 0;
+ PFN_vkAcquireFullScreenExclusiveModeEXT vkAcquireFullScreenExclusiveModeEXT = 0;
+ PFN_vkReleaseFullScreenExclusiveModeEXT vkReleaseFullScreenExclusiveModeEXT = 0;
+ PFN_vkGetDeviceGroupSurfacePresentModes2EXT vkGetDeviceGroupSurfacePresentModes2EXT = 0;
+#else
+ PFN_dummy vkGetPhysicalDeviceSurfacePresentModes2EXT_placeholder = 0;
+ PFN_dummy vkAcquireFullScreenExclusiveModeEXT_placeholder = 0;
+ PFN_dummy vkReleaseFullScreenExclusiveModeEXT_placeholder = 0;
+ PFN_dummy vkGetDeviceGroupSurfacePresentModes2EXT_placeholder = 0;
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_EXT_headless_surface ===
+ PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT = 0;
+
+ //=== VK_KHR_buffer_device_address ===
+ PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR = 0;
+ PFN_vkGetBufferOpaqueCaptureAddressKHR vkGetBufferOpaqueCaptureAddressKHR = 0;
+ PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR vkGetDeviceMemoryOpaqueCaptureAddressKHR = 0;
+
+ //=== VK_EXT_line_rasterization ===
+ PFN_vkCmdSetLineStippleEXT vkCmdSetLineStippleEXT = 0;
+
+ //=== VK_EXT_host_query_reset ===
+ PFN_vkResetQueryPoolEXT vkResetQueryPoolEXT = 0;
+
+ //=== VK_EXT_extended_dynamic_state ===
+ PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT = 0;
+ PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT = 0;
+ PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT = 0;
+ PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT = 0;
+ PFN_vkCmdSetScissorWithCountEXT vkCmdSetScissorWithCountEXT = 0;
+ PFN_vkCmdBindVertexBuffers2EXT vkCmdBindVertexBuffers2EXT = 0;
+ PFN_vkCmdSetDepthTestEnableEXT vkCmdSetDepthTestEnableEXT = 0;
+ PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT = 0;
+ PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT = 0;
+ PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnableEXT = 0;
+ PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT = 0;
+ PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT = 0;
+
+ //=== VK_KHR_deferred_host_operations ===
+ PFN_vkCreateDeferredOperationKHR vkCreateDeferredOperationKHR = 0;
+ PFN_vkDestroyDeferredOperationKHR vkDestroyDeferredOperationKHR = 0;
+ PFN_vkGetDeferredOperationMaxConcurrencyKHR vkGetDeferredOperationMaxConcurrencyKHR = 0;
+ PFN_vkGetDeferredOperationResultKHR vkGetDeferredOperationResultKHR = 0;
+ PFN_vkDeferredOperationJoinKHR vkDeferredOperationJoinKHR = 0;
+
+ //=== VK_KHR_pipeline_executable_properties ===
+ PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR = 0;
+ PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR = 0;
+ PFN_vkGetPipelineExecutableInternalRepresentationsKHR vkGetPipelineExecutableInternalRepresentationsKHR = 0;
+
+ //=== VK_NV_device_generated_commands ===
+ PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemoryRequirementsNV = 0;
+ PFN_vkCmdPreprocessGeneratedCommandsNV vkCmdPreprocessGeneratedCommandsNV = 0;
+ PFN_vkCmdExecuteGeneratedCommandsNV vkCmdExecuteGeneratedCommandsNV = 0;
+ PFN_vkCmdBindPipelineShaderGroupNV vkCmdBindPipelineShaderGroupNV = 0;
+ PFN_vkCreateIndirectCommandsLayoutNV vkCreateIndirectCommandsLayoutNV = 0;
+ PFN_vkDestroyIndirectCommandsLayoutNV vkDestroyIndirectCommandsLayoutNV = 0;
+
+ //=== VK_EXT_acquire_drm_display ===
+ PFN_vkAcquireDrmDisplayEXT vkAcquireDrmDisplayEXT = 0;
+ PFN_vkGetDrmDisplayEXT vkGetDrmDisplayEXT = 0;
+
+ //=== VK_EXT_private_data ===
+ PFN_vkCreatePrivateDataSlotEXT vkCreatePrivateDataSlotEXT = 0;
+ PFN_vkDestroyPrivateDataSlotEXT vkDestroyPrivateDataSlotEXT = 0;
+ PFN_vkSetPrivateDataEXT vkSetPrivateDataEXT = 0;
+ PFN_vkGetPrivateDataEXT vkGetPrivateDataEXT = 0;
+
+#if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_encode_queue ===
+ PFN_vkCmdEncodeVideoKHR vkCmdEncodeVideoKHR = 0;
+#else
+ PFN_dummy vkCmdEncodeVideoKHR_placeholder = 0;
+#endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+#if defined( VK_USE_PLATFORM_METAL_EXT )
+ //=== VK_EXT_metal_objects ===
+ PFN_vkExportMetalObjectsEXT vkExportMetalObjectsEXT = 0;
+#else
+ PFN_dummy vkExportMetalObjectsEXT_placeholder = 0;
+#endif /*VK_USE_PLATFORM_METAL_EXT*/
+
+ //=== VK_KHR_synchronization2 ===
+ PFN_vkCmdSetEvent2KHR vkCmdSetEvent2KHR = 0;
+ PFN_vkCmdResetEvent2KHR vkCmdResetEvent2KHR = 0;
+ PFN_vkCmdWaitEvents2KHR vkCmdWaitEvents2KHR = 0;
+ PFN_vkCmdPipelineBarrier2KHR vkCmdPipelineBarrier2KHR = 0;
+ PFN_vkCmdWriteTimestamp2KHR vkCmdWriteTimestamp2KHR = 0;
+ PFN_vkQueueSubmit2KHR vkQueueSubmit2KHR = 0;
+ PFN_vkCmdWriteBufferMarker2AMD vkCmdWriteBufferMarker2AMD = 0;
+ PFN_vkGetQueueCheckpointData2NV vkGetQueueCheckpointData2NV = 0;
+
+ //=== VK_NV_fragment_shading_rate_enums ===
+ PFN_vkCmdSetFragmentShadingRateEnumNV vkCmdSetFragmentShadingRateEnumNV = 0;
+
+ //=== VK_EXT_mesh_shader ===
+ PFN_vkCmdDrawMeshTasksEXT vkCmdDrawMeshTasksEXT = 0;
+ PFN_vkCmdDrawMeshTasksIndirectEXT vkCmdDrawMeshTasksIndirectEXT = 0;
+ PFN_vkCmdDrawMeshTasksIndirectCountEXT vkCmdDrawMeshTasksIndirectCountEXT = 0;
+
+ //=== VK_KHR_copy_commands2 ===
+ PFN_vkCmdCopyBuffer2KHR vkCmdCopyBuffer2KHR = 0;
+ PFN_vkCmdCopyImage2KHR vkCmdCopyImage2KHR = 0;
+ PFN_vkCmdCopyBufferToImage2KHR vkCmdCopyBufferToImage2KHR = 0;
+ PFN_vkCmdCopyImageToBuffer2KHR vkCmdCopyImageToBuffer2KHR = 0;
+ PFN_vkCmdBlitImage2KHR vkCmdBlitImage2KHR = 0;
+ PFN_vkCmdResolveImage2KHR vkCmdResolveImage2KHR = 0;
+
+ //=== VK_EXT_image_compression_control ===
+ PFN_vkGetImageSubresourceLayout2EXT vkGetImageSubresourceLayout2EXT = 0;
+
+ //=== VK_EXT_device_fault ===
+ PFN_vkGetDeviceFaultInfoEXT vkGetDeviceFaultInfoEXT = 0;
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_NV_acquire_winrt_display ===
+ PFN_vkAcquireWinrtDisplayNV vkAcquireWinrtDisplayNV = 0;
+ PFN_vkGetWinrtDisplayNV vkGetWinrtDisplayNV = 0;
+#else
+ PFN_dummy vkAcquireWinrtDisplayNV_placeholder = 0;
+ PFN_dummy vkGetWinrtDisplayNV_placeholder = 0;
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+#if defined( VK_USE_PLATFORM_DIRECTFB_EXT )
+ //=== VK_EXT_directfb_surface ===
+ PFN_vkCreateDirectFBSurfaceEXT vkCreateDirectFBSurfaceEXT = 0;
+ PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT vkGetPhysicalDeviceDirectFBPresentationSupportEXT = 0;
+#else
+ PFN_dummy vkCreateDirectFBSurfaceEXT_placeholder = 0;
+ PFN_dummy vkGetPhysicalDeviceDirectFBPresentationSupportEXT_placeholder = 0;
+#endif /*VK_USE_PLATFORM_DIRECTFB_EXT*/
+
+ //=== VK_KHR_ray_tracing_pipeline ===
+ PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR = 0;
+ PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR = 0;
+ PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR = 0;
+ PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR vkGetRayTracingCaptureReplayShaderGroupHandlesKHR = 0;
+ PFN_vkCmdTraceRaysIndirectKHR vkCmdTraceRaysIndirectKHR = 0;
+ PFN_vkGetRayTracingShaderGroupStackSizeKHR vkGetRayTracingShaderGroupStackSizeKHR = 0;
+ PFN_vkCmdSetRayTracingPipelineStackSizeKHR vkCmdSetRayTracingPipelineStackSizeKHR = 0;
+
+ //=== VK_EXT_vertex_input_dynamic_state ===
+ PFN_vkCmdSetVertexInputEXT vkCmdSetVertexInputEXT = 0;
+
+#if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_external_memory ===
+ PFN_vkGetMemoryZirconHandleFUCHSIA vkGetMemoryZirconHandleFUCHSIA = 0;
+ PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA vkGetMemoryZirconHandlePropertiesFUCHSIA = 0;
+#else
+ PFN_dummy vkGetMemoryZirconHandleFUCHSIA_placeholder = 0;
+ PFN_dummy vkGetMemoryZirconHandlePropertiesFUCHSIA_placeholder = 0;
+#endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+#if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_external_semaphore ===
+ PFN_vkImportSemaphoreZirconHandleFUCHSIA vkImportSemaphoreZirconHandleFUCHSIA = 0;
+ PFN_vkGetSemaphoreZirconHandleFUCHSIA vkGetSemaphoreZirconHandleFUCHSIA = 0;
+#else
+ PFN_dummy vkImportSemaphoreZirconHandleFUCHSIA_placeholder = 0;
+ PFN_dummy vkGetSemaphoreZirconHandleFUCHSIA_placeholder = 0;
+#endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+#if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_buffer_collection ===
+ PFN_vkCreateBufferCollectionFUCHSIA vkCreateBufferCollectionFUCHSIA = 0;
+ PFN_vkSetBufferCollectionImageConstraintsFUCHSIA vkSetBufferCollectionImageConstraintsFUCHSIA = 0;
+ PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA vkSetBufferCollectionBufferConstraintsFUCHSIA = 0;
+ PFN_vkDestroyBufferCollectionFUCHSIA vkDestroyBufferCollectionFUCHSIA = 0;
+ PFN_vkGetBufferCollectionPropertiesFUCHSIA vkGetBufferCollectionPropertiesFUCHSIA = 0;
+#else
+ PFN_dummy vkCreateBufferCollectionFUCHSIA_placeholder = 0;
+ PFN_dummy vkSetBufferCollectionImageConstraintsFUCHSIA_placeholder = 0;
+ PFN_dummy vkSetBufferCollectionBufferConstraintsFUCHSIA_placeholder = 0;
+ PFN_dummy vkDestroyBufferCollectionFUCHSIA_placeholder = 0;
+ PFN_dummy vkGetBufferCollectionPropertiesFUCHSIA_placeholder = 0;
+#endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+ //=== VK_HUAWEI_subpass_shading ===
+ PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = 0;
+ PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI = 0;
+
+ //=== VK_HUAWEI_invocation_mask ===
+ PFN_vkCmdBindInvocationMaskHUAWEI vkCmdBindInvocationMaskHUAWEI = 0;
+
+ //=== VK_NV_external_memory_rdma ===
+ PFN_vkGetMemoryRemoteAddressNV vkGetMemoryRemoteAddressNV = 0;
+
+ //=== VK_EXT_pipeline_properties ===
+ PFN_vkGetPipelinePropertiesEXT vkGetPipelinePropertiesEXT = 0;
+
+ //=== VK_EXT_extended_dynamic_state2 ===
+ PFN_vkCmdSetPatchControlPointsEXT vkCmdSetPatchControlPointsEXT = 0;
+ PFN_vkCmdSetRasterizerDiscardEnableEXT vkCmdSetRasterizerDiscardEnableEXT = 0;
+ PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT = 0;
+ PFN_vkCmdSetLogicOpEXT vkCmdSetLogicOpEXT = 0;
+ PFN_vkCmdSetPrimitiveRestartEnableEXT vkCmdSetPrimitiveRestartEnableEXT = 0;
+
+#if defined( VK_USE_PLATFORM_SCREEN_QNX )
+ //=== VK_QNX_screen_surface ===
+ PFN_vkCreateScreenSurfaceQNX vkCreateScreenSurfaceQNX = 0;
+ PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX vkGetPhysicalDeviceScreenPresentationSupportQNX = 0;
+#else
+ PFN_dummy vkCreateScreenSurfaceQNX_placeholder = 0;
+ PFN_dummy vkGetPhysicalDeviceScreenPresentationSupportQNX_placeholder = 0;
+#endif /*VK_USE_PLATFORM_SCREEN_QNX*/
+
+ //=== VK_EXT_color_write_enable ===
+ PFN_vkCmdSetColorWriteEnableEXT vkCmdSetColorWriteEnableEXT = 0;
+
+ //=== VK_KHR_ray_tracing_maintenance1 ===
+ PFN_vkCmdTraceRaysIndirect2KHR vkCmdTraceRaysIndirect2KHR = 0;
+
+ //=== VK_EXT_multi_draw ===
+ PFN_vkCmdDrawMultiEXT vkCmdDrawMultiEXT = 0;
+ PFN_vkCmdDrawMultiIndexedEXT vkCmdDrawMultiIndexedEXT = 0;
+
+ //=== VK_EXT_opacity_micromap ===
+ PFN_vkCreateMicromapEXT vkCreateMicromapEXT = 0;
+ PFN_vkDestroyMicromapEXT vkDestroyMicromapEXT = 0;
+ PFN_vkCmdBuildMicromapsEXT vkCmdBuildMicromapsEXT = 0;
+ PFN_vkBuildMicromapsEXT vkBuildMicromapsEXT = 0;
+ PFN_vkCopyMicromapEXT vkCopyMicromapEXT = 0;
+ PFN_vkCopyMicromapToMemoryEXT vkCopyMicromapToMemoryEXT = 0;
+ PFN_vkCopyMemoryToMicromapEXT vkCopyMemoryToMicromapEXT = 0;
+ PFN_vkWriteMicromapsPropertiesEXT vkWriteMicromapsPropertiesEXT = 0;
+ PFN_vkCmdCopyMicromapEXT vkCmdCopyMicromapEXT = 0;
+ PFN_vkCmdCopyMicromapToMemoryEXT vkCmdCopyMicromapToMemoryEXT = 0;
+ PFN_vkCmdCopyMemoryToMicromapEXT vkCmdCopyMemoryToMicromapEXT = 0;
+ PFN_vkCmdWriteMicromapsPropertiesEXT vkCmdWriteMicromapsPropertiesEXT = 0;
+ PFN_vkGetDeviceMicromapCompatibilityEXT vkGetDeviceMicromapCompatibilityEXT = 0;
+ PFN_vkGetMicromapBuildSizesEXT vkGetMicromapBuildSizesEXT = 0;
+
+ //=== VK_EXT_pageable_device_local_memory ===
+ PFN_vkSetDeviceMemoryPriorityEXT vkSetDeviceMemoryPriorityEXT = 0;
+
+ //=== VK_KHR_maintenance4 ===
+ PFN_vkGetDeviceBufferMemoryRequirementsKHR vkGetDeviceBufferMemoryRequirementsKHR = 0;
+ PFN_vkGetDeviceImageMemoryRequirementsKHR vkGetDeviceImageMemoryRequirementsKHR = 0;
+ PFN_vkGetDeviceImageSparseMemoryRequirementsKHR vkGetDeviceImageSparseMemoryRequirementsKHR = 0;
+
+ //=== VK_VALVE_descriptor_set_host_mapping ===
+ PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE vkGetDescriptorSetLayoutHostMappingInfoVALVE = 0;
+ PFN_vkGetDescriptorSetHostMappingVALVE vkGetDescriptorSetHostMappingVALVE = 0;
+
+ //=== VK_EXT_extended_dynamic_state3 ===
+ PFN_vkCmdSetTessellationDomainOriginEXT vkCmdSetTessellationDomainOriginEXT = 0;
+ PFN_vkCmdSetDepthClampEnableEXT vkCmdSetDepthClampEnableEXT = 0;
+ PFN_vkCmdSetPolygonModeEXT vkCmdSetPolygonModeEXT = 0;
+ PFN_vkCmdSetRasterizationSamplesEXT vkCmdSetRasterizationSamplesEXT = 0;
+ PFN_vkCmdSetSampleMaskEXT vkCmdSetSampleMaskEXT = 0;
+ PFN_vkCmdSetAlphaToCoverageEnableEXT vkCmdSetAlphaToCoverageEnableEXT = 0;
+ PFN_vkCmdSetAlphaToOneEnableEXT vkCmdSetAlphaToOneEnableEXT = 0;
+ PFN_vkCmdSetLogicOpEnableEXT vkCmdSetLogicOpEnableEXT = 0;
+ PFN_vkCmdSetColorBlendEnableEXT vkCmdSetColorBlendEnableEXT = 0;
+ PFN_vkCmdSetColorBlendEquationEXT vkCmdSetColorBlendEquationEXT = 0;
+ PFN_vkCmdSetColorWriteMaskEXT vkCmdSetColorWriteMaskEXT = 0;
+ PFN_vkCmdSetRasterizationStreamEXT vkCmdSetRasterizationStreamEXT = 0;
+ PFN_vkCmdSetConservativeRasterizationModeEXT vkCmdSetConservativeRasterizationModeEXT = 0;
+ PFN_vkCmdSetExtraPrimitiveOverestimationSizeEXT vkCmdSetExtraPrimitiveOverestimationSizeEXT = 0;
+ PFN_vkCmdSetDepthClipEnableEXT vkCmdSetDepthClipEnableEXT = 0;
+ PFN_vkCmdSetSampleLocationsEnableEXT vkCmdSetSampleLocationsEnableEXT = 0;
+ PFN_vkCmdSetColorBlendAdvancedEXT vkCmdSetColorBlendAdvancedEXT = 0;
+ PFN_vkCmdSetProvokingVertexModeEXT vkCmdSetProvokingVertexModeEXT = 0;
+ PFN_vkCmdSetLineRasterizationModeEXT vkCmdSetLineRasterizationModeEXT = 0;
+ PFN_vkCmdSetLineStippleEnableEXT vkCmdSetLineStippleEnableEXT = 0;
+ PFN_vkCmdSetDepthClipNegativeOneToOneEXT vkCmdSetDepthClipNegativeOneToOneEXT = 0;
+ PFN_vkCmdSetViewportWScalingEnableNV vkCmdSetViewportWScalingEnableNV = 0;
+ PFN_vkCmdSetViewportSwizzleNV vkCmdSetViewportSwizzleNV = 0;
+ PFN_vkCmdSetCoverageToColorEnableNV vkCmdSetCoverageToColorEnableNV = 0;
+ PFN_vkCmdSetCoverageToColorLocationNV vkCmdSetCoverageToColorLocationNV = 0;
+ PFN_vkCmdSetCoverageModulationModeNV vkCmdSetCoverageModulationModeNV = 0;
+ PFN_vkCmdSetCoverageModulationTableEnableNV vkCmdSetCoverageModulationTableEnableNV = 0;
+ PFN_vkCmdSetCoverageModulationTableNV vkCmdSetCoverageModulationTableNV = 0;
+ PFN_vkCmdSetShadingRateImageEnableNV vkCmdSetShadingRateImageEnableNV = 0;
+ PFN_vkCmdSetRepresentativeFragmentTestEnableNV vkCmdSetRepresentativeFragmentTestEnableNV = 0;
+ PFN_vkCmdSetCoverageReductionModeNV vkCmdSetCoverageReductionModeNV = 0;
+
+ //=== VK_EXT_shader_module_identifier ===
+ PFN_vkGetShaderModuleIdentifierEXT vkGetShaderModuleIdentifierEXT = 0;
+ PFN_vkGetShaderModuleCreateInfoIdentifierEXT vkGetShaderModuleCreateInfoIdentifierEXT = 0;
+
+ //=== VK_NV_optical_flow ===
+ PFN_vkGetPhysicalDeviceOpticalFlowImageFormatsNV vkGetPhysicalDeviceOpticalFlowImageFormatsNV = 0;
+ PFN_vkCreateOpticalFlowSessionNV vkCreateOpticalFlowSessionNV = 0;
+ PFN_vkDestroyOpticalFlowSessionNV vkDestroyOpticalFlowSessionNV = 0;
+ PFN_vkBindOpticalFlowSessionImageNV vkBindOpticalFlowSessionImageNV = 0;
+ PFN_vkCmdOpticalFlowExecuteNV vkCmdOpticalFlowExecuteNV = 0;
+
+ //=== VK_QCOM_tile_properties ===
+ PFN_vkGetFramebufferTilePropertiesQCOM vkGetFramebufferTilePropertiesQCOM = 0;
+ PFN_vkGetDynamicRenderingTilePropertiesQCOM vkGetDynamicRenderingTilePropertiesQCOM = 0;
+
+ public:
+ DispatchLoaderDynamic() VULKAN_HPP_NOEXCEPT = default;
+ DispatchLoaderDynamic( DispatchLoaderDynamic const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+
+#if !defined( VK_NO_PROTOTYPES )
+ // This interface is designed to be used for per-device function pointers in combination with a linked vulkan library.
+ template <typename DynamicLoader>
+ void init( VULKAN_HPP_NAMESPACE::Instance const & instance, VULKAN_HPP_NAMESPACE::Device const & device, DynamicLoader const & dl ) VULKAN_HPP_NOEXCEPT
+ {
+ PFN_vkGetInstanceProcAddr getInstanceProcAddr = dl.template getProcAddress<PFN_vkGetInstanceProcAddr>( "vkGetInstanceProcAddr" );
+ PFN_vkGetDeviceProcAddr getDeviceProcAddr = dl.template getProcAddress<PFN_vkGetDeviceProcAddr>( "vkGetDeviceProcAddr" );
+ init( static_cast<VkInstance>( instance ), getInstanceProcAddr, static_cast<VkDevice>( device ), device ? getDeviceProcAddr : nullptr );
+ }
+
+ // This interface is designed to be used for per-device function pointers in combination with a linked vulkan library.
+ template <typename DynamicLoader
+# if VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL
+ = VULKAN_HPP_NAMESPACE::DynamicLoader
+# endif
+ >
+ void init( VULKAN_HPP_NAMESPACE::Instance const & instance, VULKAN_HPP_NAMESPACE::Device const & device ) VULKAN_HPP_NOEXCEPT
+ {
+ static DynamicLoader dl;
+ init( instance, device, dl );
+ }
+#endif // !defined( VK_NO_PROTOTYPES )
+
+ DispatchLoaderDynamic( PFN_vkGetInstanceProcAddr getInstanceProcAddr ) VULKAN_HPP_NOEXCEPT
+ {
+ init( getInstanceProcAddr );
+ }
+
+ void init( PFN_vkGetInstanceProcAddr getInstanceProcAddr ) VULKAN_HPP_NOEXCEPT
+ {
+ VULKAN_HPP_ASSERT( getInstanceProcAddr );
+
+ vkGetInstanceProcAddr = getInstanceProcAddr;
+
+ //=== VK_VERSION_1_0 ===
+ vkCreateInstance = PFN_vkCreateInstance( vkGetInstanceProcAddr( NULL, "vkCreateInstance" ) );
+ vkEnumerateInstanceExtensionProperties =
+ PFN_vkEnumerateInstanceExtensionProperties( vkGetInstanceProcAddr( NULL, "vkEnumerateInstanceExtensionProperties" ) );
+ vkEnumerateInstanceLayerProperties = PFN_vkEnumerateInstanceLayerProperties( vkGetInstanceProcAddr( NULL, "vkEnumerateInstanceLayerProperties" ) );
+
+ //=== VK_VERSION_1_1 ===
+ vkEnumerateInstanceVersion = PFN_vkEnumerateInstanceVersion( vkGetInstanceProcAddr( NULL, "vkEnumerateInstanceVersion" ) );
+ }
+
+ // This interface does not require a linked vulkan library.
+ DispatchLoaderDynamic( VkInstance instance,
+ PFN_vkGetInstanceProcAddr getInstanceProcAddr,
+ VkDevice device = {},
+ PFN_vkGetDeviceProcAddr getDeviceProcAddr = nullptr ) VULKAN_HPP_NOEXCEPT
+ {
+ init( instance, getInstanceProcAddr, device, getDeviceProcAddr );
+ }
+
+ // This interface does not require a linked vulkan library.
+ void init( VkInstance instance,
+ PFN_vkGetInstanceProcAddr getInstanceProcAddr,
+ VkDevice device = {},
+ PFN_vkGetDeviceProcAddr /*getDeviceProcAddr*/ = nullptr ) VULKAN_HPP_NOEXCEPT
+ {
+ VULKAN_HPP_ASSERT( instance && getInstanceProcAddr );
+ vkGetInstanceProcAddr = getInstanceProcAddr;
+ init( VULKAN_HPP_NAMESPACE::Instance( instance ) );
+ if ( device )
+ {
+ init( VULKAN_HPP_NAMESPACE::Device( device ) );
+ }
+ }
+
+ void init( VULKAN_HPP_NAMESPACE::Instance instanceCpp ) VULKAN_HPP_NOEXCEPT
+ {
+ VkInstance instance = static_cast<VkInstance>( instanceCpp );
+
+ //=== VK_VERSION_1_0 ===
+ vkDestroyInstance = PFN_vkDestroyInstance( vkGetInstanceProcAddr( instance, "vkDestroyInstance" ) );
+ vkEnumeratePhysicalDevices = PFN_vkEnumeratePhysicalDevices( vkGetInstanceProcAddr( instance, "vkEnumeratePhysicalDevices" ) );
+ vkGetPhysicalDeviceFeatures = PFN_vkGetPhysicalDeviceFeatures( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceFeatures" ) );
+ vkGetPhysicalDeviceFormatProperties = PFN_vkGetPhysicalDeviceFormatProperties( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceFormatProperties" ) );
+ vkGetPhysicalDeviceImageFormatProperties =
+ PFN_vkGetPhysicalDeviceImageFormatProperties( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceImageFormatProperties" ) );
+ vkGetPhysicalDeviceProperties = PFN_vkGetPhysicalDeviceProperties( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceProperties" ) );
+ vkGetPhysicalDeviceQueueFamilyProperties =
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceQueueFamilyProperties" ) );
+ vkGetPhysicalDeviceMemoryProperties = PFN_vkGetPhysicalDeviceMemoryProperties( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceMemoryProperties" ) );
+ vkGetDeviceProcAddr = PFN_vkGetDeviceProcAddr( vkGetInstanceProcAddr( instance, "vkGetDeviceProcAddr" ) );
+ vkCreateDevice = PFN_vkCreateDevice( vkGetInstanceProcAddr( instance, "vkCreateDevice" ) );
+ vkDestroyDevice = PFN_vkDestroyDevice( vkGetInstanceProcAddr( instance, "vkDestroyDevice" ) );
+ vkEnumerateDeviceExtensionProperties =
+ PFN_vkEnumerateDeviceExtensionProperties( vkGetInstanceProcAddr( instance, "vkEnumerateDeviceExtensionProperties" ) );
+ vkEnumerateDeviceLayerProperties = PFN_vkEnumerateDeviceLayerProperties( vkGetInstanceProcAddr( instance, "vkEnumerateDeviceLayerProperties" ) );
+ vkGetDeviceQueue = PFN_vkGetDeviceQueue( vkGetInstanceProcAddr( instance, "vkGetDeviceQueue" ) );
+ vkQueueSubmit = PFN_vkQueueSubmit( vkGetInstanceProcAddr( instance, "vkQueueSubmit" ) );
+ vkQueueWaitIdle = PFN_vkQueueWaitIdle( vkGetInstanceProcAddr( instance, "vkQueueWaitIdle" ) );
+ vkDeviceWaitIdle = PFN_vkDeviceWaitIdle( vkGetInstanceProcAddr( instance, "vkDeviceWaitIdle" ) );
+ vkAllocateMemory = PFN_vkAllocateMemory( vkGetInstanceProcAddr( instance, "vkAllocateMemory" ) );
+ vkFreeMemory = PFN_vkFreeMemory( vkGetInstanceProcAddr( instance, "vkFreeMemory" ) );
+ vkMapMemory = PFN_vkMapMemory( vkGetInstanceProcAddr( instance, "vkMapMemory" ) );
+ vkUnmapMemory = PFN_vkUnmapMemory( vkGetInstanceProcAddr( instance, "vkUnmapMemory" ) );
+ vkFlushMappedMemoryRanges = PFN_vkFlushMappedMemoryRanges( vkGetInstanceProcAddr( instance, "vkFlushMappedMemoryRanges" ) );
+ vkInvalidateMappedMemoryRanges = PFN_vkInvalidateMappedMemoryRanges( vkGetInstanceProcAddr( instance, "vkInvalidateMappedMemoryRanges" ) );
+ vkGetDeviceMemoryCommitment = PFN_vkGetDeviceMemoryCommitment( vkGetInstanceProcAddr( instance, "vkGetDeviceMemoryCommitment" ) );
+ vkBindBufferMemory = PFN_vkBindBufferMemory( vkGetInstanceProcAddr( instance, "vkBindBufferMemory" ) );
+ vkBindImageMemory = PFN_vkBindImageMemory( vkGetInstanceProcAddr( instance, "vkBindImageMemory" ) );
+ vkGetBufferMemoryRequirements = PFN_vkGetBufferMemoryRequirements( vkGetInstanceProcAddr( instance, "vkGetBufferMemoryRequirements" ) );
+ vkGetImageMemoryRequirements = PFN_vkGetImageMemoryRequirements( vkGetInstanceProcAddr( instance, "vkGetImageMemoryRequirements" ) );
+ vkGetImageSparseMemoryRequirements = PFN_vkGetImageSparseMemoryRequirements( vkGetInstanceProcAddr( instance, "vkGetImageSparseMemoryRequirements" ) );
+ vkGetPhysicalDeviceSparseImageFormatProperties =
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSparseImageFormatProperties" ) );
+ vkQueueBindSparse = PFN_vkQueueBindSparse( vkGetInstanceProcAddr( instance, "vkQueueBindSparse" ) );
+ vkCreateFence = PFN_vkCreateFence( vkGetInstanceProcAddr( instance, "vkCreateFence" ) );
+ vkDestroyFence = PFN_vkDestroyFence( vkGetInstanceProcAddr( instance, "vkDestroyFence" ) );
+ vkResetFences = PFN_vkResetFences( vkGetInstanceProcAddr( instance, "vkResetFences" ) );
+ vkGetFenceStatus = PFN_vkGetFenceStatus( vkGetInstanceProcAddr( instance, "vkGetFenceStatus" ) );
+ vkWaitForFences = PFN_vkWaitForFences( vkGetInstanceProcAddr( instance, "vkWaitForFences" ) );
+ vkCreateSemaphore = PFN_vkCreateSemaphore( vkGetInstanceProcAddr( instance, "vkCreateSemaphore" ) );
+ vkDestroySemaphore = PFN_vkDestroySemaphore( vkGetInstanceProcAddr( instance, "vkDestroySemaphore" ) );
+ vkCreateEvent = PFN_vkCreateEvent( vkGetInstanceProcAddr( instance, "vkCreateEvent" ) );
+ vkDestroyEvent = PFN_vkDestroyEvent( vkGetInstanceProcAddr( instance, "vkDestroyEvent" ) );
+ vkGetEventStatus = PFN_vkGetEventStatus( vkGetInstanceProcAddr( instance, "vkGetEventStatus" ) );
+ vkSetEvent = PFN_vkSetEvent( vkGetInstanceProcAddr( instance, "vkSetEvent" ) );
+ vkResetEvent = PFN_vkResetEvent( vkGetInstanceProcAddr( instance, "vkResetEvent" ) );
+ vkCreateQueryPool = PFN_vkCreateQueryPool( vkGetInstanceProcAddr( instance, "vkCreateQueryPool" ) );
+ vkDestroyQueryPool = PFN_vkDestroyQueryPool( vkGetInstanceProcAddr( instance, "vkDestroyQueryPool" ) );
+ vkGetQueryPoolResults = PFN_vkGetQueryPoolResults( vkGetInstanceProcAddr( instance, "vkGetQueryPoolResults" ) );
+ vkCreateBuffer = PFN_vkCreateBuffer( vkGetInstanceProcAddr( instance, "vkCreateBuffer" ) );
+ vkDestroyBuffer = PFN_vkDestroyBuffer( vkGetInstanceProcAddr( instance, "vkDestroyBuffer" ) );
+ vkCreateBufferView = PFN_vkCreateBufferView( vkGetInstanceProcAddr( instance, "vkCreateBufferView" ) );
+ vkDestroyBufferView = PFN_vkDestroyBufferView( vkGetInstanceProcAddr( instance, "vkDestroyBufferView" ) );
+ vkCreateImage = PFN_vkCreateImage( vkGetInstanceProcAddr( instance, "vkCreateImage" ) );
+ vkDestroyImage = PFN_vkDestroyImage( vkGetInstanceProcAddr( instance, "vkDestroyImage" ) );
+ vkGetImageSubresourceLayout = PFN_vkGetImageSubresourceLayout( vkGetInstanceProcAddr( instance, "vkGetImageSubresourceLayout" ) );
+ vkCreateImageView = PFN_vkCreateImageView( vkGetInstanceProcAddr( instance, "vkCreateImageView" ) );
+ vkDestroyImageView = PFN_vkDestroyImageView( vkGetInstanceProcAddr( instance, "vkDestroyImageView" ) );
+ vkCreateShaderModule = PFN_vkCreateShaderModule( vkGetInstanceProcAddr( instance, "vkCreateShaderModule" ) );
+ vkDestroyShaderModule = PFN_vkDestroyShaderModule( vkGetInstanceProcAddr( instance, "vkDestroyShaderModule" ) );
+ vkCreatePipelineCache = PFN_vkCreatePipelineCache( vkGetInstanceProcAddr( instance, "vkCreatePipelineCache" ) );
+ vkDestroyPipelineCache = PFN_vkDestroyPipelineCache( vkGetInstanceProcAddr( instance, "vkDestroyPipelineCache" ) );
+ vkGetPipelineCacheData = PFN_vkGetPipelineCacheData( vkGetInstanceProcAddr( instance, "vkGetPipelineCacheData" ) );
+ vkMergePipelineCaches = PFN_vkMergePipelineCaches( vkGetInstanceProcAddr( instance, "vkMergePipelineCaches" ) );
+ vkCreateGraphicsPipelines = PFN_vkCreateGraphicsPipelines( vkGetInstanceProcAddr( instance, "vkCreateGraphicsPipelines" ) );
+ vkCreateComputePipelines = PFN_vkCreateComputePipelines( vkGetInstanceProcAddr( instance, "vkCreateComputePipelines" ) );
+ vkDestroyPipeline = PFN_vkDestroyPipeline( vkGetInstanceProcAddr( instance, "vkDestroyPipeline" ) );
+ vkCreatePipelineLayout = PFN_vkCreatePipelineLayout( vkGetInstanceProcAddr( instance, "vkCreatePipelineLayout" ) );
+ vkDestroyPipelineLayout = PFN_vkDestroyPipelineLayout( vkGetInstanceProcAddr( instance, "vkDestroyPipelineLayout" ) );
+ vkCreateSampler = PFN_vkCreateSampler( vkGetInstanceProcAddr( instance, "vkCreateSampler" ) );
+ vkDestroySampler = PFN_vkDestroySampler( vkGetInstanceProcAddr( instance, "vkDestroySampler" ) );
+ vkCreateDescriptorSetLayout = PFN_vkCreateDescriptorSetLayout( vkGetInstanceProcAddr( instance, "vkCreateDescriptorSetLayout" ) );
+ vkDestroyDescriptorSetLayout = PFN_vkDestroyDescriptorSetLayout( vkGetInstanceProcAddr( instance, "vkDestroyDescriptorSetLayout" ) );
+ vkCreateDescriptorPool = PFN_vkCreateDescriptorPool( vkGetInstanceProcAddr( instance, "vkCreateDescriptorPool" ) );
+ vkDestroyDescriptorPool = PFN_vkDestroyDescriptorPool( vkGetInstanceProcAddr( instance, "vkDestroyDescriptorPool" ) );
+ vkResetDescriptorPool = PFN_vkResetDescriptorPool( vkGetInstanceProcAddr( instance, "vkResetDescriptorPool" ) );
+ vkAllocateDescriptorSets = PFN_vkAllocateDescriptorSets( vkGetInstanceProcAddr( instance, "vkAllocateDescriptorSets" ) );
+ vkFreeDescriptorSets = PFN_vkFreeDescriptorSets( vkGetInstanceProcAddr( instance, "vkFreeDescriptorSets" ) );
+ vkUpdateDescriptorSets = PFN_vkUpdateDescriptorSets( vkGetInstanceProcAddr( instance, "vkUpdateDescriptorSets" ) );
+ vkCreateFramebuffer = PFN_vkCreateFramebuffer( vkGetInstanceProcAddr( instance, "vkCreateFramebuffer" ) );
+ vkDestroyFramebuffer = PFN_vkDestroyFramebuffer( vkGetInstanceProcAddr( instance, "vkDestroyFramebuffer" ) );
+ vkCreateRenderPass = PFN_vkCreateRenderPass( vkGetInstanceProcAddr( instance, "vkCreateRenderPass" ) );
+ vkDestroyRenderPass = PFN_vkDestroyRenderPass( vkGetInstanceProcAddr( instance, "vkDestroyRenderPass" ) );
+ vkGetRenderAreaGranularity = PFN_vkGetRenderAreaGranularity( vkGetInstanceProcAddr( instance, "vkGetRenderAreaGranularity" ) );
+ vkCreateCommandPool = PFN_vkCreateCommandPool( vkGetInstanceProcAddr( instance, "vkCreateCommandPool" ) );
+ vkDestroyCommandPool = PFN_vkDestroyCommandPool( vkGetInstanceProcAddr( instance, "vkDestroyCommandPool" ) );
+ vkResetCommandPool = PFN_vkResetCommandPool( vkGetInstanceProcAddr( instance, "vkResetCommandPool" ) );
+ vkAllocateCommandBuffers = PFN_vkAllocateCommandBuffers( vkGetInstanceProcAddr( instance, "vkAllocateCommandBuffers" ) );
+ vkFreeCommandBuffers = PFN_vkFreeCommandBuffers( vkGetInstanceProcAddr( instance, "vkFreeCommandBuffers" ) );
+ vkBeginCommandBuffer = PFN_vkBeginCommandBuffer( vkGetInstanceProcAddr( instance, "vkBeginCommandBuffer" ) );
+ vkEndCommandBuffer = PFN_vkEndCommandBuffer( vkGetInstanceProcAddr( instance, "vkEndCommandBuffer" ) );
+ vkResetCommandBuffer = PFN_vkResetCommandBuffer( vkGetInstanceProcAddr( instance, "vkResetCommandBuffer" ) );
+ vkCmdBindPipeline = PFN_vkCmdBindPipeline( vkGetInstanceProcAddr( instance, "vkCmdBindPipeline" ) );
+ vkCmdSetViewport = PFN_vkCmdSetViewport( vkGetInstanceProcAddr( instance, "vkCmdSetViewport" ) );
+ vkCmdSetScissor = PFN_vkCmdSetScissor( vkGetInstanceProcAddr( instance, "vkCmdSetScissor" ) );
+ vkCmdSetLineWidth = PFN_vkCmdSetLineWidth( vkGetInstanceProcAddr( instance, "vkCmdSetLineWidth" ) );
+ vkCmdSetDepthBias = PFN_vkCmdSetDepthBias( vkGetInstanceProcAddr( instance, "vkCmdSetDepthBias" ) );
+ vkCmdSetBlendConstants = PFN_vkCmdSetBlendConstants( vkGetInstanceProcAddr( instance, "vkCmdSetBlendConstants" ) );
+ vkCmdSetDepthBounds = PFN_vkCmdSetDepthBounds( vkGetInstanceProcAddr( instance, "vkCmdSetDepthBounds" ) );
+ vkCmdSetStencilCompareMask = PFN_vkCmdSetStencilCompareMask( vkGetInstanceProcAddr( instance, "vkCmdSetStencilCompareMask" ) );
+ vkCmdSetStencilWriteMask = PFN_vkCmdSetStencilWriteMask( vkGetInstanceProcAddr( instance, "vkCmdSetStencilWriteMask" ) );
+ vkCmdSetStencilReference = PFN_vkCmdSetStencilReference( vkGetInstanceProcAddr( instance, "vkCmdSetStencilReference" ) );
+ vkCmdBindDescriptorSets = PFN_vkCmdBindDescriptorSets( vkGetInstanceProcAddr( instance, "vkCmdBindDescriptorSets" ) );
+ vkCmdBindIndexBuffer = PFN_vkCmdBindIndexBuffer( vkGetInstanceProcAddr( instance, "vkCmdBindIndexBuffer" ) );
+ vkCmdBindVertexBuffers = PFN_vkCmdBindVertexBuffers( vkGetInstanceProcAddr( instance, "vkCmdBindVertexBuffers" ) );
+ vkCmdDraw = PFN_vkCmdDraw( vkGetInstanceProcAddr( instance, "vkCmdDraw" ) );
+ vkCmdDrawIndexed = PFN_vkCmdDrawIndexed( vkGetInstanceProcAddr( instance, "vkCmdDrawIndexed" ) );
+ vkCmdDrawIndirect = PFN_vkCmdDrawIndirect( vkGetInstanceProcAddr( instance, "vkCmdDrawIndirect" ) );
+ vkCmdDrawIndexedIndirect = PFN_vkCmdDrawIndexedIndirect( vkGetInstanceProcAddr( instance, "vkCmdDrawIndexedIndirect" ) );
+ vkCmdDispatch = PFN_vkCmdDispatch( vkGetInstanceProcAddr( instance, "vkCmdDispatch" ) );
+ vkCmdDispatchIndirect = PFN_vkCmdDispatchIndirect( vkGetInstanceProcAddr( instance, "vkCmdDispatchIndirect" ) );
+ vkCmdCopyBuffer = PFN_vkCmdCopyBuffer( vkGetInstanceProcAddr( instance, "vkCmdCopyBuffer" ) );
+ vkCmdCopyImage = PFN_vkCmdCopyImage( vkGetInstanceProcAddr( instance, "vkCmdCopyImage" ) );
+ vkCmdBlitImage = PFN_vkCmdBlitImage( vkGetInstanceProcAddr( instance, "vkCmdBlitImage" ) );
+ vkCmdCopyBufferToImage = PFN_vkCmdCopyBufferToImage( vkGetInstanceProcAddr( instance, "vkCmdCopyBufferToImage" ) );
+ vkCmdCopyImageToBuffer = PFN_vkCmdCopyImageToBuffer( vkGetInstanceProcAddr( instance, "vkCmdCopyImageToBuffer" ) );
+ vkCmdUpdateBuffer = PFN_vkCmdUpdateBuffer( vkGetInstanceProcAddr( instance, "vkCmdUpdateBuffer" ) );
+ vkCmdFillBuffer = PFN_vkCmdFillBuffer( vkGetInstanceProcAddr( instance, "vkCmdFillBuffer" ) );
+ vkCmdClearColorImage = PFN_vkCmdClearColorImage( vkGetInstanceProcAddr( instance, "vkCmdClearColorImage" ) );
+ vkCmdClearDepthStencilImage = PFN_vkCmdClearDepthStencilImage( vkGetInstanceProcAddr( instance, "vkCmdClearDepthStencilImage" ) );
+ vkCmdClearAttachments = PFN_vkCmdClearAttachments( vkGetInstanceProcAddr( instance, "vkCmdClearAttachments" ) );
+ vkCmdResolveImage = PFN_vkCmdResolveImage( vkGetInstanceProcAddr( instance, "vkCmdResolveImage" ) );
+ vkCmdSetEvent = PFN_vkCmdSetEvent( vkGetInstanceProcAddr( instance, "vkCmdSetEvent" ) );
+ vkCmdResetEvent = PFN_vkCmdResetEvent( vkGetInstanceProcAddr( instance, "vkCmdResetEvent" ) );
+ vkCmdWaitEvents = PFN_vkCmdWaitEvents( vkGetInstanceProcAddr( instance, "vkCmdWaitEvents" ) );
+ vkCmdPipelineBarrier = PFN_vkCmdPipelineBarrier( vkGetInstanceProcAddr( instance, "vkCmdPipelineBarrier" ) );
+ vkCmdBeginQuery = PFN_vkCmdBeginQuery( vkGetInstanceProcAddr( instance, "vkCmdBeginQuery" ) );
+ vkCmdEndQuery = PFN_vkCmdEndQuery( vkGetInstanceProcAddr( instance, "vkCmdEndQuery" ) );
+ vkCmdResetQueryPool = PFN_vkCmdResetQueryPool( vkGetInstanceProcAddr( instance, "vkCmdResetQueryPool" ) );
+ vkCmdWriteTimestamp = PFN_vkCmdWriteTimestamp( vkGetInstanceProcAddr( instance, "vkCmdWriteTimestamp" ) );
+ vkCmdCopyQueryPoolResults = PFN_vkCmdCopyQueryPoolResults( vkGetInstanceProcAddr( instance, "vkCmdCopyQueryPoolResults" ) );
+ vkCmdPushConstants = PFN_vkCmdPushConstants( vkGetInstanceProcAddr( instance, "vkCmdPushConstants" ) );
+ vkCmdBeginRenderPass = PFN_vkCmdBeginRenderPass( vkGetInstanceProcAddr( instance, "vkCmdBeginRenderPass" ) );
+ vkCmdNextSubpass = PFN_vkCmdNextSubpass( vkGetInstanceProcAddr( instance, "vkCmdNextSubpass" ) );
+ vkCmdEndRenderPass = PFN_vkCmdEndRenderPass( vkGetInstanceProcAddr( instance, "vkCmdEndRenderPass" ) );
+ vkCmdExecuteCommands = PFN_vkCmdExecuteCommands( vkGetInstanceProcAddr( instance, "vkCmdExecuteCommands" ) );
+
+ //=== VK_VERSION_1_1 ===
+ vkBindBufferMemory2 = PFN_vkBindBufferMemory2( vkGetInstanceProcAddr( instance, "vkBindBufferMemory2" ) );
+ vkBindImageMemory2 = PFN_vkBindImageMemory2( vkGetInstanceProcAddr( instance, "vkBindImageMemory2" ) );
+ vkGetDeviceGroupPeerMemoryFeatures = PFN_vkGetDeviceGroupPeerMemoryFeatures( vkGetInstanceProcAddr( instance, "vkGetDeviceGroupPeerMemoryFeatures" ) );
+ vkCmdSetDeviceMask = PFN_vkCmdSetDeviceMask( vkGetInstanceProcAddr( instance, "vkCmdSetDeviceMask" ) );
+ vkCmdDispatchBase = PFN_vkCmdDispatchBase( vkGetInstanceProcAddr( instance, "vkCmdDispatchBase" ) );
+ vkEnumeratePhysicalDeviceGroups = PFN_vkEnumeratePhysicalDeviceGroups( vkGetInstanceProcAddr( instance, "vkEnumeratePhysicalDeviceGroups" ) );
+ vkGetImageMemoryRequirements2 = PFN_vkGetImageMemoryRequirements2( vkGetInstanceProcAddr( instance, "vkGetImageMemoryRequirements2" ) );
+ vkGetBufferMemoryRequirements2 = PFN_vkGetBufferMemoryRequirements2( vkGetInstanceProcAddr( instance, "vkGetBufferMemoryRequirements2" ) );
+ vkGetImageSparseMemoryRequirements2 = PFN_vkGetImageSparseMemoryRequirements2( vkGetInstanceProcAddr( instance, "vkGetImageSparseMemoryRequirements2" ) );
+ vkGetPhysicalDeviceFeatures2 = PFN_vkGetPhysicalDeviceFeatures2( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceFeatures2" ) );
+ vkGetPhysicalDeviceProperties2 = PFN_vkGetPhysicalDeviceProperties2( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceProperties2" ) );
+ vkGetPhysicalDeviceFormatProperties2 =
+ PFN_vkGetPhysicalDeviceFormatProperties2( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceFormatProperties2" ) );
+ vkGetPhysicalDeviceImageFormatProperties2 =
+ PFN_vkGetPhysicalDeviceImageFormatProperties2( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceImageFormatProperties2" ) );
+ vkGetPhysicalDeviceQueueFamilyProperties2 =
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties2( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceQueueFamilyProperties2" ) );
+ vkGetPhysicalDeviceMemoryProperties2 =
+ PFN_vkGetPhysicalDeviceMemoryProperties2( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceMemoryProperties2" ) );
+ vkGetPhysicalDeviceSparseImageFormatProperties2 =
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties2( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSparseImageFormatProperties2" ) );
+ vkTrimCommandPool = PFN_vkTrimCommandPool( vkGetInstanceProcAddr( instance, "vkTrimCommandPool" ) );
+ vkGetDeviceQueue2 = PFN_vkGetDeviceQueue2( vkGetInstanceProcAddr( instance, "vkGetDeviceQueue2" ) );
+ vkCreateSamplerYcbcrConversion = PFN_vkCreateSamplerYcbcrConversion( vkGetInstanceProcAddr( instance, "vkCreateSamplerYcbcrConversion" ) );
+ vkDestroySamplerYcbcrConversion = PFN_vkDestroySamplerYcbcrConversion( vkGetInstanceProcAddr( instance, "vkDestroySamplerYcbcrConversion" ) );
+ vkCreateDescriptorUpdateTemplate = PFN_vkCreateDescriptorUpdateTemplate( vkGetInstanceProcAddr( instance, "vkCreateDescriptorUpdateTemplate" ) );
+ vkDestroyDescriptorUpdateTemplate = PFN_vkDestroyDescriptorUpdateTemplate( vkGetInstanceProcAddr( instance, "vkDestroyDescriptorUpdateTemplate" ) );
+ vkUpdateDescriptorSetWithTemplate = PFN_vkUpdateDescriptorSetWithTemplate( vkGetInstanceProcAddr( instance, "vkUpdateDescriptorSetWithTemplate" ) );
+ vkGetPhysicalDeviceExternalBufferProperties =
+ PFN_vkGetPhysicalDeviceExternalBufferProperties( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceExternalBufferProperties" ) );
+ vkGetPhysicalDeviceExternalFenceProperties =
+ PFN_vkGetPhysicalDeviceExternalFenceProperties( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceExternalFenceProperties" ) );
+ vkGetPhysicalDeviceExternalSemaphoreProperties =
+ PFN_vkGetPhysicalDeviceExternalSemaphoreProperties( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceExternalSemaphoreProperties" ) );
+ vkGetDescriptorSetLayoutSupport = PFN_vkGetDescriptorSetLayoutSupport( vkGetInstanceProcAddr( instance, "vkGetDescriptorSetLayoutSupport" ) );
+
+ //=== VK_VERSION_1_2 ===
+ vkCmdDrawIndirectCount = PFN_vkCmdDrawIndirectCount( vkGetInstanceProcAddr( instance, "vkCmdDrawIndirectCount" ) );
+ vkCmdDrawIndexedIndirectCount = PFN_vkCmdDrawIndexedIndirectCount( vkGetInstanceProcAddr( instance, "vkCmdDrawIndexedIndirectCount" ) );
+ vkCreateRenderPass2 = PFN_vkCreateRenderPass2( vkGetInstanceProcAddr( instance, "vkCreateRenderPass2" ) );
+ vkCmdBeginRenderPass2 = PFN_vkCmdBeginRenderPass2( vkGetInstanceProcAddr( instance, "vkCmdBeginRenderPass2" ) );
+ vkCmdNextSubpass2 = PFN_vkCmdNextSubpass2( vkGetInstanceProcAddr( instance, "vkCmdNextSubpass2" ) );
+ vkCmdEndRenderPass2 = PFN_vkCmdEndRenderPass2( vkGetInstanceProcAddr( instance, "vkCmdEndRenderPass2" ) );
+ vkResetQueryPool = PFN_vkResetQueryPool( vkGetInstanceProcAddr( instance, "vkResetQueryPool" ) );
+ vkGetSemaphoreCounterValue = PFN_vkGetSemaphoreCounterValue( vkGetInstanceProcAddr( instance, "vkGetSemaphoreCounterValue" ) );
+ vkWaitSemaphores = PFN_vkWaitSemaphores( vkGetInstanceProcAddr( instance, "vkWaitSemaphores" ) );
+ vkSignalSemaphore = PFN_vkSignalSemaphore( vkGetInstanceProcAddr( instance, "vkSignalSemaphore" ) );
+ vkGetBufferDeviceAddress = PFN_vkGetBufferDeviceAddress( vkGetInstanceProcAddr( instance, "vkGetBufferDeviceAddress" ) );
+ vkGetBufferOpaqueCaptureAddress = PFN_vkGetBufferOpaqueCaptureAddress( vkGetInstanceProcAddr( instance, "vkGetBufferOpaqueCaptureAddress" ) );
+ vkGetDeviceMemoryOpaqueCaptureAddress =
+ PFN_vkGetDeviceMemoryOpaqueCaptureAddress( vkGetInstanceProcAddr( instance, "vkGetDeviceMemoryOpaqueCaptureAddress" ) );
+
+ //=== VK_VERSION_1_3 ===
+ vkGetPhysicalDeviceToolProperties = PFN_vkGetPhysicalDeviceToolProperties( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceToolProperties" ) );
+ vkCreatePrivateDataSlot = PFN_vkCreatePrivateDataSlot( vkGetInstanceProcAddr( instance, "vkCreatePrivateDataSlot" ) );
+ vkDestroyPrivateDataSlot = PFN_vkDestroyPrivateDataSlot( vkGetInstanceProcAddr( instance, "vkDestroyPrivateDataSlot" ) );
+ vkSetPrivateData = PFN_vkSetPrivateData( vkGetInstanceProcAddr( instance, "vkSetPrivateData" ) );
+ vkGetPrivateData = PFN_vkGetPrivateData( vkGetInstanceProcAddr( instance, "vkGetPrivateData" ) );
+ vkCmdSetEvent2 = PFN_vkCmdSetEvent2( vkGetInstanceProcAddr( instance, "vkCmdSetEvent2" ) );
+ vkCmdResetEvent2 = PFN_vkCmdResetEvent2( vkGetInstanceProcAddr( instance, "vkCmdResetEvent2" ) );
+ vkCmdWaitEvents2 = PFN_vkCmdWaitEvents2( vkGetInstanceProcAddr( instance, "vkCmdWaitEvents2" ) );
+ vkCmdPipelineBarrier2 = PFN_vkCmdPipelineBarrier2( vkGetInstanceProcAddr( instance, "vkCmdPipelineBarrier2" ) );
+ vkCmdWriteTimestamp2 = PFN_vkCmdWriteTimestamp2( vkGetInstanceProcAddr( instance, "vkCmdWriteTimestamp2" ) );
+ vkQueueSubmit2 = PFN_vkQueueSubmit2( vkGetInstanceProcAddr( instance, "vkQueueSubmit2" ) );
+ vkCmdCopyBuffer2 = PFN_vkCmdCopyBuffer2( vkGetInstanceProcAddr( instance, "vkCmdCopyBuffer2" ) );
+ vkCmdCopyImage2 = PFN_vkCmdCopyImage2( vkGetInstanceProcAddr( instance, "vkCmdCopyImage2" ) );
+ vkCmdCopyBufferToImage2 = PFN_vkCmdCopyBufferToImage2( vkGetInstanceProcAddr( instance, "vkCmdCopyBufferToImage2" ) );
+ vkCmdCopyImageToBuffer2 = PFN_vkCmdCopyImageToBuffer2( vkGetInstanceProcAddr( instance, "vkCmdCopyImageToBuffer2" ) );
+ vkCmdBlitImage2 = PFN_vkCmdBlitImage2( vkGetInstanceProcAddr( instance, "vkCmdBlitImage2" ) );
+ vkCmdResolveImage2 = PFN_vkCmdResolveImage2( vkGetInstanceProcAddr( instance, "vkCmdResolveImage2" ) );
+ vkCmdBeginRendering = PFN_vkCmdBeginRendering( vkGetInstanceProcAddr( instance, "vkCmdBeginRendering" ) );
+ vkCmdEndRendering = PFN_vkCmdEndRendering( vkGetInstanceProcAddr( instance, "vkCmdEndRendering" ) );
+ vkCmdSetCullMode = PFN_vkCmdSetCullMode( vkGetInstanceProcAddr( instance, "vkCmdSetCullMode" ) );
+ vkCmdSetFrontFace = PFN_vkCmdSetFrontFace( vkGetInstanceProcAddr( instance, "vkCmdSetFrontFace" ) );
+ vkCmdSetPrimitiveTopology = PFN_vkCmdSetPrimitiveTopology( vkGetInstanceProcAddr( instance, "vkCmdSetPrimitiveTopology" ) );
+ vkCmdSetViewportWithCount = PFN_vkCmdSetViewportWithCount( vkGetInstanceProcAddr( instance, "vkCmdSetViewportWithCount" ) );
+ vkCmdSetScissorWithCount = PFN_vkCmdSetScissorWithCount( vkGetInstanceProcAddr( instance, "vkCmdSetScissorWithCount" ) );
+ vkCmdBindVertexBuffers2 = PFN_vkCmdBindVertexBuffers2( vkGetInstanceProcAddr( instance, "vkCmdBindVertexBuffers2" ) );
+ vkCmdSetDepthTestEnable = PFN_vkCmdSetDepthTestEnable( vkGetInstanceProcAddr( instance, "vkCmdSetDepthTestEnable" ) );
+ vkCmdSetDepthWriteEnable = PFN_vkCmdSetDepthWriteEnable( vkGetInstanceProcAddr( instance, "vkCmdSetDepthWriteEnable" ) );
+ vkCmdSetDepthCompareOp = PFN_vkCmdSetDepthCompareOp( vkGetInstanceProcAddr( instance, "vkCmdSetDepthCompareOp" ) );
+ vkCmdSetDepthBoundsTestEnable = PFN_vkCmdSetDepthBoundsTestEnable( vkGetInstanceProcAddr( instance, "vkCmdSetDepthBoundsTestEnable" ) );
+ vkCmdSetStencilTestEnable = PFN_vkCmdSetStencilTestEnable( vkGetInstanceProcAddr( instance, "vkCmdSetStencilTestEnable" ) );
+ vkCmdSetStencilOp = PFN_vkCmdSetStencilOp( vkGetInstanceProcAddr( instance, "vkCmdSetStencilOp" ) );
+ vkCmdSetRasterizerDiscardEnable = PFN_vkCmdSetRasterizerDiscardEnable( vkGetInstanceProcAddr( instance, "vkCmdSetRasterizerDiscardEnable" ) );
+ vkCmdSetDepthBiasEnable = PFN_vkCmdSetDepthBiasEnable( vkGetInstanceProcAddr( instance, "vkCmdSetDepthBiasEnable" ) );
+ vkCmdSetPrimitiveRestartEnable = PFN_vkCmdSetPrimitiveRestartEnable( vkGetInstanceProcAddr( instance, "vkCmdSetPrimitiveRestartEnable" ) );
+ vkGetDeviceBufferMemoryRequirements = PFN_vkGetDeviceBufferMemoryRequirements( vkGetInstanceProcAddr( instance, "vkGetDeviceBufferMemoryRequirements" ) );
+ vkGetDeviceImageMemoryRequirements = PFN_vkGetDeviceImageMemoryRequirements( vkGetInstanceProcAddr( instance, "vkGetDeviceImageMemoryRequirements" ) );
+ vkGetDeviceImageSparseMemoryRequirements =
+ PFN_vkGetDeviceImageSparseMemoryRequirements( vkGetInstanceProcAddr( instance, "vkGetDeviceImageSparseMemoryRequirements" ) );
+
+ //=== VK_KHR_surface ===
+ vkDestroySurfaceKHR = PFN_vkDestroySurfaceKHR( vkGetInstanceProcAddr( instance, "vkDestroySurfaceKHR" ) );
+ vkGetPhysicalDeviceSurfaceSupportKHR =
+ PFN_vkGetPhysicalDeviceSurfaceSupportKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSurfaceSupportKHR" ) );
+ vkGetPhysicalDeviceSurfaceCapabilitiesKHR =
+ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" ) );
+ vkGetPhysicalDeviceSurfaceFormatsKHR =
+ PFN_vkGetPhysicalDeviceSurfaceFormatsKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSurfaceFormatsKHR" ) );
+ vkGetPhysicalDeviceSurfacePresentModesKHR =
+ PFN_vkGetPhysicalDeviceSurfacePresentModesKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSurfacePresentModesKHR" ) );
+
+ //=== VK_KHR_swapchain ===
+ vkCreateSwapchainKHR = PFN_vkCreateSwapchainKHR( vkGetInstanceProcAddr( instance, "vkCreateSwapchainKHR" ) );
+ vkDestroySwapchainKHR = PFN_vkDestroySwapchainKHR( vkGetInstanceProcAddr( instance, "vkDestroySwapchainKHR" ) );
+ vkGetSwapchainImagesKHR = PFN_vkGetSwapchainImagesKHR( vkGetInstanceProcAddr( instance, "vkGetSwapchainImagesKHR" ) );
+ vkAcquireNextImageKHR = PFN_vkAcquireNextImageKHR( vkGetInstanceProcAddr( instance, "vkAcquireNextImageKHR" ) );
+ vkQueuePresentKHR = PFN_vkQueuePresentKHR( vkGetInstanceProcAddr( instance, "vkQueuePresentKHR" ) );
+ vkGetDeviceGroupPresentCapabilitiesKHR =
+ PFN_vkGetDeviceGroupPresentCapabilitiesKHR( vkGetInstanceProcAddr( instance, "vkGetDeviceGroupPresentCapabilitiesKHR" ) );
+ vkGetDeviceGroupSurfacePresentModesKHR =
+ PFN_vkGetDeviceGroupSurfacePresentModesKHR( vkGetInstanceProcAddr( instance, "vkGetDeviceGroupSurfacePresentModesKHR" ) );
+ vkGetPhysicalDevicePresentRectanglesKHR =
+ PFN_vkGetPhysicalDevicePresentRectanglesKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDevicePresentRectanglesKHR" ) );
+ vkAcquireNextImage2KHR = PFN_vkAcquireNextImage2KHR( vkGetInstanceProcAddr( instance, "vkAcquireNextImage2KHR" ) );
+
+ //=== VK_KHR_display ===
+ vkGetPhysicalDeviceDisplayPropertiesKHR =
+ PFN_vkGetPhysicalDeviceDisplayPropertiesKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceDisplayPropertiesKHR" ) );
+ vkGetPhysicalDeviceDisplayPlanePropertiesKHR =
+ PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR" ) );
+ vkGetDisplayPlaneSupportedDisplaysKHR =
+ PFN_vkGetDisplayPlaneSupportedDisplaysKHR( vkGetInstanceProcAddr( instance, "vkGetDisplayPlaneSupportedDisplaysKHR" ) );
+ vkGetDisplayModePropertiesKHR = PFN_vkGetDisplayModePropertiesKHR( vkGetInstanceProcAddr( instance, "vkGetDisplayModePropertiesKHR" ) );
+ vkCreateDisplayModeKHR = PFN_vkCreateDisplayModeKHR( vkGetInstanceProcAddr( instance, "vkCreateDisplayModeKHR" ) );
+ vkGetDisplayPlaneCapabilitiesKHR = PFN_vkGetDisplayPlaneCapabilitiesKHR( vkGetInstanceProcAddr( instance, "vkGetDisplayPlaneCapabilitiesKHR" ) );
+ vkCreateDisplayPlaneSurfaceKHR = PFN_vkCreateDisplayPlaneSurfaceKHR( vkGetInstanceProcAddr( instance, "vkCreateDisplayPlaneSurfaceKHR" ) );
+
+ //=== VK_KHR_display_swapchain ===
+ vkCreateSharedSwapchainsKHR = PFN_vkCreateSharedSwapchainsKHR( vkGetInstanceProcAddr( instance, "vkCreateSharedSwapchainsKHR" ) );
+
+#if defined( VK_USE_PLATFORM_XLIB_KHR )
+ //=== VK_KHR_xlib_surface ===
+ vkCreateXlibSurfaceKHR = PFN_vkCreateXlibSurfaceKHR( vkGetInstanceProcAddr( instance, "vkCreateXlibSurfaceKHR" ) );
+ vkGetPhysicalDeviceXlibPresentationSupportKHR =
+ PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR" ) );
+#endif /*VK_USE_PLATFORM_XLIB_KHR*/
+
+#if defined( VK_USE_PLATFORM_XCB_KHR )
+ //=== VK_KHR_xcb_surface ===
+ vkCreateXcbSurfaceKHR = PFN_vkCreateXcbSurfaceKHR( vkGetInstanceProcAddr( instance, "vkCreateXcbSurfaceKHR" ) );
+ vkGetPhysicalDeviceXcbPresentationSupportKHR =
+ PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR" ) );
+#endif /*VK_USE_PLATFORM_XCB_KHR*/
+
+#if defined( VK_USE_PLATFORM_WAYLAND_KHR )
+ //=== VK_KHR_wayland_surface ===
+ vkCreateWaylandSurfaceKHR = PFN_vkCreateWaylandSurfaceKHR( vkGetInstanceProcAddr( instance, "vkCreateWaylandSurfaceKHR" ) );
+ vkGetPhysicalDeviceWaylandPresentationSupportKHR =
+ PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR" ) );
+#endif /*VK_USE_PLATFORM_WAYLAND_KHR*/
+
+#if defined( VK_USE_PLATFORM_ANDROID_KHR )
+ //=== VK_KHR_android_surface ===
+ vkCreateAndroidSurfaceKHR = PFN_vkCreateAndroidSurfaceKHR( vkGetInstanceProcAddr( instance, "vkCreateAndroidSurfaceKHR" ) );
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_win32_surface ===
+ vkCreateWin32SurfaceKHR = PFN_vkCreateWin32SurfaceKHR( vkGetInstanceProcAddr( instance, "vkCreateWin32SurfaceKHR" ) );
+ vkGetPhysicalDeviceWin32PresentationSupportKHR =
+ PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_EXT_debug_report ===
+ vkCreateDebugReportCallbackEXT = PFN_vkCreateDebugReportCallbackEXT( vkGetInstanceProcAddr( instance, "vkCreateDebugReportCallbackEXT" ) );
+ vkDestroyDebugReportCallbackEXT = PFN_vkDestroyDebugReportCallbackEXT( vkGetInstanceProcAddr( instance, "vkDestroyDebugReportCallbackEXT" ) );
+ vkDebugReportMessageEXT = PFN_vkDebugReportMessageEXT( vkGetInstanceProcAddr( instance, "vkDebugReportMessageEXT" ) );
+
+ //=== VK_EXT_debug_marker ===
+ vkDebugMarkerSetObjectTagEXT = PFN_vkDebugMarkerSetObjectTagEXT( vkGetInstanceProcAddr( instance, "vkDebugMarkerSetObjectTagEXT" ) );
+ vkDebugMarkerSetObjectNameEXT = PFN_vkDebugMarkerSetObjectNameEXT( vkGetInstanceProcAddr( instance, "vkDebugMarkerSetObjectNameEXT" ) );
+ vkCmdDebugMarkerBeginEXT = PFN_vkCmdDebugMarkerBeginEXT( vkGetInstanceProcAddr( instance, "vkCmdDebugMarkerBeginEXT" ) );
+ vkCmdDebugMarkerEndEXT = PFN_vkCmdDebugMarkerEndEXT( vkGetInstanceProcAddr( instance, "vkCmdDebugMarkerEndEXT" ) );
+ vkCmdDebugMarkerInsertEXT = PFN_vkCmdDebugMarkerInsertEXT( vkGetInstanceProcAddr( instance, "vkCmdDebugMarkerInsertEXT" ) );
+
+#if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_queue ===
+ vkGetPhysicalDeviceVideoCapabilitiesKHR =
+ PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceVideoCapabilitiesKHR" ) );
+ vkGetPhysicalDeviceVideoFormatPropertiesKHR =
+ PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceVideoFormatPropertiesKHR" ) );
+ vkCreateVideoSessionKHR = PFN_vkCreateVideoSessionKHR( vkGetInstanceProcAddr( instance, "vkCreateVideoSessionKHR" ) );
+ vkDestroyVideoSessionKHR = PFN_vkDestroyVideoSessionKHR( vkGetInstanceProcAddr( instance, "vkDestroyVideoSessionKHR" ) );
+ vkGetVideoSessionMemoryRequirementsKHR =
+ PFN_vkGetVideoSessionMemoryRequirementsKHR( vkGetInstanceProcAddr( instance, "vkGetVideoSessionMemoryRequirementsKHR" ) );
+ vkBindVideoSessionMemoryKHR = PFN_vkBindVideoSessionMemoryKHR( vkGetInstanceProcAddr( instance, "vkBindVideoSessionMemoryKHR" ) );
+ vkCreateVideoSessionParametersKHR = PFN_vkCreateVideoSessionParametersKHR( vkGetInstanceProcAddr( instance, "vkCreateVideoSessionParametersKHR" ) );
+ vkUpdateVideoSessionParametersKHR = PFN_vkUpdateVideoSessionParametersKHR( vkGetInstanceProcAddr( instance, "vkUpdateVideoSessionParametersKHR" ) );
+ vkDestroyVideoSessionParametersKHR = PFN_vkDestroyVideoSessionParametersKHR( vkGetInstanceProcAddr( instance, "vkDestroyVideoSessionParametersKHR" ) );
+ vkCmdBeginVideoCodingKHR = PFN_vkCmdBeginVideoCodingKHR( vkGetInstanceProcAddr( instance, "vkCmdBeginVideoCodingKHR" ) );
+ vkCmdEndVideoCodingKHR = PFN_vkCmdEndVideoCodingKHR( vkGetInstanceProcAddr( instance, "vkCmdEndVideoCodingKHR" ) );
+ vkCmdControlVideoCodingKHR = PFN_vkCmdControlVideoCodingKHR( vkGetInstanceProcAddr( instance, "vkCmdControlVideoCodingKHR" ) );
+#endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+#if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_decode_queue ===
+ vkCmdDecodeVideoKHR = PFN_vkCmdDecodeVideoKHR( vkGetInstanceProcAddr( instance, "vkCmdDecodeVideoKHR" ) );
+#endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+ //=== VK_EXT_transform_feedback ===
+ vkCmdBindTransformFeedbackBuffersEXT =
+ PFN_vkCmdBindTransformFeedbackBuffersEXT( vkGetInstanceProcAddr( instance, "vkCmdBindTransformFeedbackBuffersEXT" ) );
+ vkCmdBeginTransformFeedbackEXT = PFN_vkCmdBeginTransformFeedbackEXT( vkGetInstanceProcAddr( instance, "vkCmdBeginTransformFeedbackEXT" ) );
+ vkCmdEndTransformFeedbackEXT = PFN_vkCmdEndTransformFeedbackEXT( vkGetInstanceProcAddr( instance, "vkCmdEndTransformFeedbackEXT" ) );
+ vkCmdBeginQueryIndexedEXT = PFN_vkCmdBeginQueryIndexedEXT( vkGetInstanceProcAddr( instance, "vkCmdBeginQueryIndexedEXT" ) );
+ vkCmdEndQueryIndexedEXT = PFN_vkCmdEndQueryIndexedEXT( vkGetInstanceProcAddr( instance, "vkCmdEndQueryIndexedEXT" ) );
+ vkCmdDrawIndirectByteCountEXT = PFN_vkCmdDrawIndirectByteCountEXT( vkGetInstanceProcAddr( instance, "vkCmdDrawIndirectByteCountEXT" ) );
+
+ //=== VK_NVX_binary_import ===
+ vkCreateCuModuleNVX = PFN_vkCreateCuModuleNVX( vkGetInstanceProcAddr( instance, "vkCreateCuModuleNVX" ) );
+ vkCreateCuFunctionNVX = PFN_vkCreateCuFunctionNVX( vkGetInstanceProcAddr( instance, "vkCreateCuFunctionNVX" ) );
+ vkDestroyCuModuleNVX = PFN_vkDestroyCuModuleNVX( vkGetInstanceProcAddr( instance, "vkDestroyCuModuleNVX" ) );
+ vkDestroyCuFunctionNVX = PFN_vkDestroyCuFunctionNVX( vkGetInstanceProcAddr( instance, "vkDestroyCuFunctionNVX" ) );
+ vkCmdCuLaunchKernelNVX = PFN_vkCmdCuLaunchKernelNVX( vkGetInstanceProcAddr( instance, "vkCmdCuLaunchKernelNVX" ) );
+
+ //=== VK_NVX_image_view_handle ===
+ vkGetImageViewHandleNVX = PFN_vkGetImageViewHandleNVX( vkGetInstanceProcAddr( instance, "vkGetImageViewHandleNVX" ) );
+ vkGetImageViewAddressNVX = PFN_vkGetImageViewAddressNVX( vkGetInstanceProcAddr( instance, "vkGetImageViewAddressNVX" ) );
+
+ //=== VK_AMD_draw_indirect_count ===
+ vkCmdDrawIndirectCountAMD = PFN_vkCmdDrawIndirectCountAMD( vkGetInstanceProcAddr( instance, "vkCmdDrawIndirectCountAMD" ) );
+ if ( !vkCmdDrawIndirectCount )
+ vkCmdDrawIndirectCount = vkCmdDrawIndirectCountAMD;
+ vkCmdDrawIndexedIndirectCountAMD = PFN_vkCmdDrawIndexedIndirectCountAMD( vkGetInstanceProcAddr( instance, "vkCmdDrawIndexedIndirectCountAMD" ) );
+ if ( !vkCmdDrawIndexedIndirectCount )
+ vkCmdDrawIndexedIndirectCount = vkCmdDrawIndexedIndirectCountAMD;
+
+ //=== VK_AMD_shader_info ===
+ vkGetShaderInfoAMD = PFN_vkGetShaderInfoAMD( vkGetInstanceProcAddr( instance, "vkGetShaderInfoAMD" ) );
+
+ //=== VK_KHR_dynamic_rendering ===
+ vkCmdBeginRenderingKHR = PFN_vkCmdBeginRenderingKHR( vkGetInstanceProcAddr( instance, "vkCmdBeginRenderingKHR" ) );
+ if ( !vkCmdBeginRendering )
+ vkCmdBeginRendering = vkCmdBeginRenderingKHR;
+ vkCmdEndRenderingKHR = PFN_vkCmdEndRenderingKHR( vkGetInstanceProcAddr( instance, "vkCmdEndRenderingKHR" ) );
+ if ( !vkCmdEndRendering )
+ vkCmdEndRendering = vkCmdEndRenderingKHR;
+
+#if defined( VK_USE_PLATFORM_GGP )
+ //=== VK_GGP_stream_descriptor_surface ===
+ vkCreateStreamDescriptorSurfaceGGP = PFN_vkCreateStreamDescriptorSurfaceGGP( vkGetInstanceProcAddr( instance, "vkCreateStreamDescriptorSurfaceGGP" ) );
+#endif /*VK_USE_PLATFORM_GGP*/
+
+ //=== VK_NV_external_memory_capabilities ===
+ vkGetPhysicalDeviceExternalImageFormatPropertiesNV =
+ PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceExternalImageFormatPropertiesNV" ) );
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_NV_external_memory_win32 ===
+ vkGetMemoryWin32HandleNV = PFN_vkGetMemoryWin32HandleNV( vkGetInstanceProcAddr( instance, "vkGetMemoryWin32HandleNV" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_get_physical_device_properties2 ===
+ vkGetPhysicalDeviceFeatures2KHR = PFN_vkGetPhysicalDeviceFeatures2KHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceFeatures2KHR" ) );
+ if ( !vkGetPhysicalDeviceFeatures2 )
+ vkGetPhysicalDeviceFeatures2 = vkGetPhysicalDeviceFeatures2KHR;
+ vkGetPhysicalDeviceProperties2KHR = PFN_vkGetPhysicalDeviceProperties2KHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceProperties2KHR" ) );
+ if ( !vkGetPhysicalDeviceProperties2 )
+ vkGetPhysicalDeviceProperties2 = vkGetPhysicalDeviceProperties2KHR;
+ vkGetPhysicalDeviceFormatProperties2KHR =
+ PFN_vkGetPhysicalDeviceFormatProperties2KHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceFormatProperties2KHR" ) );
+ if ( !vkGetPhysicalDeviceFormatProperties2 )
+ vkGetPhysicalDeviceFormatProperties2 = vkGetPhysicalDeviceFormatProperties2KHR;
+ vkGetPhysicalDeviceImageFormatProperties2KHR =
+ PFN_vkGetPhysicalDeviceImageFormatProperties2KHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceImageFormatProperties2KHR" ) );
+ if ( !vkGetPhysicalDeviceImageFormatProperties2 )
+ vkGetPhysicalDeviceImageFormatProperties2 = vkGetPhysicalDeviceImageFormatProperties2KHR;
+ vkGetPhysicalDeviceQueueFamilyProperties2KHR =
+ PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR" ) );
+ if ( !vkGetPhysicalDeviceQueueFamilyProperties2 )
+ vkGetPhysicalDeviceQueueFamilyProperties2 = vkGetPhysicalDeviceQueueFamilyProperties2KHR;
+ vkGetPhysicalDeviceMemoryProperties2KHR =
+ PFN_vkGetPhysicalDeviceMemoryProperties2KHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceMemoryProperties2KHR" ) );
+ if ( !vkGetPhysicalDeviceMemoryProperties2 )
+ vkGetPhysicalDeviceMemoryProperties2 = vkGetPhysicalDeviceMemoryProperties2KHR;
+ vkGetPhysicalDeviceSparseImageFormatProperties2KHR =
+ PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR" ) );
+ if ( !vkGetPhysicalDeviceSparseImageFormatProperties2 )
+ vkGetPhysicalDeviceSparseImageFormatProperties2 = vkGetPhysicalDeviceSparseImageFormatProperties2KHR;
+
+ //=== VK_KHR_device_group ===
+ vkGetDeviceGroupPeerMemoryFeaturesKHR =
+ PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR( vkGetInstanceProcAddr( instance, "vkGetDeviceGroupPeerMemoryFeaturesKHR" ) );
+ if ( !vkGetDeviceGroupPeerMemoryFeatures )
+ vkGetDeviceGroupPeerMemoryFeatures = vkGetDeviceGroupPeerMemoryFeaturesKHR;
+ vkCmdSetDeviceMaskKHR = PFN_vkCmdSetDeviceMaskKHR( vkGetInstanceProcAddr( instance, "vkCmdSetDeviceMaskKHR" ) );
+ if ( !vkCmdSetDeviceMask )
+ vkCmdSetDeviceMask = vkCmdSetDeviceMaskKHR;
+ vkCmdDispatchBaseKHR = PFN_vkCmdDispatchBaseKHR( vkGetInstanceProcAddr( instance, "vkCmdDispatchBaseKHR" ) );
+ if ( !vkCmdDispatchBase )
+ vkCmdDispatchBase = vkCmdDispatchBaseKHR;
+
+#if defined( VK_USE_PLATFORM_VI_NN )
+ //=== VK_NN_vi_surface ===
+ vkCreateViSurfaceNN = PFN_vkCreateViSurfaceNN( vkGetInstanceProcAddr( instance, "vkCreateViSurfaceNN" ) );
+#endif /*VK_USE_PLATFORM_VI_NN*/
+
+ //=== VK_KHR_maintenance1 ===
+ vkTrimCommandPoolKHR = PFN_vkTrimCommandPoolKHR( vkGetInstanceProcAddr( instance, "vkTrimCommandPoolKHR" ) );
+ if ( !vkTrimCommandPool )
+ vkTrimCommandPool = vkTrimCommandPoolKHR;
+
+ //=== VK_KHR_device_group_creation ===
+ vkEnumeratePhysicalDeviceGroupsKHR = PFN_vkEnumeratePhysicalDeviceGroupsKHR( vkGetInstanceProcAddr( instance, "vkEnumeratePhysicalDeviceGroupsKHR" ) );
+ if ( !vkEnumeratePhysicalDeviceGroups )
+ vkEnumeratePhysicalDeviceGroups = vkEnumeratePhysicalDeviceGroupsKHR;
+
+ //=== VK_KHR_external_memory_capabilities ===
+ vkGetPhysicalDeviceExternalBufferPropertiesKHR =
+ PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceExternalBufferPropertiesKHR" ) );
+ if ( !vkGetPhysicalDeviceExternalBufferProperties )
+ vkGetPhysicalDeviceExternalBufferProperties = vkGetPhysicalDeviceExternalBufferPropertiesKHR;
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_memory_win32 ===
+ vkGetMemoryWin32HandleKHR = PFN_vkGetMemoryWin32HandleKHR( vkGetInstanceProcAddr( instance, "vkGetMemoryWin32HandleKHR" ) );
+ vkGetMemoryWin32HandlePropertiesKHR = PFN_vkGetMemoryWin32HandlePropertiesKHR( vkGetInstanceProcAddr( instance, "vkGetMemoryWin32HandlePropertiesKHR" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_memory_fd ===
+ vkGetMemoryFdKHR = PFN_vkGetMemoryFdKHR( vkGetInstanceProcAddr( instance, "vkGetMemoryFdKHR" ) );
+ vkGetMemoryFdPropertiesKHR = PFN_vkGetMemoryFdPropertiesKHR( vkGetInstanceProcAddr( instance, "vkGetMemoryFdPropertiesKHR" ) );
+
+ //=== VK_KHR_external_semaphore_capabilities ===
+ vkGetPhysicalDeviceExternalSemaphorePropertiesKHR =
+ PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR" ) );
+ if ( !vkGetPhysicalDeviceExternalSemaphoreProperties )
+ vkGetPhysicalDeviceExternalSemaphoreProperties = vkGetPhysicalDeviceExternalSemaphorePropertiesKHR;
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_semaphore_win32 ===
+ vkImportSemaphoreWin32HandleKHR = PFN_vkImportSemaphoreWin32HandleKHR( vkGetInstanceProcAddr( instance, "vkImportSemaphoreWin32HandleKHR" ) );
+ vkGetSemaphoreWin32HandleKHR = PFN_vkGetSemaphoreWin32HandleKHR( vkGetInstanceProcAddr( instance, "vkGetSemaphoreWin32HandleKHR" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_semaphore_fd ===
+ vkImportSemaphoreFdKHR = PFN_vkImportSemaphoreFdKHR( vkGetInstanceProcAddr( instance, "vkImportSemaphoreFdKHR" ) );
+ vkGetSemaphoreFdKHR = PFN_vkGetSemaphoreFdKHR( vkGetInstanceProcAddr( instance, "vkGetSemaphoreFdKHR" ) );
+
+ //=== VK_KHR_push_descriptor ===
+ vkCmdPushDescriptorSetKHR = PFN_vkCmdPushDescriptorSetKHR( vkGetInstanceProcAddr( instance, "vkCmdPushDescriptorSetKHR" ) );
+ vkCmdPushDescriptorSetWithTemplateKHR =
+ PFN_vkCmdPushDescriptorSetWithTemplateKHR( vkGetInstanceProcAddr( instance, "vkCmdPushDescriptorSetWithTemplateKHR" ) );
+
+ //=== VK_EXT_conditional_rendering ===
+ vkCmdBeginConditionalRenderingEXT = PFN_vkCmdBeginConditionalRenderingEXT( vkGetInstanceProcAddr( instance, "vkCmdBeginConditionalRenderingEXT" ) );
+ vkCmdEndConditionalRenderingEXT = PFN_vkCmdEndConditionalRenderingEXT( vkGetInstanceProcAddr( instance, "vkCmdEndConditionalRenderingEXT" ) );
+
+ //=== VK_KHR_descriptor_update_template ===
+ vkCreateDescriptorUpdateTemplateKHR = PFN_vkCreateDescriptorUpdateTemplateKHR( vkGetInstanceProcAddr( instance, "vkCreateDescriptorUpdateTemplateKHR" ) );
+ if ( !vkCreateDescriptorUpdateTemplate )
+ vkCreateDescriptorUpdateTemplate = vkCreateDescriptorUpdateTemplateKHR;
+ vkDestroyDescriptorUpdateTemplateKHR =
+ PFN_vkDestroyDescriptorUpdateTemplateKHR( vkGetInstanceProcAddr( instance, "vkDestroyDescriptorUpdateTemplateKHR" ) );
+ if ( !vkDestroyDescriptorUpdateTemplate )
+ vkDestroyDescriptorUpdateTemplate = vkDestroyDescriptorUpdateTemplateKHR;
+ vkUpdateDescriptorSetWithTemplateKHR =
+ PFN_vkUpdateDescriptorSetWithTemplateKHR( vkGetInstanceProcAddr( instance, "vkUpdateDescriptorSetWithTemplateKHR" ) );
+ if ( !vkUpdateDescriptorSetWithTemplate )
+ vkUpdateDescriptorSetWithTemplate = vkUpdateDescriptorSetWithTemplateKHR;
+
+ //=== VK_NV_clip_space_w_scaling ===
+ vkCmdSetViewportWScalingNV = PFN_vkCmdSetViewportWScalingNV( vkGetInstanceProcAddr( instance, "vkCmdSetViewportWScalingNV" ) );
+
+ //=== VK_EXT_direct_mode_display ===
+ vkReleaseDisplayEXT = PFN_vkReleaseDisplayEXT( vkGetInstanceProcAddr( instance, "vkReleaseDisplayEXT" ) );
+
+#if defined( VK_USE_PLATFORM_XLIB_XRANDR_EXT )
+ //=== VK_EXT_acquire_xlib_display ===
+ vkAcquireXlibDisplayEXT = PFN_vkAcquireXlibDisplayEXT( vkGetInstanceProcAddr( instance, "vkAcquireXlibDisplayEXT" ) );
+ vkGetRandROutputDisplayEXT = PFN_vkGetRandROutputDisplayEXT( vkGetInstanceProcAddr( instance, "vkGetRandROutputDisplayEXT" ) );
+#endif /*VK_USE_PLATFORM_XLIB_XRANDR_EXT*/
+
+ //=== VK_EXT_display_surface_counter ===
+ vkGetPhysicalDeviceSurfaceCapabilities2EXT =
+ PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSurfaceCapabilities2EXT" ) );
+
+ //=== VK_EXT_display_control ===
+ vkDisplayPowerControlEXT = PFN_vkDisplayPowerControlEXT( vkGetInstanceProcAddr( instance, "vkDisplayPowerControlEXT" ) );
+ vkRegisterDeviceEventEXT = PFN_vkRegisterDeviceEventEXT( vkGetInstanceProcAddr( instance, "vkRegisterDeviceEventEXT" ) );
+ vkRegisterDisplayEventEXT = PFN_vkRegisterDisplayEventEXT( vkGetInstanceProcAddr( instance, "vkRegisterDisplayEventEXT" ) );
+ vkGetSwapchainCounterEXT = PFN_vkGetSwapchainCounterEXT( vkGetInstanceProcAddr( instance, "vkGetSwapchainCounterEXT" ) );
+
+ //=== VK_GOOGLE_display_timing ===
+ vkGetRefreshCycleDurationGOOGLE = PFN_vkGetRefreshCycleDurationGOOGLE( vkGetInstanceProcAddr( instance, "vkGetRefreshCycleDurationGOOGLE" ) );
+ vkGetPastPresentationTimingGOOGLE = PFN_vkGetPastPresentationTimingGOOGLE( vkGetInstanceProcAddr( instance, "vkGetPastPresentationTimingGOOGLE" ) );
+
+ //=== VK_EXT_discard_rectangles ===
+ vkCmdSetDiscardRectangleEXT = PFN_vkCmdSetDiscardRectangleEXT( vkGetInstanceProcAddr( instance, "vkCmdSetDiscardRectangleEXT" ) );
+
+ //=== VK_EXT_hdr_metadata ===
+ vkSetHdrMetadataEXT = PFN_vkSetHdrMetadataEXT( vkGetInstanceProcAddr( instance, "vkSetHdrMetadataEXT" ) );
+
+ //=== VK_KHR_create_renderpass2 ===
+ vkCreateRenderPass2KHR = PFN_vkCreateRenderPass2KHR( vkGetInstanceProcAddr( instance, "vkCreateRenderPass2KHR" ) );
+ if ( !vkCreateRenderPass2 )
+ vkCreateRenderPass2 = vkCreateRenderPass2KHR;
+ vkCmdBeginRenderPass2KHR = PFN_vkCmdBeginRenderPass2KHR( vkGetInstanceProcAddr( instance, "vkCmdBeginRenderPass2KHR" ) );
+ if ( !vkCmdBeginRenderPass2 )
+ vkCmdBeginRenderPass2 = vkCmdBeginRenderPass2KHR;
+ vkCmdNextSubpass2KHR = PFN_vkCmdNextSubpass2KHR( vkGetInstanceProcAddr( instance, "vkCmdNextSubpass2KHR" ) );
+ if ( !vkCmdNextSubpass2 )
+ vkCmdNextSubpass2 = vkCmdNextSubpass2KHR;
+ vkCmdEndRenderPass2KHR = PFN_vkCmdEndRenderPass2KHR( vkGetInstanceProcAddr( instance, "vkCmdEndRenderPass2KHR" ) );
+ if ( !vkCmdEndRenderPass2 )
+ vkCmdEndRenderPass2 = vkCmdEndRenderPass2KHR;
+
+ //=== VK_KHR_shared_presentable_image ===
+ vkGetSwapchainStatusKHR = PFN_vkGetSwapchainStatusKHR( vkGetInstanceProcAddr( instance, "vkGetSwapchainStatusKHR" ) );
+
+ //=== VK_KHR_external_fence_capabilities ===
+ vkGetPhysicalDeviceExternalFencePropertiesKHR =
+ PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceExternalFencePropertiesKHR" ) );
+ if ( !vkGetPhysicalDeviceExternalFenceProperties )
+ vkGetPhysicalDeviceExternalFenceProperties = vkGetPhysicalDeviceExternalFencePropertiesKHR;
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_fence_win32 ===
+ vkImportFenceWin32HandleKHR = PFN_vkImportFenceWin32HandleKHR( vkGetInstanceProcAddr( instance, "vkImportFenceWin32HandleKHR" ) );
+ vkGetFenceWin32HandleKHR = PFN_vkGetFenceWin32HandleKHR( vkGetInstanceProcAddr( instance, "vkGetFenceWin32HandleKHR" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_fence_fd ===
+ vkImportFenceFdKHR = PFN_vkImportFenceFdKHR( vkGetInstanceProcAddr( instance, "vkImportFenceFdKHR" ) );
+ vkGetFenceFdKHR = PFN_vkGetFenceFdKHR( vkGetInstanceProcAddr( instance, "vkGetFenceFdKHR" ) );
+
+ //=== VK_KHR_performance_query ===
+ vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR = PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
+ vkGetInstanceProcAddr( instance, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR" ) );
+ vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR = PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(
+ vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR" ) );
+ vkAcquireProfilingLockKHR = PFN_vkAcquireProfilingLockKHR( vkGetInstanceProcAddr( instance, "vkAcquireProfilingLockKHR" ) );
+ vkReleaseProfilingLockKHR = PFN_vkReleaseProfilingLockKHR( vkGetInstanceProcAddr( instance, "vkReleaseProfilingLockKHR" ) );
+
+ //=== VK_KHR_get_surface_capabilities2 ===
+ vkGetPhysicalDeviceSurfaceCapabilities2KHR =
+ PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSurfaceCapabilities2KHR" ) );
+ vkGetPhysicalDeviceSurfaceFormats2KHR =
+ PFN_vkGetPhysicalDeviceSurfaceFormats2KHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSurfaceFormats2KHR" ) );
+
+ //=== VK_KHR_get_display_properties2 ===
+ vkGetPhysicalDeviceDisplayProperties2KHR =
+ PFN_vkGetPhysicalDeviceDisplayProperties2KHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceDisplayProperties2KHR" ) );
+ vkGetPhysicalDeviceDisplayPlaneProperties2KHR =
+ PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR" ) );
+ vkGetDisplayModeProperties2KHR = PFN_vkGetDisplayModeProperties2KHR( vkGetInstanceProcAddr( instance, "vkGetDisplayModeProperties2KHR" ) );
+ vkGetDisplayPlaneCapabilities2KHR = PFN_vkGetDisplayPlaneCapabilities2KHR( vkGetInstanceProcAddr( instance, "vkGetDisplayPlaneCapabilities2KHR" ) );
+
+#if defined( VK_USE_PLATFORM_IOS_MVK )
+ //=== VK_MVK_ios_surface ===
+ vkCreateIOSSurfaceMVK = PFN_vkCreateIOSSurfaceMVK( vkGetInstanceProcAddr( instance, "vkCreateIOSSurfaceMVK" ) );
+#endif /*VK_USE_PLATFORM_IOS_MVK*/
+
+#if defined( VK_USE_PLATFORM_MACOS_MVK )
+ //=== VK_MVK_macos_surface ===
+ vkCreateMacOSSurfaceMVK = PFN_vkCreateMacOSSurfaceMVK( vkGetInstanceProcAddr( instance, "vkCreateMacOSSurfaceMVK" ) );
+#endif /*VK_USE_PLATFORM_MACOS_MVK*/
+
+ //=== VK_EXT_debug_utils ===
+ vkSetDebugUtilsObjectNameEXT = PFN_vkSetDebugUtilsObjectNameEXT( vkGetInstanceProcAddr( instance, "vkSetDebugUtilsObjectNameEXT" ) );
+ vkSetDebugUtilsObjectTagEXT = PFN_vkSetDebugUtilsObjectTagEXT( vkGetInstanceProcAddr( instance, "vkSetDebugUtilsObjectTagEXT" ) );
+ vkQueueBeginDebugUtilsLabelEXT = PFN_vkQueueBeginDebugUtilsLabelEXT( vkGetInstanceProcAddr( instance, "vkQueueBeginDebugUtilsLabelEXT" ) );
+ vkQueueEndDebugUtilsLabelEXT = PFN_vkQueueEndDebugUtilsLabelEXT( vkGetInstanceProcAddr( instance, "vkQueueEndDebugUtilsLabelEXT" ) );
+ vkQueueInsertDebugUtilsLabelEXT = PFN_vkQueueInsertDebugUtilsLabelEXT( vkGetInstanceProcAddr( instance, "vkQueueInsertDebugUtilsLabelEXT" ) );
+ vkCmdBeginDebugUtilsLabelEXT = PFN_vkCmdBeginDebugUtilsLabelEXT( vkGetInstanceProcAddr( instance, "vkCmdBeginDebugUtilsLabelEXT" ) );
+ vkCmdEndDebugUtilsLabelEXT = PFN_vkCmdEndDebugUtilsLabelEXT( vkGetInstanceProcAddr( instance, "vkCmdEndDebugUtilsLabelEXT" ) );
+ vkCmdInsertDebugUtilsLabelEXT = PFN_vkCmdInsertDebugUtilsLabelEXT( vkGetInstanceProcAddr( instance, "vkCmdInsertDebugUtilsLabelEXT" ) );
+ vkCreateDebugUtilsMessengerEXT = PFN_vkCreateDebugUtilsMessengerEXT( vkGetInstanceProcAddr( instance, "vkCreateDebugUtilsMessengerEXT" ) );
+ vkDestroyDebugUtilsMessengerEXT = PFN_vkDestroyDebugUtilsMessengerEXT( vkGetInstanceProcAddr( instance, "vkDestroyDebugUtilsMessengerEXT" ) );
+ vkSubmitDebugUtilsMessageEXT = PFN_vkSubmitDebugUtilsMessageEXT( vkGetInstanceProcAddr( instance, "vkSubmitDebugUtilsMessageEXT" ) );
+
+#if defined( VK_USE_PLATFORM_ANDROID_KHR )
+ //=== VK_ANDROID_external_memory_android_hardware_buffer ===
+ vkGetAndroidHardwareBufferPropertiesANDROID =
+ PFN_vkGetAndroidHardwareBufferPropertiesANDROID( vkGetInstanceProcAddr( instance, "vkGetAndroidHardwareBufferPropertiesANDROID" ) );
+ vkGetMemoryAndroidHardwareBufferANDROID =
+ PFN_vkGetMemoryAndroidHardwareBufferANDROID( vkGetInstanceProcAddr( instance, "vkGetMemoryAndroidHardwareBufferANDROID" ) );
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+ //=== VK_EXT_sample_locations ===
+ vkCmdSetSampleLocationsEXT = PFN_vkCmdSetSampleLocationsEXT( vkGetInstanceProcAddr( instance, "vkCmdSetSampleLocationsEXT" ) );
+ vkGetPhysicalDeviceMultisamplePropertiesEXT =
+ PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceMultisamplePropertiesEXT" ) );
+
+ //=== VK_KHR_get_memory_requirements2 ===
+ vkGetImageMemoryRequirements2KHR = PFN_vkGetImageMemoryRequirements2KHR( vkGetInstanceProcAddr( instance, "vkGetImageMemoryRequirements2KHR" ) );
+ if ( !vkGetImageMemoryRequirements2 )
+ vkGetImageMemoryRequirements2 = vkGetImageMemoryRequirements2KHR;
+ vkGetBufferMemoryRequirements2KHR = PFN_vkGetBufferMemoryRequirements2KHR( vkGetInstanceProcAddr( instance, "vkGetBufferMemoryRequirements2KHR" ) );
+ if ( !vkGetBufferMemoryRequirements2 )
+ vkGetBufferMemoryRequirements2 = vkGetBufferMemoryRequirements2KHR;
+ vkGetImageSparseMemoryRequirements2KHR =
+ PFN_vkGetImageSparseMemoryRequirements2KHR( vkGetInstanceProcAddr( instance, "vkGetImageSparseMemoryRequirements2KHR" ) );
+ if ( !vkGetImageSparseMemoryRequirements2 )
+ vkGetImageSparseMemoryRequirements2 = vkGetImageSparseMemoryRequirements2KHR;
+
+ //=== VK_KHR_acceleration_structure ===
+ vkCreateAccelerationStructureKHR = PFN_vkCreateAccelerationStructureKHR( vkGetInstanceProcAddr( instance, "vkCreateAccelerationStructureKHR" ) );
+ vkDestroyAccelerationStructureKHR = PFN_vkDestroyAccelerationStructureKHR( vkGetInstanceProcAddr( instance, "vkDestroyAccelerationStructureKHR" ) );
+ vkCmdBuildAccelerationStructuresKHR = PFN_vkCmdBuildAccelerationStructuresKHR( vkGetInstanceProcAddr( instance, "vkCmdBuildAccelerationStructuresKHR" ) );
+ vkCmdBuildAccelerationStructuresIndirectKHR =
+ PFN_vkCmdBuildAccelerationStructuresIndirectKHR( vkGetInstanceProcAddr( instance, "vkCmdBuildAccelerationStructuresIndirectKHR" ) );
+ vkBuildAccelerationStructuresKHR = PFN_vkBuildAccelerationStructuresKHR( vkGetInstanceProcAddr( instance, "vkBuildAccelerationStructuresKHR" ) );
+ vkCopyAccelerationStructureKHR = PFN_vkCopyAccelerationStructureKHR( vkGetInstanceProcAddr( instance, "vkCopyAccelerationStructureKHR" ) );
+ vkCopyAccelerationStructureToMemoryKHR =
+ PFN_vkCopyAccelerationStructureToMemoryKHR( vkGetInstanceProcAddr( instance, "vkCopyAccelerationStructureToMemoryKHR" ) );
+ vkCopyMemoryToAccelerationStructureKHR =
+ PFN_vkCopyMemoryToAccelerationStructureKHR( vkGetInstanceProcAddr( instance, "vkCopyMemoryToAccelerationStructureKHR" ) );
+ vkWriteAccelerationStructuresPropertiesKHR =
+ PFN_vkWriteAccelerationStructuresPropertiesKHR( vkGetInstanceProcAddr( instance, "vkWriteAccelerationStructuresPropertiesKHR" ) );
+ vkCmdCopyAccelerationStructureKHR = PFN_vkCmdCopyAccelerationStructureKHR( vkGetInstanceProcAddr( instance, "vkCmdCopyAccelerationStructureKHR" ) );
+ vkCmdCopyAccelerationStructureToMemoryKHR =
+ PFN_vkCmdCopyAccelerationStructureToMemoryKHR( vkGetInstanceProcAddr( instance, "vkCmdCopyAccelerationStructureToMemoryKHR" ) );
+ vkCmdCopyMemoryToAccelerationStructureKHR =
+ PFN_vkCmdCopyMemoryToAccelerationStructureKHR( vkGetInstanceProcAddr( instance, "vkCmdCopyMemoryToAccelerationStructureKHR" ) );
+ vkGetAccelerationStructureDeviceAddressKHR =
+ PFN_vkGetAccelerationStructureDeviceAddressKHR( vkGetInstanceProcAddr( instance, "vkGetAccelerationStructureDeviceAddressKHR" ) );
+ vkCmdWriteAccelerationStructuresPropertiesKHR =
+ PFN_vkCmdWriteAccelerationStructuresPropertiesKHR( vkGetInstanceProcAddr( instance, "vkCmdWriteAccelerationStructuresPropertiesKHR" ) );
+ vkGetDeviceAccelerationStructureCompatibilityKHR =
+ PFN_vkGetDeviceAccelerationStructureCompatibilityKHR( vkGetInstanceProcAddr( instance, "vkGetDeviceAccelerationStructureCompatibilityKHR" ) );
+ vkGetAccelerationStructureBuildSizesKHR =
+ PFN_vkGetAccelerationStructureBuildSizesKHR( vkGetInstanceProcAddr( instance, "vkGetAccelerationStructureBuildSizesKHR" ) );
+
+ //=== VK_KHR_sampler_ycbcr_conversion ===
+ vkCreateSamplerYcbcrConversionKHR = PFN_vkCreateSamplerYcbcrConversionKHR( vkGetInstanceProcAddr( instance, "vkCreateSamplerYcbcrConversionKHR" ) );
+ if ( !vkCreateSamplerYcbcrConversion )
+ vkCreateSamplerYcbcrConversion = vkCreateSamplerYcbcrConversionKHR;
+ vkDestroySamplerYcbcrConversionKHR = PFN_vkDestroySamplerYcbcrConversionKHR( vkGetInstanceProcAddr( instance, "vkDestroySamplerYcbcrConversionKHR" ) );
+ if ( !vkDestroySamplerYcbcrConversion )
+ vkDestroySamplerYcbcrConversion = vkDestroySamplerYcbcrConversionKHR;
+
+ //=== VK_KHR_bind_memory2 ===
+ vkBindBufferMemory2KHR = PFN_vkBindBufferMemory2KHR( vkGetInstanceProcAddr( instance, "vkBindBufferMemory2KHR" ) );
+ if ( !vkBindBufferMemory2 )
+ vkBindBufferMemory2 = vkBindBufferMemory2KHR;
+ vkBindImageMemory2KHR = PFN_vkBindImageMemory2KHR( vkGetInstanceProcAddr( instance, "vkBindImageMemory2KHR" ) );
+ if ( !vkBindImageMemory2 )
+ vkBindImageMemory2 = vkBindImageMemory2KHR;
+
+ //=== VK_EXT_image_drm_format_modifier ===
+ vkGetImageDrmFormatModifierPropertiesEXT =
+ PFN_vkGetImageDrmFormatModifierPropertiesEXT( vkGetInstanceProcAddr( instance, "vkGetImageDrmFormatModifierPropertiesEXT" ) );
+
+ //=== VK_EXT_validation_cache ===
+ vkCreateValidationCacheEXT = PFN_vkCreateValidationCacheEXT( vkGetInstanceProcAddr( instance, "vkCreateValidationCacheEXT" ) );
+ vkDestroyValidationCacheEXT = PFN_vkDestroyValidationCacheEXT( vkGetInstanceProcAddr( instance, "vkDestroyValidationCacheEXT" ) );
+ vkMergeValidationCachesEXT = PFN_vkMergeValidationCachesEXT( vkGetInstanceProcAddr( instance, "vkMergeValidationCachesEXT" ) );
+ vkGetValidationCacheDataEXT = PFN_vkGetValidationCacheDataEXT( vkGetInstanceProcAddr( instance, "vkGetValidationCacheDataEXT" ) );
+
+ //=== VK_NV_shading_rate_image ===
+ vkCmdBindShadingRateImageNV = PFN_vkCmdBindShadingRateImageNV( vkGetInstanceProcAddr( instance, "vkCmdBindShadingRateImageNV" ) );
+ vkCmdSetViewportShadingRatePaletteNV =
+ PFN_vkCmdSetViewportShadingRatePaletteNV( vkGetInstanceProcAddr( instance, "vkCmdSetViewportShadingRatePaletteNV" ) );
+ vkCmdSetCoarseSampleOrderNV = PFN_vkCmdSetCoarseSampleOrderNV( vkGetInstanceProcAddr( instance, "vkCmdSetCoarseSampleOrderNV" ) );
+
+ //=== VK_NV_ray_tracing ===
+ vkCreateAccelerationStructureNV = PFN_vkCreateAccelerationStructureNV( vkGetInstanceProcAddr( instance, "vkCreateAccelerationStructureNV" ) );
+ vkDestroyAccelerationStructureNV = PFN_vkDestroyAccelerationStructureNV( vkGetInstanceProcAddr( instance, "vkDestroyAccelerationStructureNV" ) );
+ vkGetAccelerationStructureMemoryRequirementsNV =
+ PFN_vkGetAccelerationStructureMemoryRequirementsNV( vkGetInstanceProcAddr( instance, "vkGetAccelerationStructureMemoryRequirementsNV" ) );
+ vkBindAccelerationStructureMemoryNV = PFN_vkBindAccelerationStructureMemoryNV( vkGetInstanceProcAddr( instance, "vkBindAccelerationStructureMemoryNV" ) );
+ vkCmdBuildAccelerationStructureNV = PFN_vkCmdBuildAccelerationStructureNV( vkGetInstanceProcAddr( instance, "vkCmdBuildAccelerationStructureNV" ) );
+ vkCmdCopyAccelerationStructureNV = PFN_vkCmdCopyAccelerationStructureNV( vkGetInstanceProcAddr( instance, "vkCmdCopyAccelerationStructureNV" ) );
+ vkCmdTraceRaysNV = PFN_vkCmdTraceRaysNV( vkGetInstanceProcAddr( instance, "vkCmdTraceRaysNV" ) );
+ vkCreateRayTracingPipelinesNV = PFN_vkCreateRayTracingPipelinesNV( vkGetInstanceProcAddr( instance, "vkCreateRayTracingPipelinesNV" ) );
+ vkGetRayTracingShaderGroupHandlesNV = PFN_vkGetRayTracingShaderGroupHandlesNV( vkGetInstanceProcAddr( instance, "vkGetRayTracingShaderGroupHandlesNV" ) );
+ if ( !vkGetRayTracingShaderGroupHandlesKHR )
+ vkGetRayTracingShaderGroupHandlesKHR = vkGetRayTracingShaderGroupHandlesNV;
+ vkGetAccelerationStructureHandleNV = PFN_vkGetAccelerationStructureHandleNV( vkGetInstanceProcAddr( instance, "vkGetAccelerationStructureHandleNV" ) );
+ vkCmdWriteAccelerationStructuresPropertiesNV =
+ PFN_vkCmdWriteAccelerationStructuresPropertiesNV( vkGetInstanceProcAddr( instance, "vkCmdWriteAccelerationStructuresPropertiesNV" ) );
+ vkCompileDeferredNV = PFN_vkCompileDeferredNV( vkGetInstanceProcAddr( instance, "vkCompileDeferredNV" ) );
+
+ //=== VK_KHR_maintenance3 ===
+ vkGetDescriptorSetLayoutSupportKHR = PFN_vkGetDescriptorSetLayoutSupportKHR( vkGetInstanceProcAddr( instance, "vkGetDescriptorSetLayoutSupportKHR" ) );
+ if ( !vkGetDescriptorSetLayoutSupport )
+ vkGetDescriptorSetLayoutSupport = vkGetDescriptorSetLayoutSupportKHR;
+
+ //=== VK_KHR_draw_indirect_count ===
+ vkCmdDrawIndirectCountKHR = PFN_vkCmdDrawIndirectCountKHR( vkGetInstanceProcAddr( instance, "vkCmdDrawIndirectCountKHR" ) );
+ if ( !vkCmdDrawIndirectCount )
+ vkCmdDrawIndirectCount = vkCmdDrawIndirectCountKHR;
+ vkCmdDrawIndexedIndirectCountKHR = PFN_vkCmdDrawIndexedIndirectCountKHR( vkGetInstanceProcAddr( instance, "vkCmdDrawIndexedIndirectCountKHR" ) );
+ if ( !vkCmdDrawIndexedIndirectCount )
+ vkCmdDrawIndexedIndirectCount = vkCmdDrawIndexedIndirectCountKHR;
+
+ //=== VK_EXT_external_memory_host ===
+ vkGetMemoryHostPointerPropertiesEXT = PFN_vkGetMemoryHostPointerPropertiesEXT( vkGetInstanceProcAddr( instance, "vkGetMemoryHostPointerPropertiesEXT" ) );
+
+ //=== VK_AMD_buffer_marker ===
+ vkCmdWriteBufferMarkerAMD = PFN_vkCmdWriteBufferMarkerAMD( vkGetInstanceProcAddr( instance, "vkCmdWriteBufferMarkerAMD" ) );
+
+ //=== VK_EXT_calibrated_timestamps ===
+ vkGetPhysicalDeviceCalibrateableTimeDomainsEXT =
+ PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT" ) );
+ vkGetCalibratedTimestampsEXT = PFN_vkGetCalibratedTimestampsEXT( vkGetInstanceProcAddr( instance, "vkGetCalibratedTimestampsEXT" ) );
+
+ //=== VK_NV_mesh_shader ===
+ vkCmdDrawMeshTasksNV = PFN_vkCmdDrawMeshTasksNV( vkGetInstanceProcAddr( instance, "vkCmdDrawMeshTasksNV" ) );
+ vkCmdDrawMeshTasksIndirectNV = PFN_vkCmdDrawMeshTasksIndirectNV( vkGetInstanceProcAddr( instance, "vkCmdDrawMeshTasksIndirectNV" ) );
+ vkCmdDrawMeshTasksIndirectCountNV = PFN_vkCmdDrawMeshTasksIndirectCountNV( vkGetInstanceProcAddr( instance, "vkCmdDrawMeshTasksIndirectCountNV" ) );
+
+ //=== VK_NV_scissor_exclusive ===
+ vkCmdSetExclusiveScissorNV = PFN_vkCmdSetExclusiveScissorNV( vkGetInstanceProcAddr( instance, "vkCmdSetExclusiveScissorNV" ) );
+
+ //=== VK_NV_device_diagnostic_checkpoints ===
+ vkCmdSetCheckpointNV = PFN_vkCmdSetCheckpointNV( vkGetInstanceProcAddr( instance, "vkCmdSetCheckpointNV" ) );
+ vkGetQueueCheckpointDataNV = PFN_vkGetQueueCheckpointDataNV( vkGetInstanceProcAddr( instance, "vkGetQueueCheckpointDataNV" ) );
+
+ //=== VK_KHR_timeline_semaphore ===
+ vkGetSemaphoreCounterValueKHR = PFN_vkGetSemaphoreCounterValueKHR( vkGetInstanceProcAddr( instance, "vkGetSemaphoreCounterValueKHR" ) );
+ if ( !vkGetSemaphoreCounterValue )
+ vkGetSemaphoreCounterValue = vkGetSemaphoreCounterValueKHR;
+ vkWaitSemaphoresKHR = PFN_vkWaitSemaphoresKHR( vkGetInstanceProcAddr( instance, "vkWaitSemaphoresKHR" ) );
+ if ( !vkWaitSemaphores )
+ vkWaitSemaphores = vkWaitSemaphoresKHR;
+ vkSignalSemaphoreKHR = PFN_vkSignalSemaphoreKHR( vkGetInstanceProcAddr( instance, "vkSignalSemaphoreKHR" ) );
+ if ( !vkSignalSemaphore )
+ vkSignalSemaphore = vkSignalSemaphoreKHR;
+
+ //=== VK_INTEL_performance_query ===
+ vkInitializePerformanceApiINTEL = PFN_vkInitializePerformanceApiINTEL( vkGetInstanceProcAddr( instance, "vkInitializePerformanceApiINTEL" ) );
+ vkUninitializePerformanceApiINTEL = PFN_vkUninitializePerformanceApiINTEL( vkGetInstanceProcAddr( instance, "vkUninitializePerformanceApiINTEL" ) );
+ vkCmdSetPerformanceMarkerINTEL = PFN_vkCmdSetPerformanceMarkerINTEL( vkGetInstanceProcAddr( instance, "vkCmdSetPerformanceMarkerINTEL" ) );
+ vkCmdSetPerformanceStreamMarkerINTEL =
+ PFN_vkCmdSetPerformanceStreamMarkerINTEL( vkGetInstanceProcAddr( instance, "vkCmdSetPerformanceStreamMarkerINTEL" ) );
+ vkCmdSetPerformanceOverrideINTEL = PFN_vkCmdSetPerformanceOverrideINTEL( vkGetInstanceProcAddr( instance, "vkCmdSetPerformanceOverrideINTEL" ) );
+ vkAcquirePerformanceConfigurationINTEL =
+ PFN_vkAcquirePerformanceConfigurationINTEL( vkGetInstanceProcAddr( instance, "vkAcquirePerformanceConfigurationINTEL" ) );
+ vkReleasePerformanceConfigurationINTEL =
+ PFN_vkReleasePerformanceConfigurationINTEL( vkGetInstanceProcAddr( instance, "vkReleasePerformanceConfigurationINTEL" ) );
+ vkQueueSetPerformanceConfigurationINTEL =
+ PFN_vkQueueSetPerformanceConfigurationINTEL( vkGetInstanceProcAddr( instance, "vkQueueSetPerformanceConfigurationINTEL" ) );
+ vkGetPerformanceParameterINTEL = PFN_vkGetPerformanceParameterINTEL( vkGetInstanceProcAddr( instance, "vkGetPerformanceParameterINTEL" ) );
+
+ //=== VK_AMD_display_native_hdr ===
+ vkSetLocalDimmingAMD = PFN_vkSetLocalDimmingAMD( vkGetInstanceProcAddr( instance, "vkSetLocalDimmingAMD" ) );
+
+#if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_imagepipe_surface ===
+ vkCreateImagePipeSurfaceFUCHSIA = PFN_vkCreateImagePipeSurfaceFUCHSIA( vkGetInstanceProcAddr( instance, "vkCreateImagePipeSurfaceFUCHSIA" ) );
+#endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+#if defined( VK_USE_PLATFORM_METAL_EXT )
+ //=== VK_EXT_metal_surface ===
+ vkCreateMetalSurfaceEXT = PFN_vkCreateMetalSurfaceEXT( vkGetInstanceProcAddr( instance, "vkCreateMetalSurfaceEXT" ) );
+#endif /*VK_USE_PLATFORM_METAL_EXT*/
+
+ //=== VK_KHR_fragment_shading_rate ===
+ vkGetPhysicalDeviceFragmentShadingRatesKHR =
+ PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceFragmentShadingRatesKHR" ) );
+ vkCmdSetFragmentShadingRateKHR = PFN_vkCmdSetFragmentShadingRateKHR( vkGetInstanceProcAddr( instance, "vkCmdSetFragmentShadingRateKHR" ) );
+
+ //=== VK_EXT_buffer_device_address ===
+ vkGetBufferDeviceAddressEXT = PFN_vkGetBufferDeviceAddressEXT( vkGetInstanceProcAddr( instance, "vkGetBufferDeviceAddressEXT" ) );
+ if ( !vkGetBufferDeviceAddress )
+ vkGetBufferDeviceAddress = vkGetBufferDeviceAddressEXT;
+
+ //=== VK_EXT_tooling_info ===
+ vkGetPhysicalDeviceToolPropertiesEXT =
+ PFN_vkGetPhysicalDeviceToolPropertiesEXT( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceToolPropertiesEXT" ) );
+ if ( !vkGetPhysicalDeviceToolProperties )
+ vkGetPhysicalDeviceToolProperties = vkGetPhysicalDeviceToolPropertiesEXT;
+
+ //=== VK_KHR_present_wait ===
+ vkWaitForPresentKHR = PFN_vkWaitForPresentKHR( vkGetInstanceProcAddr( instance, "vkWaitForPresentKHR" ) );
+
+ //=== VK_NV_cooperative_matrix ===
+ vkGetPhysicalDeviceCooperativeMatrixPropertiesNV =
+ PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV" ) );
+
+ //=== VK_NV_coverage_reduction_mode ===
+ vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV = PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(
+ vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV" ) );
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_EXT_full_screen_exclusive ===
+ vkGetPhysicalDeviceSurfacePresentModes2EXT =
+ PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceSurfacePresentModes2EXT" ) );
+ vkAcquireFullScreenExclusiveModeEXT = PFN_vkAcquireFullScreenExclusiveModeEXT( vkGetInstanceProcAddr( instance, "vkAcquireFullScreenExclusiveModeEXT" ) );
+ vkReleaseFullScreenExclusiveModeEXT = PFN_vkReleaseFullScreenExclusiveModeEXT( vkGetInstanceProcAddr( instance, "vkReleaseFullScreenExclusiveModeEXT" ) );
+ vkGetDeviceGroupSurfacePresentModes2EXT =
+ PFN_vkGetDeviceGroupSurfacePresentModes2EXT( vkGetInstanceProcAddr( instance, "vkGetDeviceGroupSurfacePresentModes2EXT" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_EXT_headless_surface ===
+ vkCreateHeadlessSurfaceEXT = PFN_vkCreateHeadlessSurfaceEXT( vkGetInstanceProcAddr( instance, "vkCreateHeadlessSurfaceEXT" ) );
+
+ //=== VK_KHR_buffer_device_address ===
+ vkGetBufferDeviceAddressKHR = PFN_vkGetBufferDeviceAddressKHR( vkGetInstanceProcAddr( instance, "vkGetBufferDeviceAddressKHR" ) );
+ if ( !vkGetBufferDeviceAddress )
+ vkGetBufferDeviceAddress = vkGetBufferDeviceAddressKHR;
+ vkGetBufferOpaqueCaptureAddressKHR = PFN_vkGetBufferOpaqueCaptureAddressKHR( vkGetInstanceProcAddr( instance, "vkGetBufferOpaqueCaptureAddressKHR" ) );
+ if ( !vkGetBufferOpaqueCaptureAddress )
+ vkGetBufferOpaqueCaptureAddress = vkGetBufferOpaqueCaptureAddressKHR;
+ vkGetDeviceMemoryOpaqueCaptureAddressKHR =
+ PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR( vkGetInstanceProcAddr( instance, "vkGetDeviceMemoryOpaqueCaptureAddressKHR" ) );
+ if ( !vkGetDeviceMemoryOpaqueCaptureAddress )
+ vkGetDeviceMemoryOpaqueCaptureAddress = vkGetDeviceMemoryOpaqueCaptureAddressKHR;
+
+ //=== VK_EXT_line_rasterization ===
+ vkCmdSetLineStippleEXT = PFN_vkCmdSetLineStippleEXT( vkGetInstanceProcAddr( instance, "vkCmdSetLineStippleEXT" ) );
+
+ //=== VK_EXT_host_query_reset ===
+ vkResetQueryPoolEXT = PFN_vkResetQueryPoolEXT( vkGetInstanceProcAddr( instance, "vkResetQueryPoolEXT" ) );
+ if ( !vkResetQueryPool )
+ vkResetQueryPool = vkResetQueryPoolEXT;
+
+ //=== VK_EXT_extended_dynamic_state ===
+ vkCmdSetCullModeEXT = PFN_vkCmdSetCullModeEXT( vkGetInstanceProcAddr( instance, "vkCmdSetCullModeEXT" ) );
+ if ( !vkCmdSetCullMode )
+ vkCmdSetCullMode = vkCmdSetCullModeEXT;
+ vkCmdSetFrontFaceEXT = PFN_vkCmdSetFrontFaceEXT( vkGetInstanceProcAddr( instance, "vkCmdSetFrontFaceEXT" ) );
+ if ( !vkCmdSetFrontFace )
+ vkCmdSetFrontFace = vkCmdSetFrontFaceEXT;
+ vkCmdSetPrimitiveTopologyEXT = PFN_vkCmdSetPrimitiveTopologyEXT( vkGetInstanceProcAddr( instance, "vkCmdSetPrimitiveTopologyEXT" ) );
+ if ( !vkCmdSetPrimitiveTopology )
+ vkCmdSetPrimitiveTopology = vkCmdSetPrimitiveTopologyEXT;
+ vkCmdSetViewportWithCountEXT = PFN_vkCmdSetViewportWithCountEXT( vkGetInstanceProcAddr( instance, "vkCmdSetViewportWithCountEXT" ) );
+ if ( !vkCmdSetViewportWithCount )
+ vkCmdSetViewportWithCount = vkCmdSetViewportWithCountEXT;
+ vkCmdSetScissorWithCountEXT = PFN_vkCmdSetScissorWithCountEXT( vkGetInstanceProcAddr( instance, "vkCmdSetScissorWithCountEXT" ) );
+ if ( !vkCmdSetScissorWithCount )
+ vkCmdSetScissorWithCount = vkCmdSetScissorWithCountEXT;
+ vkCmdBindVertexBuffers2EXT = PFN_vkCmdBindVertexBuffers2EXT( vkGetInstanceProcAddr( instance, "vkCmdBindVertexBuffers2EXT" ) );
+ if ( !vkCmdBindVertexBuffers2 )
+ vkCmdBindVertexBuffers2 = vkCmdBindVertexBuffers2EXT;
+ vkCmdSetDepthTestEnableEXT = PFN_vkCmdSetDepthTestEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetDepthTestEnableEXT" ) );
+ if ( !vkCmdSetDepthTestEnable )
+ vkCmdSetDepthTestEnable = vkCmdSetDepthTestEnableEXT;
+ vkCmdSetDepthWriteEnableEXT = PFN_vkCmdSetDepthWriteEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetDepthWriteEnableEXT" ) );
+ if ( !vkCmdSetDepthWriteEnable )
+ vkCmdSetDepthWriteEnable = vkCmdSetDepthWriteEnableEXT;
+ vkCmdSetDepthCompareOpEXT = PFN_vkCmdSetDepthCompareOpEXT( vkGetInstanceProcAddr( instance, "vkCmdSetDepthCompareOpEXT" ) );
+ if ( !vkCmdSetDepthCompareOp )
+ vkCmdSetDepthCompareOp = vkCmdSetDepthCompareOpEXT;
+ vkCmdSetDepthBoundsTestEnableEXT = PFN_vkCmdSetDepthBoundsTestEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetDepthBoundsTestEnableEXT" ) );
+ if ( !vkCmdSetDepthBoundsTestEnable )
+ vkCmdSetDepthBoundsTestEnable = vkCmdSetDepthBoundsTestEnableEXT;
+ vkCmdSetStencilTestEnableEXT = PFN_vkCmdSetStencilTestEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetStencilTestEnableEXT" ) );
+ if ( !vkCmdSetStencilTestEnable )
+ vkCmdSetStencilTestEnable = vkCmdSetStencilTestEnableEXT;
+ vkCmdSetStencilOpEXT = PFN_vkCmdSetStencilOpEXT( vkGetInstanceProcAddr( instance, "vkCmdSetStencilOpEXT" ) );
+ if ( !vkCmdSetStencilOp )
+ vkCmdSetStencilOp = vkCmdSetStencilOpEXT;
+
+ //=== VK_KHR_deferred_host_operations ===
+ vkCreateDeferredOperationKHR = PFN_vkCreateDeferredOperationKHR( vkGetInstanceProcAddr( instance, "vkCreateDeferredOperationKHR" ) );
+ vkDestroyDeferredOperationKHR = PFN_vkDestroyDeferredOperationKHR( vkGetInstanceProcAddr( instance, "vkDestroyDeferredOperationKHR" ) );
+ vkGetDeferredOperationMaxConcurrencyKHR =
+ PFN_vkGetDeferredOperationMaxConcurrencyKHR( vkGetInstanceProcAddr( instance, "vkGetDeferredOperationMaxConcurrencyKHR" ) );
+ vkGetDeferredOperationResultKHR = PFN_vkGetDeferredOperationResultKHR( vkGetInstanceProcAddr( instance, "vkGetDeferredOperationResultKHR" ) );
+ vkDeferredOperationJoinKHR = PFN_vkDeferredOperationJoinKHR( vkGetInstanceProcAddr( instance, "vkDeferredOperationJoinKHR" ) );
+
+ //=== VK_KHR_pipeline_executable_properties ===
+ vkGetPipelineExecutablePropertiesKHR =
+ PFN_vkGetPipelineExecutablePropertiesKHR( vkGetInstanceProcAddr( instance, "vkGetPipelineExecutablePropertiesKHR" ) );
+ vkGetPipelineExecutableStatisticsKHR =
+ PFN_vkGetPipelineExecutableStatisticsKHR( vkGetInstanceProcAddr( instance, "vkGetPipelineExecutableStatisticsKHR" ) );
+ vkGetPipelineExecutableInternalRepresentationsKHR =
+ PFN_vkGetPipelineExecutableInternalRepresentationsKHR( vkGetInstanceProcAddr( instance, "vkGetPipelineExecutableInternalRepresentationsKHR" ) );
+
+ //=== VK_NV_device_generated_commands ===
+ vkGetGeneratedCommandsMemoryRequirementsNV =
+ PFN_vkGetGeneratedCommandsMemoryRequirementsNV( vkGetInstanceProcAddr( instance, "vkGetGeneratedCommandsMemoryRequirementsNV" ) );
+ vkCmdPreprocessGeneratedCommandsNV = PFN_vkCmdPreprocessGeneratedCommandsNV( vkGetInstanceProcAddr( instance, "vkCmdPreprocessGeneratedCommandsNV" ) );
+ vkCmdExecuteGeneratedCommandsNV = PFN_vkCmdExecuteGeneratedCommandsNV( vkGetInstanceProcAddr( instance, "vkCmdExecuteGeneratedCommandsNV" ) );
+ vkCmdBindPipelineShaderGroupNV = PFN_vkCmdBindPipelineShaderGroupNV( vkGetInstanceProcAddr( instance, "vkCmdBindPipelineShaderGroupNV" ) );
+ vkCreateIndirectCommandsLayoutNV = PFN_vkCreateIndirectCommandsLayoutNV( vkGetInstanceProcAddr( instance, "vkCreateIndirectCommandsLayoutNV" ) );
+ vkDestroyIndirectCommandsLayoutNV = PFN_vkDestroyIndirectCommandsLayoutNV( vkGetInstanceProcAddr( instance, "vkDestroyIndirectCommandsLayoutNV" ) );
+
+ //=== VK_EXT_acquire_drm_display ===
+ vkAcquireDrmDisplayEXT = PFN_vkAcquireDrmDisplayEXT( vkGetInstanceProcAddr( instance, "vkAcquireDrmDisplayEXT" ) );
+ vkGetDrmDisplayEXT = PFN_vkGetDrmDisplayEXT( vkGetInstanceProcAddr( instance, "vkGetDrmDisplayEXT" ) );
+
+ //=== VK_EXT_private_data ===
+ vkCreatePrivateDataSlotEXT = PFN_vkCreatePrivateDataSlotEXT( vkGetInstanceProcAddr( instance, "vkCreatePrivateDataSlotEXT" ) );
+ if ( !vkCreatePrivateDataSlot )
+ vkCreatePrivateDataSlot = vkCreatePrivateDataSlotEXT;
+ vkDestroyPrivateDataSlotEXT = PFN_vkDestroyPrivateDataSlotEXT( vkGetInstanceProcAddr( instance, "vkDestroyPrivateDataSlotEXT" ) );
+ if ( !vkDestroyPrivateDataSlot )
+ vkDestroyPrivateDataSlot = vkDestroyPrivateDataSlotEXT;
+ vkSetPrivateDataEXT = PFN_vkSetPrivateDataEXT( vkGetInstanceProcAddr( instance, "vkSetPrivateDataEXT" ) );
+ if ( !vkSetPrivateData )
+ vkSetPrivateData = vkSetPrivateDataEXT;
+ vkGetPrivateDataEXT = PFN_vkGetPrivateDataEXT( vkGetInstanceProcAddr( instance, "vkGetPrivateDataEXT" ) );
+ if ( !vkGetPrivateData )
+ vkGetPrivateData = vkGetPrivateDataEXT;
+
+#if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_encode_queue ===
+ vkCmdEncodeVideoKHR = PFN_vkCmdEncodeVideoKHR( vkGetInstanceProcAddr( instance, "vkCmdEncodeVideoKHR" ) );
+#endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+#if defined( VK_USE_PLATFORM_METAL_EXT )
+ //=== VK_EXT_metal_objects ===
+ vkExportMetalObjectsEXT = PFN_vkExportMetalObjectsEXT( vkGetInstanceProcAddr( instance, "vkExportMetalObjectsEXT" ) );
+#endif /*VK_USE_PLATFORM_METAL_EXT*/
+
+ //=== VK_KHR_synchronization2 ===
+ vkCmdSetEvent2KHR = PFN_vkCmdSetEvent2KHR( vkGetInstanceProcAddr( instance, "vkCmdSetEvent2KHR" ) );
+ if ( !vkCmdSetEvent2 )
+ vkCmdSetEvent2 = vkCmdSetEvent2KHR;
+ vkCmdResetEvent2KHR = PFN_vkCmdResetEvent2KHR( vkGetInstanceProcAddr( instance, "vkCmdResetEvent2KHR" ) );
+ if ( !vkCmdResetEvent2 )
+ vkCmdResetEvent2 = vkCmdResetEvent2KHR;
+ vkCmdWaitEvents2KHR = PFN_vkCmdWaitEvents2KHR( vkGetInstanceProcAddr( instance, "vkCmdWaitEvents2KHR" ) );
+ if ( !vkCmdWaitEvents2 )
+ vkCmdWaitEvents2 = vkCmdWaitEvents2KHR;
+ vkCmdPipelineBarrier2KHR = PFN_vkCmdPipelineBarrier2KHR( vkGetInstanceProcAddr( instance, "vkCmdPipelineBarrier2KHR" ) );
+ if ( !vkCmdPipelineBarrier2 )
+ vkCmdPipelineBarrier2 = vkCmdPipelineBarrier2KHR;
+ vkCmdWriteTimestamp2KHR = PFN_vkCmdWriteTimestamp2KHR( vkGetInstanceProcAddr( instance, "vkCmdWriteTimestamp2KHR" ) );
+ if ( !vkCmdWriteTimestamp2 )
+ vkCmdWriteTimestamp2 = vkCmdWriteTimestamp2KHR;
+ vkQueueSubmit2KHR = PFN_vkQueueSubmit2KHR( vkGetInstanceProcAddr( instance, "vkQueueSubmit2KHR" ) );
+ if ( !vkQueueSubmit2 )
+ vkQueueSubmit2 = vkQueueSubmit2KHR;
+ vkCmdWriteBufferMarker2AMD = PFN_vkCmdWriteBufferMarker2AMD( vkGetInstanceProcAddr( instance, "vkCmdWriteBufferMarker2AMD" ) );
+ vkGetQueueCheckpointData2NV = PFN_vkGetQueueCheckpointData2NV( vkGetInstanceProcAddr( instance, "vkGetQueueCheckpointData2NV" ) );
+
+ //=== VK_NV_fragment_shading_rate_enums ===
+ vkCmdSetFragmentShadingRateEnumNV = PFN_vkCmdSetFragmentShadingRateEnumNV( vkGetInstanceProcAddr( instance, "vkCmdSetFragmentShadingRateEnumNV" ) );
+
+ //=== VK_EXT_mesh_shader ===
+ vkCmdDrawMeshTasksEXT = PFN_vkCmdDrawMeshTasksEXT( vkGetInstanceProcAddr( instance, "vkCmdDrawMeshTasksEXT" ) );
+ vkCmdDrawMeshTasksIndirectEXT = PFN_vkCmdDrawMeshTasksIndirectEXT( vkGetInstanceProcAddr( instance, "vkCmdDrawMeshTasksIndirectEXT" ) );
+ vkCmdDrawMeshTasksIndirectCountEXT = PFN_vkCmdDrawMeshTasksIndirectCountEXT( vkGetInstanceProcAddr( instance, "vkCmdDrawMeshTasksIndirectCountEXT" ) );
+
+ //=== VK_KHR_copy_commands2 ===
+ vkCmdCopyBuffer2KHR = PFN_vkCmdCopyBuffer2KHR( vkGetInstanceProcAddr( instance, "vkCmdCopyBuffer2KHR" ) );
+ if ( !vkCmdCopyBuffer2 )
+ vkCmdCopyBuffer2 = vkCmdCopyBuffer2KHR;
+ vkCmdCopyImage2KHR = PFN_vkCmdCopyImage2KHR( vkGetInstanceProcAddr( instance, "vkCmdCopyImage2KHR" ) );
+ if ( !vkCmdCopyImage2 )
+ vkCmdCopyImage2 = vkCmdCopyImage2KHR;
+ vkCmdCopyBufferToImage2KHR = PFN_vkCmdCopyBufferToImage2KHR( vkGetInstanceProcAddr( instance, "vkCmdCopyBufferToImage2KHR" ) );
+ if ( !vkCmdCopyBufferToImage2 )
+ vkCmdCopyBufferToImage2 = vkCmdCopyBufferToImage2KHR;
+ vkCmdCopyImageToBuffer2KHR = PFN_vkCmdCopyImageToBuffer2KHR( vkGetInstanceProcAddr( instance, "vkCmdCopyImageToBuffer2KHR" ) );
+ if ( !vkCmdCopyImageToBuffer2 )
+ vkCmdCopyImageToBuffer2 = vkCmdCopyImageToBuffer2KHR;
+ vkCmdBlitImage2KHR = PFN_vkCmdBlitImage2KHR( vkGetInstanceProcAddr( instance, "vkCmdBlitImage2KHR" ) );
+ if ( !vkCmdBlitImage2 )
+ vkCmdBlitImage2 = vkCmdBlitImage2KHR;
+ vkCmdResolveImage2KHR = PFN_vkCmdResolveImage2KHR( vkGetInstanceProcAddr( instance, "vkCmdResolveImage2KHR" ) );
+ if ( !vkCmdResolveImage2 )
+ vkCmdResolveImage2 = vkCmdResolveImage2KHR;
+
+ //=== VK_EXT_image_compression_control ===
+ vkGetImageSubresourceLayout2EXT = PFN_vkGetImageSubresourceLayout2EXT( vkGetInstanceProcAddr( instance, "vkGetImageSubresourceLayout2EXT" ) );
+
+ //=== VK_EXT_device_fault ===
+ vkGetDeviceFaultInfoEXT = PFN_vkGetDeviceFaultInfoEXT( vkGetInstanceProcAddr( instance, "vkGetDeviceFaultInfoEXT" ) );
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_NV_acquire_winrt_display ===
+ vkAcquireWinrtDisplayNV = PFN_vkAcquireWinrtDisplayNV( vkGetInstanceProcAddr( instance, "vkAcquireWinrtDisplayNV" ) );
+ vkGetWinrtDisplayNV = PFN_vkGetWinrtDisplayNV( vkGetInstanceProcAddr( instance, "vkGetWinrtDisplayNV" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+#if defined( VK_USE_PLATFORM_DIRECTFB_EXT )
+ //=== VK_EXT_directfb_surface ===
+ vkCreateDirectFBSurfaceEXT = PFN_vkCreateDirectFBSurfaceEXT( vkGetInstanceProcAddr( instance, "vkCreateDirectFBSurfaceEXT" ) );
+ vkGetPhysicalDeviceDirectFBPresentationSupportEXT =
+ PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceDirectFBPresentationSupportEXT" ) );
+#endif /*VK_USE_PLATFORM_DIRECTFB_EXT*/
+
+ //=== VK_KHR_ray_tracing_pipeline ===
+ vkCmdTraceRaysKHR = PFN_vkCmdTraceRaysKHR( vkGetInstanceProcAddr( instance, "vkCmdTraceRaysKHR" ) );
+ vkCreateRayTracingPipelinesKHR = PFN_vkCreateRayTracingPipelinesKHR( vkGetInstanceProcAddr( instance, "vkCreateRayTracingPipelinesKHR" ) );
+ vkGetRayTracingShaderGroupHandlesKHR =
+ PFN_vkGetRayTracingShaderGroupHandlesKHR( vkGetInstanceProcAddr( instance, "vkGetRayTracingShaderGroupHandlesKHR" ) );
+ vkGetRayTracingCaptureReplayShaderGroupHandlesKHR =
+ PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR( vkGetInstanceProcAddr( instance, "vkGetRayTracingCaptureReplayShaderGroupHandlesKHR" ) );
+ vkCmdTraceRaysIndirectKHR = PFN_vkCmdTraceRaysIndirectKHR( vkGetInstanceProcAddr( instance, "vkCmdTraceRaysIndirectKHR" ) );
+ vkGetRayTracingShaderGroupStackSizeKHR =
+ PFN_vkGetRayTracingShaderGroupStackSizeKHR( vkGetInstanceProcAddr( instance, "vkGetRayTracingShaderGroupStackSizeKHR" ) );
+ vkCmdSetRayTracingPipelineStackSizeKHR =
+ PFN_vkCmdSetRayTracingPipelineStackSizeKHR( vkGetInstanceProcAddr( instance, "vkCmdSetRayTracingPipelineStackSizeKHR" ) );
+
+ //=== VK_EXT_vertex_input_dynamic_state ===
+ vkCmdSetVertexInputEXT = PFN_vkCmdSetVertexInputEXT( vkGetInstanceProcAddr( instance, "vkCmdSetVertexInputEXT" ) );
+
+#if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_external_memory ===
+ vkGetMemoryZirconHandleFUCHSIA = PFN_vkGetMemoryZirconHandleFUCHSIA( vkGetInstanceProcAddr( instance, "vkGetMemoryZirconHandleFUCHSIA" ) );
+ vkGetMemoryZirconHandlePropertiesFUCHSIA =
+ PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA( vkGetInstanceProcAddr( instance, "vkGetMemoryZirconHandlePropertiesFUCHSIA" ) );
+#endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+#if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_external_semaphore ===
+ vkImportSemaphoreZirconHandleFUCHSIA =
+ PFN_vkImportSemaphoreZirconHandleFUCHSIA( vkGetInstanceProcAddr( instance, "vkImportSemaphoreZirconHandleFUCHSIA" ) );
+ vkGetSemaphoreZirconHandleFUCHSIA = PFN_vkGetSemaphoreZirconHandleFUCHSIA( vkGetInstanceProcAddr( instance, "vkGetSemaphoreZirconHandleFUCHSIA" ) );
+#endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+#if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_buffer_collection ===
+ vkCreateBufferCollectionFUCHSIA = PFN_vkCreateBufferCollectionFUCHSIA( vkGetInstanceProcAddr( instance, "vkCreateBufferCollectionFUCHSIA" ) );
+ vkSetBufferCollectionImageConstraintsFUCHSIA =
+ PFN_vkSetBufferCollectionImageConstraintsFUCHSIA( vkGetInstanceProcAddr( instance, "vkSetBufferCollectionImageConstraintsFUCHSIA" ) );
+ vkSetBufferCollectionBufferConstraintsFUCHSIA =
+ PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA( vkGetInstanceProcAddr( instance, "vkSetBufferCollectionBufferConstraintsFUCHSIA" ) );
+ vkDestroyBufferCollectionFUCHSIA = PFN_vkDestroyBufferCollectionFUCHSIA( vkGetInstanceProcAddr( instance, "vkDestroyBufferCollectionFUCHSIA" ) );
+ vkGetBufferCollectionPropertiesFUCHSIA =
+ PFN_vkGetBufferCollectionPropertiesFUCHSIA( vkGetInstanceProcAddr( instance, "vkGetBufferCollectionPropertiesFUCHSIA" ) );
+#endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+ //=== VK_HUAWEI_subpass_shading ===
+ vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI =
+ PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI( vkGetInstanceProcAddr( instance, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI" ) );
+ vkCmdSubpassShadingHUAWEI = PFN_vkCmdSubpassShadingHUAWEI( vkGetInstanceProcAddr( instance, "vkCmdSubpassShadingHUAWEI" ) );
+
+ //=== VK_HUAWEI_invocation_mask ===
+ vkCmdBindInvocationMaskHUAWEI = PFN_vkCmdBindInvocationMaskHUAWEI( vkGetInstanceProcAddr( instance, "vkCmdBindInvocationMaskHUAWEI" ) );
+
+ //=== VK_NV_external_memory_rdma ===
+ vkGetMemoryRemoteAddressNV = PFN_vkGetMemoryRemoteAddressNV( vkGetInstanceProcAddr( instance, "vkGetMemoryRemoteAddressNV" ) );
+
+ //=== VK_EXT_pipeline_properties ===
+ vkGetPipelinePropertiesEXT = PFN_vkGetPipelinePropertiesEXT( vkGetInstanceProcAddr( instance, "vkGetPipelinePropertiesEXT" ) );
+
+ //=== VK_EXT_extended_dynamic_state2 ===
+ vkCmdSetPatchControlPointsEXT = PFN_vkCmdSetPatchControlPointsEXT( vkGetInstanceProcAddr( instance, "vkCmdSetPatchControlPointsEXT" ) );
+ vkCmdSetRasterizerDiscardEnableEXT = PFN_vkCmdSetRasterizerDiscardEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetRasterizerDiscardEnableEXT" ) );
+ if ( !vkCmdSetRasterizerDiscardEnable )
+ vkCmdSetRasterizerDiscardEnable = vkCmdSetRasterizerDiscardEnableEXT;
+ vkCmdSetDepthBiasEnableEXT = PFN_vkCmdSetDepthBiasEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetDepthBiasEnableEXT" ) );
+ if ( !vkCmdSetDepthBiasEnable )
+ vkCmdSetDepthBiasEnable = vkCmdSetDepthBiasEnableEXT;
+ vkCmdSetLogicOpEXT = PFN_vkCmdSetLogicOpEXT( vkGetInstanceProcAddr( instance, "vkCmdSetLogicOpEXT" ) );
+ vkCmdSetPrimitiveRestartEnableEXT = PFN_vkCmdSetPrimitiveRestartEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetPrimitiveRestartEnableEXT" ) );
+ if ( !vkCmdSetPrimitiveRestartEnable )
+ vkCmdSetPrimitiveRestartEnable = vkCmdSetPrimitiveRestartEnableEXT;
+
+#if defined( VK_USE_PLATFORM_SCREEN_QNX )
+ //=== VK_QNX_screen_surface ===
+ vkCreateScreenSurfaceQNX = PFN_vkCreateScreenSurfaceQNX( vkGetInstanceProcAddr( instance, "vkCreateScreenSurfaceQNX" ) );
+ vkGetPhysicalDeviceScreenPresentationSupportQNX =
+ PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceScreenPresentationSupportQNX" ) );
+#endif /*VK_USE_PLATFORM_SCREEN_QNX*/
+
+ //=== VK_EXT_color_write_enable ===
+ vkCmdSetColorWriteEnableEXT = PFN_vkCmdSetColorWriteEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetColorWriteEnableEXT" ) );
+
+ //=== VK_KHR_ray_tracing_maintenance1 ===
+ vkCmdTraceRaysIndirect2KHR = PFN_vkCmdTraceRaysIndirect2KHR( vkGetInstanceProcAddr( instance, "vkCmdTraceRaysIndirect2KHR" ) );
+
+ //=== VK_EXT_multi_draw ===
+ vkCmdDrawMultiEXT = PFN_vkCmdDrawMultiEXT( vkGetInstanceProcAddr( instance, "vkCmdDrawMultiEXT" ) );
+ vkCmdDrawMultiIndexedEXT = PFN_vkCmdDrawMultiIndexedEXT( vkGetInstanceProcAddr( instance, "vkCmdDrawMultiIndexedEXT" ) );
+
+ //=== VK_EXT_opacity_micromap ===
+ vkCreateMicromapEXT = PFN_vkCreateMicromapEXT( vkGetInstanceProcAddr( instance, "vkCreateMicromapEXT" ) );
+ vkDestroyMicromapEXT = PFN_vkDestroyMicromapEXT( vkGetInstanceProcAddr( instance, "vkDestroyMicromapEXT" ) );
+ vkCmdBuildMicromapsEXT = PFN_vkCmdBuildMicromapsEXT( vkGetInstanceProcAddr( instance, "vkCmdBuildMicromapsEXT" ) );
+ vkBuildMicromapsEXT = PFN_vkBuildMicromapsEXT( vkGetInstanceProcAddr( instance, "vkBuildMicromapsEXT" ) );
+ vkCopyMicromapEXT = PFN_vkCopyMicromapEXT( vkGetInstanceProcAddr( instance, "vkCopyMicromapEXT" ) );
+ vkCopyMicromapToMemoryEXT = PFN_vkCopyMicromapToMemoryEXT( vkGetInstanceProcAddr( instance, "vkCopyMicromapToMemoryEXT" ) );
+ vkCopyMemoryToMicromapEXT = PFN_vkCopyMemoryToMicromapEXT( vkGetInstanceProcAddr( instance, "vkCopyMemoryToMicromapEXT" ) );
+ vkWriteMicromapsPropertiesEXT = PFN_vkWriteMicromapsPropertiesEXT( vkGetInstanceProcAddr( instance, "vkWriteMicromapsPropertiesEXT" ) );
+ vkCmdCopyMicromapEXT = PFN_vkCmdCopyMicromapEXT( vkGetInstanceProcAddr( instance, "vkCmdCopyMicromapEXT" ) );
+ vkCmdCopyMicromapToMemoryEXT = PFN_vkCmdCopyMicromapToMemoryEXT( vkGetInstanceProcAddr( instance, "vkCmdCopyMicromapToMemoryEXT" ) );
+ vkCmdCopyMemoryToMicromapEXT = PFN_vkCmdCopyMemoryToMicromapEXT( vkGetInstanceProcAddr( instance, "vkCmdCopyMemoryToMicromapEXT" ) );
+ vkCmdWriteMicromapsPropertiesEXT = PFN_vkCmdWriteMicromapsPropertiesEXT( vkGetInstanceProcAddr( instance, "vkCmdWriteMicromapsPropertiesEXT" ) );
+ vkGetDeviceMicromapCompatibilityEXT = PFN_vkGetDeviceMicromapCompatibilityEXT( vkGetInstanceProcAddr( instance, "vkGetDeviceMicromapCompatibilityEXT" ) );
+ vkGetMicromapBuildSizesEXT = PFN_vkGetMicromapBuildSizesEXT( vkGetInstanceProcAddr( instance, "vkGetMicromapBuildSizesEXT" ) );
+
+ //=== VK_EXT_pageable_device_local_memory ===
+ vkSetDeviceMemoryPriorityEXT = PFN_vkSetDeviceMemoryPriorityEXT( vkGetInstanceProcAddr( instance, "vkSetDeviceMemoryPriorityEXT" ) );
+
+ //=== VK_KHR_maintenance4 ===
+ vkGetDeviceBufferMemoryRequirementsKHR =
+ PFN_vkGetDeviceBufferMemoryRequirementsKHR( vkGetInstanceProcAddr( instance, "vkGetDeviceBufferMemoryRequirementsKHR" ) );
+ if ( !vkGetDeviceBufferMemoryRequirements )
+ vkGetDeviceBufferMemoryRequirements = vkGetDeviceBufferMemoryRequirementsKHR;
+ vkGetDeviceImageMemoryRequirementsKHR =
+ PFN_vkGetDeviceImageMemoryRequirementsKHR( vkGetInstanceProcAddr( instance, "vkGetDeviceImageMemoryRequirementsKHR" ) );
+ if ( !vkGetDeviceImageMemoryRequirements )
+ vkGetDeviceImageMemoryRequirements = vkGetDeviceImageMemoryRequirementsKHR;
+ vkGetDeviceImageSparseMemoryRequirementsKHR =
+ PFN_vkGetDeviceImageSparseMemoryRequirementsKHR( vkGetInstanceProcAddr( instance, "vkGetDeviceImageSparseMemoryRequirementsKHR" ) );
+ if ( !vkGetDeviceImageSparseMemoryRequirements )
+ vkGetDeviceImageSparseMemoryRequirements = vkGetDeviceImageSparseMemoryRequirementsKHR;
+
+ //=== VK_VALVE_descriptor_set_host_mapping ===
+ vkGetDescriptorSetLayoutHostMappingInfoVALVE =
+ PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE( vkGetInstanceProcAddr( instance, "vkGetDescriptorSetLayoutHostMappingInfoVALVE" ) );
+ vkGetDescriptorSetHostMappingVALVE = PFN_vkGetDescriptorSetHostMappingVALVE( vkGetInstanceProcAddr( instance, "vkGetDescriptorSetHostMappingVALVE" ) );
+
+ //=== VK_EXT_extended_dynamic_state3 ===
+ vkCmdSetTessellationDomainOriginEXT = PFN_vkCmdSetTessellationDomainOriginEXT( vkGetInstanceProcAddr( instance, "vkCmdSetTessellationDomainOriginEXT" ) );
+ vkCmdSetDepthClampEnableEXT = PFN_vkCmdSetDepthClampEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetDepthClampEnableEXT" ) );
+ vkCmdSetPolygonModeEXT = PFN_vkCmdSetPolygonModeEXT( vkGetInstanceProcAddr( instance, "vkCmdSetPolygonModeEXT" ) );
+ vkCmdSetRasterizationSamplesEXT = PFN_vkCmdSetRasterizationSamplesEXT( vkGetInstanceProcAddr( instance, "vkCmdSetRasterizationSamplesEXT" ) );
+ vkCmdSetSampleMaskEXT = PFN_vkCmdSetSampleMaskEXT( vkGetInstanceProcAddr( instance, "vkCmdSetSampleMaskEXT" ) );
+ vkCmdSetAlphaToCoverageEnableEXT = PFN_vkCmdSetAlphaToCoverageEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetAlphaToCoverageEnableEXT" ) );
+ vkCmdSetAlphaToOneEnableEXT = PFN_vkCmdSetAlphaToOneEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetAlphaToOneEnableEXT" ) );
+ vkCmdSetLogicOpEnableEXT = PFN_vkCmdSetLogicOpEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetLogicOpEnableEXT" ) );
+ vkCmdSetColorBlendEnableEXT = PFN_vkCmdSetColorBlendEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetColorBlendEnableEXT" ) );
+ vkCmdSetColorBlendEquationEXT = PFN_vkCmdSetColorBlendEquationEXT( vkGetInstanceProcAddr( instance, "vkCmdSetColorBlendEquationEXT" ) );
+ vkCmdSetColorWriteMaskEXT = PFN_vkCmdSetColorWriteMaskEXT( vkGetInstanceProcAddr( instance, "vkCmdSetColorWriteMaskEXT" ) );
+ vkCmdSetRasterizationStreamEXT = PFN_vkCmdSetRasterizationStreamEXT( vkGetInstanceProcAddr( instance, "vkCmdSetRasterizationStreamEXT" ) );
+ vkCmdSetConservativeRasterizationModeEXT =
+ PFN_vkCmdSetConservativeRasterizationModeEXT( vkGetInstanceProcAddr( instance, "vkCmdSetConservativeRasterizationModeEXT" ) );
+ vkCmdSetExtraPrimitiveOverestimationSizeEXT =
+ PFN_vkCmdSetExtraPrimitiveOverestimationSizeEXT( vkGetInstanceProcAddr( instance, "vkCmdSetExtraPrimitiveOverestimationSizeEXT" ) );
+ vkCmdSetDepthClipEnableEXT = PFN_vkCmdSetDepthClipEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetDepthClipEnableEXT" ) );
+ vkCmdSetSampleLocationsEnableEXT = PFN_vkCmdSetSampleLocationsEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetSampleLocationsEnableEXT" ) );
+ vkCmdSetColorBlendAdvancedEXT = PFN_vkCmdSetColorBlendAdvancedEXT( vkGetInstanceProcAddr( instance, "vkCmdSetColorBlendAdvancedEXT" ) );
+ vkCmdSetProvokingVertexModeEXT = PFN_vkCmdSetProvokingVertexModeEXT( vkGetInstanceProcAddr( instance, "vkCmdSetProvokingVertexModeEXT" ) );
+ vkCmdSetLineRasterizationModeEXT = PFN_vkCmdSetLineRasterizationModeEXT( vkGetInstanceProcAddr( instance, "vkCmdSetLineRasterizationModeEXT" ) );
+ vkCmdSetLineStippleEnableEXT = PFN_vkCmdSetLineStippleEnableEXT( vkGetInstanceProcAddr( instance, "vkCmdSetLineStippleEnableEXT" ) );
+ vkCmdSetDepthClipNegativeOneToOneEXT =
+ PFN_vkCmdSetDepthClipNegativeOneToOneEXT( vkGetInstanceProcAddr( instance, "vkCmdSetDepthClipNegativeOneToOneEXT" ) );
+ vkCmdSetViewportWScalingEnableNV = PFN_vkCmdSetViewportWScalingEnableNV( vkGetInstanceProcAddr( instance, "vkCmdSetViewportWScalingEnableNV" ) );
+ vkCmdSetViewportSwizzleNV = PFN_vkCmdSetViewportSwizzleNV( vkGetInstanceProcAddr( instance, "vkCmdSetViewportSwizzleNV" ) );
+ vkCmdSetCoverageToColorEnableNV = PFN_vkCmdSetCoverageToColorEnableNV( vkGetInstanceProcAddr( instance, "vkCmdSetCoverageToColorEnableNV" ) );
+ vkCmdSetCoverageToColorLocationNV = PFN_vkCmdSetCoverageToColorLocationNV( vkGetInstanceProcAddr( instance, "vkCmdSetCoverageToColorLocationNV" ) );
+ vkCmdSetCoverageModulationModeNV = PFN_vkCmdSetCoverageModulationModeNV( vkGetInstanceProcAddr( instance, "vkCmdSetCoverageModulationModeNV" ) );
+ vkCmdSetCoverageModulationTableEnableNV =
+ PFN_vkCmdSetCoverageModulationTableEnableNV( vkGetInstanceProcAddr( instance, "vkCmdSetCoverageModulationTableEnableNV" ) );
+ vkCmdSetCoverageModulationTableNV = PFN_vkCmdSetCoverageModulationTableNV( vkGetInstanceProcAddr( instance, "vkCmdSetCoverageModulationTableNV" ) );
+ vkCmdSetShadingRateImageEnableNV = PFN_vkCmdSetShadingRateImageEnableNV( vkGetInstanceProcAddr( instance, "vkCmdSetShadingRateImageEnableNV" ) );
+ vkCmdSetRepresentativeFragmentTestEnableNV =
+ PFN_vkCmdSetRepresentativeFragmentTestEnableNV( vkGetInstanceProcAddr( instance, "vkCmdSetRepresentativeFragmentTestEnableNV" ) );
+ vkCmdSetCoverageReductionModeNV = PFN_vkCmdSetCoverageReductionModeNV( vkGetInstanceProcAddr( instance, "vkCmdSetCoverageReductionModeNV" ) );
+
+ //=== VK_EXT_shader_module_identifier ===
+ vkGetShaderModuleIdentifierEXT = PFN_vkGetShaderModuleIdentifierEXT( vkGetInstanceProcAddr( instance, "vkGetShaderModuleIdentifierEXT" ) );
+ vkGetShaderModuleCreateInfoIdentifierEXT =
+ PFN_vkGetShaderModuleCreateInfoIdentifierEXT( vkGetInstanceProcAddr( instance, "vkGetShaderModuleCreateInfoIdentifierEXT" ) );
+
+ //=== VK_NV_optical_flow ===
+ vkGetPhysicalDeviceOpticalFlowImageFormatsNV =
+ PFN_vkGetPhysicalDeviceOpticalFlowImageFormatsNV( vkGetInstanceProcAddr( instance, "vkGetPhysicalDeviceOpticalFlowImageFormatsNV" ) );
+ vkCreateOpticalFlowSessionNV = PFN_vkCreateOpticalFlowSessionNV( vkGetInstanceProcAddr( instance, "vkCreateOpticalFlowSessionNV" ) );
+ vkDestroyOpticalFlowSessionNV = PFN_vkDestroyOpticalFlowSessionNV( vkGetInstanceProcAddr( instance, "vkDestroyOpticalFlowSessionNV" ) );
+ vkBindOpticalFlowSessionImageNV = PFN_vkBindOpticalFlowSessionImageNV( vkGetInstanceProcAddr( instance, "vkBindOpticalFlowSessionImageNV" ) );
+ vkCmdOpticalFlowExecuteNV = PFN_vkCmdOpticalFlowExecuteNV( vkGetInstanceProcAddr( instance, "vkCmdOpticalFlowExecuteNV" ) );
+
+ //=== VK_QCOM_tile_properties ===
+ vkGetFramebufferTilePropertiesQCOM = PFN_vkGetFramebufferTilePropertiesQCOM( vkGetInstanceProcAddr( instance, "vkGetFramebufferTilePropertiesQCOM" ) );
+ vkGetDynamicRenderingTilePropertiesQCOM =
+ PFN_vkGetDynamicRenderingTilePropertiesQCOM( vkGetInstanceProcAddr( instance, "vkGetDynamicRenderingTilePropertiesQCOM" ) );
+ }
+
+ void init( VULKAN_HPP_NAMESPACE::Device deviceCpp ) VULKAN_HPP_NOEXCEPT
+ {
+ VkDevice device = static_cast<VkDevice>( deviceCpp );
+
+ //=== VK_VERSION_1_0 ===
+ vkGetDeviceProcAddr = PFN_vkGetDeviceProcAddr( vkGetDeviceProcAddr( device, "vkGetDeviceProcAddr" ) );
+ vkDestroyDevice = PFN_vkDestroyDevice( vkGetDeviceProcAddr( device, "vkDestroyDevice" ) );
+ vkGetDeviceQueue = PFN_vkGetDeviceQueue( vkGetDeviceProcAddr( device, "vkGetDeviceQueue" ) );
+ vkQueueSubmit = PFN_vkQueueSubmit( vkGetDeviceProcAddr( device, "vkQueueSubmit" ) );
+ vkQueueWaitIdle = PFN_vkQueueWaitIdle( vkGetDeviceProcAddr( device, "vkQueueWaitIdle" ) );
+ vkDeviceWaitIdle = PFN_vkDeviceWaitIdle( vkGetDeviceProcAddr( device, "vkDeviceWaitIdle" ) );
+ vkAllocateMemory = PFN_vkAllocateMemory( vkGetDeviceProcAddr( device, "vkAllocateMemory" ) );
+ vkFreeMemory = PFN_vkFreeMemory( vkGetDeviceProcAddr( device, "vkFreeMemory" ) );
+ vkMapMemory = PFN_vkMapMemory( vkGetDeviceProcAddr( device, "vkMapMemory" ) );
+ vkUnmapMemory = PFN_vkUnmapMemory( vkGetDeviceProcAddr( device, "vkUnmapMemory" ) );
+ vkFlushMappedMemoryRanges = PFN_vkFlushMappedMemoryRanges( vkGetDeviceProcAddr( device, "vkFlushMappedMemoryRanges" ) );
+ vkInvalidateMappedMemoryRanges = PFN_vkInvalidateMappedMemoryRanges( vkGetDeviceProcAddr( device, "vkInvalidateMappedMemoryRanges" ) );
+ vkGetDeviceMemoryCommitment = PFN_vkGetDeviceMemoryCommitment( vkGetDeviceProcAddr( device, "vkGetDeviceMemoryCommitment" ) );
+ vkBindBufferMemory = PFN_vkBindBufferMemory( vkGetDeviceProcAddr( device, "vkBindBufferMemory" ) );
+ vkBindImageMemory = PFN_vkBindImageMemory( vkGetDeviceProcAddr( device, "vkBindImageMemory" ) );
+ vkGetBufferMemoryRequirements = PFN_vkGetBufferMemoryRequirements( vkGetDeviceProcAddr( device, "vkGetBufferMemoryRequirements" ) );
+ vkGetImageMemoryRequirements = PFN_vkGetImageMemoryRequirements( vkGetDeviceProcAddr( device, "vkGetImageMemoryRequirements" ) );
+ vkGetImageSparseMemoryRequirements = PFN_vkGetImageSparseMemoryRequirements( vkGetDeviceProcAddr( device, "vkGetImageSparseMemoryRequirements" ) );
+ vkQueueBindSparse = PFN_vkQueueBindSparse( vkGetDeviceProcAddr( device, "vkQueueBindSparse" ) );
+ vkCreateFence = PFN_vkCreateFence( vkGetDeviceProcAddr( device, "vkCreateFence" ) );
+ vkDestroyFence = PFN_vkDestroyFence( vkGetDeviceProcAddr( device, "vkDestroyFence" ) );
+ vkResetFences = PFN_vkResetFences( vkGetDeviceProcAddr( device, "vkResetFences" ) );
+ vkGetFenceStatus = PFN_vkGetFenceStatus( vkGetDeviceProcAddr( device, "vkGetFenceStatus" ) );
+ vkWaitForFences = PFN_vkWaitForFences( vkGetDeviceProcAddr( device, "vkWaitForFences" ) );
+ vkCreateSemaphore = PFN_vkCreateSemaphore( vkGetDeviceProcAddr( device, "vkCreateSemaphore" ) );
+ vkDestroySemaphore = PFN_vkDestroySemaphore( vkGetDeviceProcAddr( device, "vkDestroySemaphore" ) );
+ vkCreateEvent = PFN_vkCreateEvent( vkGetDeviceProcAddr( device, "vkCreateEvent" ) );
+ vkDestroyEvent = PFN_vkDestroyEvent( vkGetDeviceProcAddr( device, "vkDestroyEvent" ) );
+ vkGetEventStatus = PFN_vkGetEventStatus( vkGetDeviceProcAddr( device, "vkGetEventStatus" ) );
+ vkSetEvent = PFN_vkSetEvent( vkGetDeviceProcAddr( device, "vkSetEvent" ) );
+ vkResetEvent = PFN_vkResetEvent( vkGetDeviceProcAddr( device, "vkResetEvent" ) );
+ vkCreateQueryPool = PFN_vkCreateQueryPool( vkGetDeviceProcAddr( device, "vkCreateQueryPool" ) );
+ vkDestroyQueryPool = PFN_vkDestroyQueryPool( vkGetDeviceProcAddr( device, "vkDestroyQueryPool" ) );
+ vkGetQueryPoolResults = PFN_vkGetQueryPoolResults( vkGetDeviceProcAddr( device, "vkGetQueryPoolResults" ) );
+ vkCreateBuffer = PFN_vkCreateBuffer( vkGetDeviceProcAddr( device, "vkCreateBuffer" ) );
+ vkDestroyBuffer = PFN_vkDestroyBuffer( vkGetDeviceProcAddr( device, "vkDestroyBuffer" ) );
+ vkCreateBufferView = PFN_vkCreateBufferView( vkGetDeviceProcAddr( device, "vkCreateBufferView" ) );
+ vkDestroyBufferView = PFN_vkDestroyBufferView( vkGetDeviceProcAddr( device, "vkDestroyBufferView" ) );
+ vkCreateImage = PFN_vkCreateImage( vkGetDeviceProcAddr( device, "vkCreateImage" ) );
+ vkDestroyImage = PFN_vkDestroyImage( vkGetDeviceProcAddr( device, "vkDestroyImage" ) );
+ vkGetImageSubresourceLayout = PFN_vkGetImageSubresourceLayout( vkGetDeviceProcAddr( device, "vkGetImageSubresourceLayout" ) );
+ vkCreateImageView = PFN_vkCreateImageView( vkGetDeviceProcAddr( device, "vkCreateImageView" ) );
+ vkDestroyImageView = PFN_vkDestroyImageView( vkGetDeviceProcAddr( device, "vkDestroyImageView" ) );
+ vkCreateShaderModule = PFN_vkCreateShaderModule( vkGetDeviceProcAddr( device, "vkCreateShaderModule" ) );
+ vkDestroyShaderModule = PFN_vkDestroyShaderModule( vkGetDeviceProcAddr( device, "vkDestroyShaderModule" ) );
+ vkCreatePipelineCache = PFN_vkCreatePipelineCache( vkGetDeviceProcAddr( device, "vkCreatePipelineCache" ) );
+ vkDestroyPipelineCache = PFN_vkDestroyPipelineCache( vkGetDeviceProcAddr( device, "vkDestroyPipelineCache" ) );
+ vkGetPipelineCacheData = PFN_vkGetPipelineCacheData( vkGetDeviceProcAddr( device, "vkGetPipelineCacheData" ) );
+ vkMergePipelineCaches = PFN_vkMergePipelineCaches( vkGetDeviceProcAddr( device, "vkMergePipelineCaches" ) );
+ vkCreateGraphicsPipelines = PFN_vkCreateGraphicsPipelines( vkGetDeviceProcAddr( device, "vkCreateGraphicsPipelines" ) );
+ vkCreateComputePipelines = PFN_vkCreateComputePipelines( vkGetDeviceProcAddr( device, "vkCreateComputePipelines" ) );
+ vkDestroyPipeline = PFN_vkDestroyPipeline( vkGetDeviceProcAddr( device, "vkDestroyPipeline" ) );
+ vkCreatePipelineLayout = PFN_vkCreatePipelineLayout( vkGetDeviceProcAddr( device, "vkCreatePipelineLayout" ) );
+ vkDestroyPipelineLayout = PFN_vkDestroyPipelineLayout( vkGetDeviceProcAddr( device, "vkDestroyPipelineLayout" ) );
+ vkCreateSampler = PFN_vkCreateSampler( vkGetDeviceProcAddr( device, "vkCreateSampler" ) );
+ vkDestroySampler = PFN_vkDestroySampler( vkGetDeviceProcAddr( device, "vkDestroySampler" ) );
+ vkCreateDescriptorSetLayout = PFN_vkCreateDescriptorSetLayout( vkGetDeviceProcAddr( device, "vkCreateDescriptorSetLayout" ) );
+ vkDestroyDescriptorSetLayout = PFN_vkDestroyDescriptorSetLayout( vkGetDeviceProcAddr( device, "vkDestroyDescriptorSetLayout" ) );
+ vkCreateDescriptorPool = PFN_vkCreateDescriptorPool( vkGetDeviceProcAddr( device, "vkCreateDescriptorPool" ) );
+ vkDestroyDescriptorPool = PFN_vkDestroyDescriptorPool( vkGetDeviceProcAddr( device, "vkDestroyDescriptorPool" ) );
+ vkResetDescriptorPool = PFN_vkResetDescriptorPool( vkGetDeviceProcAddr( device, "vkResetDescriptorPool" ) );
+ vkAllocateDescriptorSets = PFN_vkAllocateDescriptorSets( vkGetDeviceProcAddr( device, "vkAllocateDescriptorSets" ) );
+ vkFreeDescriptorSets = PFN_vkFreeDescriptorSets( vkGetDeviceProcAddr( device, "vkFreeDescriptorSets" ) );
+ vkUpdateDescriptorSets = PFN_vkUpdateDescriptorSets( vkGetDeviceProcAddr( device, "vkUpdateDescriptorSets" ) );
+ vkCreateFramebuffer = PFN_vkCreateFramebuffer( vkGetDeviceProcAddr( device, "vkCreateFramebuffer" ) );
+ vkDestroyFramebuffer = PFN_vkDestroyFramebuffer( vkGetDeviceProcAddr( device, "vkDestroyFramebuffer" ) );
+ vkCreateRenderPass = PFN_vkCreateRenderPass( vkGetDeviceProcAddr( device, "vkCreateRenderPass" ) );
+ vkDestroyRenderPass = PFN_vkDestroyRenderPass( vkGetDeviceProcAddr( device, "vkDestroyRenderPass" ) );
+ vkGetRenderAreaGranularity = PFN_vkGetRenderAreaGranularity( vkGetDeviceProcAddr( device, "vkGetRenderAreaGranularity" ) );
+ vkCreateCommandPool = PFN_vkCreateCommandPool( vkGetDeviceProcAddr( device, "vkCreateCommandPool" ) );
+ vkDestroyCommandPool = PFN_vkDestroyCommandPool( vkGetDeviceProcAddr( device, "vkDestroyCommandPool" ) );
+ vkResetCommandPool = PFN_vkResetCommandPool( vkGetDeviceProcAddr( device, "vkResetCommandPool" ) );
+ vkAllocateCommandBuffers = PFN_vkAllocateCommandBuffers( vkGetDeviceProcAddr( device, "vkAllocateCommandBuffers" ) );
+ vkFreeCommandBuffers = PFN_vkFreeCommandBuffers( vkGetDeviceProcAddr( device, "vkFreeCommandBuffers" ) );
+ vkBeginCommandBuffer = PFN_vkBeginCommandBuffer( vkGetDeviceProcAddr( device, "vkBeginCommandBuffer" ) );
+ vkEndCommandBuffer = PFN_vkEndCommandBuffer( vkGetDeviceProcAddr( device, "vkEndCommandBuffer" ) );
+ vkResetCommandBuffer = PFN_vkResetCommandBuffer( vkGetDeviceProcAddr( device, "vkResetCommandBuffer" ) );
+ vkCmdBindPipeline = PFN_vkCmdBindPipeline( vkGetDeviceProcAddr( device, "vkCmdBindPipeline" ) );
+ vkCmdSetViewport = PFN_vkCmdSetViewport( vkGetDeviceProcAddr( device, "vkCmdSetViewport" ) );
+ vkCmdSetScissor = PFN_vkCmdSetScissor( vkGetDeviceProcAddr( device, "vkCmdSetScissor" ) );
+ vkCmdSetLineWidth = PFN_vkCmdSetLineWidth( vkGetDeviceProcAddr( device, "vkCmdSetLineWidth" ) );
+ vkCmdSetDepthBias = PFN_vkCmdSetDepthBias( vkGetDeviceProcAddr( device, "vkCmdSetDepthBias" ) );
+ vkCmdSetBlendConstants = PFN_vkCmdSetBlendConstants( vkGetDeviceProcAddr( device, "vkCmdSetBlendConstants" ) );
+ vkCmdSetDepthBounds = PFN_vkCmdSetDepthBounds( vkGetDeviceProcAddr( device, "vkCmdSetDepthBounds" ) );
+ vkCmdSetStencilCompareMask = PFN_vkCmdSetStencilCompareMask( vkGetDeviceProcAddr( device, "vkCmdSetStencilCompareMask" ) );
+ vkCmdSetStencilWriteMask = PFN_vkCmdSetStencilWriteMask( vkGetDeviceProcAddr( device, "vkCmdSetStencilWriteMask" ) );
+ vkCmdSetStencilReference = PFN_vkCmdSetStencilReference( vkGetDeviceProcAddr( device, "vkCmdSetStencilReference" ) );
+ vkCmdBindDescriptorSets = PFN_vkCmdBindDescriptorSets( vkGetDeviceProcAddr( device, "vkCmdBindDescriptorSets" ) );
+ vkCmdBindIndexBuffer = PFN_vkCmdBindIndexBuffer( vkGetDeviceProcAddr( device, "vkCmdBindIndexBuffer" ) );
+ vkCmdBindVertexBuffers = PFN_vkCmdBindVertexBuffers( vkGetDeviceProcAddr( device, "vkCmdBindVertexBuffers" ) );
+ vkCmdDraw = PFN_vkCmdDraw( vkGetDeviceProcAddr( device, "vkCmdDraw" ) );
+ vkCmdDrawIndexed = PFN_vkCmdDrawIndexed( vkGetDeviceProcAddr( device, "vkCmdDrawIndexed" ) );
+ vkCmdDrawIndirect = PFN_vkCmdDrawIndirect( vkGetDeviceProcAddr( device, "vkCmdDrawIndirect" ) );
+ vkCmdDrawIndexedIndirect = PFN_vkCmdDrawIndexedIndirect( vkGetDeviceProcAddr( device, "vkCmdDrawIndexedIndirect" ) );
+ vkCmdDispatch = PFN_vkCmdDispatch( vkGetDeviceProcAddr( device, "vkCmdDispatch" ) );
+ vkCmdDispatchIndirect = PFN_vkCmdDispatchIndirect( vkGetDeviceProcAddr( device, "vkCmdDispatchIndirect" ) );
+ vkCmdCopyBuffer = PFN_vkCmdCopyBuffer( vkGetDeviceProcAddr( device, "vkCmdCopyBuffer" ) );
+ vkCmdCopyImage = PFN_vkCmdCopyImage( vkGetDeviceProcAddr( device, "vkCmdCopyImage" ) );
+ vkCmdBlitImage = PFN_vkCmdBlitImage( vkGetDeviceProcAddr( device, "vkCmdBlitImage" ) );
+ vkCmdCopyBufferToImage = PFN_vkCmdCopyBufferToImage( vkGetDeviceProcAddr( device, "vkCmdCopyBufferToImage" ) );
+ vkCmdCopyImageToBuffer = PFN_vkCmdCopyImageToBuffer( vkGetDeviceProcAddr( device, "vkCmdCopyImageToBuffer" ) );
+ vkCmdUpdateBuffer = PFN_vkCmdUpdateBuffer( vkGetDeviceProcAddr( device, "vkCmdUpdateBuffer" ) );
+ vkCmdFillBuffer = PFN_vkCmdFillBuffer( vkGetDeviceProcAddr( device, "vkCmdFillBuffer" ) );
+ vkCmdClearColorImage = PFN_vkCmdClearColorImage( vkGetDeviceProcAddr( device, "vkCmdClearColorImage" ) );
+ vkCmdClearDepthStencilImage = PFN_vkCmdClearDepthStencilImage( vkGetDeviceProcAddr( device, "vkCmdClearDepthStencilImage" ) );
+ vkCmdClearAttachments = PFN_vkCmdClearAttachments( vkGetDeviceProcAddr( device, "vkCmdClearAttachments" ) );
+ vkCmdResolveImage = PFN_vkCmdResolveImage( vkGetDeviceProcAddr( device, "vkCmdResolveImage" ) );
+ vkCmdSetEvent = PFN_vkCmdSetEvent( vkGetDeviceProcAddr( device, "vkCmdSetEvent" ) );
+ vkCmdResetEvent = PFN_vkCmdResetEvent( vkGetDeviceProcAddr( device, "vkCmdResetEvent" ) );
+ vkCmdWaitEvents = PFN_vkCmdWaitEvents( vkGetDeviceProcAddr( device, "vkCmdWaitEvents" ) );
+ vkCmdPipelineBarrier = PFN_vkCmdPipelineBarrier( vkGetDeviceProcAddr( device, "vkCmdPipelineBarrier" ) );
+ vkCmdBeginQuery = PFN_vkCmdBeginQuery( vkGetDeviceProcAddr( device, "vkCmdBeginQuery" ) );
+ vkCmdEndQuery = PFN_vkCmdEndQuery( vkGetDeviceProcAddr( device, "vkCmdEndQuery" ) );
+ vkCmdResetQueryPool = PFN_vkCmdResetQueryPool( vkGetDeviceProcAddr( device, "vkCmdResetQueryPool" ) );
+ vkCmdWriteTimestamp = PFN_vkCmdWriteTimestamp( vkGetDeviceProcAddr( device, "vkCmdWriteTimestamp" ) );
+ vkCmdCopyQueryPoolResults = PFN_vkCmdCopyQueryPoolResults( vkGetDeviceProcAddr( device, "vkCmdCopyQueryPoolResults" ) );
+ vkCmdPushConstants = PFN_vkCmdPushConstants( vkGetDeviceProcAddr( device, "vkCmdPushConstants" ) );
+ vkCmdBeginRenderPass = PFN_vkCmdBeginRenderPass( vkGetDeviceProcAddr( device, "vkCmdBeginRenderPass" ) );
+ vkCmdNextSubpass = PFN_vkCmdNextSubpass( vkGetDeviceProcAddr( device, "vkCmdNextSubpass" ) );
+ vkCmdEndRenderPass = PFN_vkCmdEndRenderPass( vkGetDeviceProcAddr( device, "vkCmdEndRenderPass" ) );
+ vkCmdExecuteCommands = PFN_vkCmdExecuteCommands( vkGetDeviceProcAddr( device, "vkCmdExecuteCommands" ) );
+
+ //=== VK_VERSION_1_1 ===
+ vkBindBufferMemory2 = PFN_vkBindBufferMemory2( vkGetDeviceProcAddr( device, "vkBindBufferMemory2" ) );
+ vkBindImageMemory2 = PFN_vkBindImageMemory2( vkGetDeviceProcAddr( device, "vkBindImageMemory2" ) );
+ vkGetDeviceGroupPeerMemoryFeatures = PFN_vkGetDeviceGroupPeerMemoryFeatures( vkGetDeviceProcAddr( device, "vkGetDeviceGroupPeerMemoryFeatures" ) );
+ vkCmdSetDeviceMask = PFN_vkCmdSetDeviceMask( vkGetDeviceProcAddr( device, "vkCmdSetDeviceMask" ) );
+ vkCmdDispatchBase = PFN_vkCmdDispatchBase( vkGetDeviceProcAddr( device, "vkCmdDispatchBase" ) );
+ vkGetImageMemoryRequirements2 = PFN_vkGetImageMemoryRequirements2( vkGetDeviceProcAddr( device, "vkGetImageMemoryRequirements2" ) );
+ vkGetBufferMemoryRequirements2 = PFN_vkGetBufferMemoryRequirements2( vkGetDeviceProcAddr( device, "vkGetBufferMemoryRequirements2" ) );
+ vkGetImageSparseMemoryRequirements2 = PFN_vkGetImageSparseMemoryRequirements2( vkGetDeviceProcAddr( device, "vkGetImageSparseMemoryRequirements2" ) );
+ vkTrimCommandPool = PFN_vkTrimCommandPool( vkGetDeviceProcAddr( device, "vkTrimCommandPool" ) );
+ vkGetDeviceQueue2 = PFN_vkGetDeviceQueue2( vkGetDeviceProcAddr( device, "vkGetDeviceQueue2" ) );
+ vkCreateSamplerYcbcrConversion = PFN_vkCreateSamplerYcbcrConversion( vkGetDeviceProcAddr( device, "vkCreateSamplerYcbcrConversion" ) );
+ vkDestroySamplerYcbcrConversion = PFN_vkDestroySamplerYcbcrConversion( vkGetDeviceProcAddr( device, "vkDestroySamplerYcbcrConversion" ) );
+ vkCreateDescriptorUpdateTemplate = PFN_vkCreateDescriptorUpdateTemplate( vkGetDeviceProcAddr( device, "vkCreateDescriptorUpdateTemplate" ) );
+ vkDestroyDescriptorUpdateTemplate = PFN_vkDestroyDescriptorUpdateTemplate( vkGetDeviceProcAddr( device, "vkDestroyDescriptorUpdateTemplate" ) );
+ vkUpdateDescriptorSetWithTemplate = PFN_vkUpdateDescriptorSetWithTemplate( vkGetDeviceProcAddr( device, "vkUpdateDescriptorSetWithTemplate" ) );
+ vkGetDescriptorSetLayoutSupport = PFN_vkGetDescriptorSetLayoutSupport( vkGetDeviceProcAddr( device, "vkGetDescriptorSetLayoutSupport" ) );
+
+ //=== VK_VERSION_1_2 ===
+ vkCmdDrawIndirectCount = PFN_vkCmdDrawIndirectCount( vkGetDeviceProcAddr( device, "vkCmdDrawIndirectCount" ) );
+ vkCmdDrawIndexedIndirectCount = PFN_vkCmdDrawIndexedIndirectCount( vkGetDeviceProcAddr( device, "vkCmdDrawIndexedIndirectCount" ) );
+ vkCreateRenderPass2 = PFN_vkCreateRenderPass2( vkGetDeviceProcAddr( device, "vkCreateRenderPass2" ) );
+ vkCmdBeginRenderPass2 = PFN_vkCmdBeginRenderPass2( vkGetDeviceProcAddr( device, "vkCmdBeginRenderPass2" ) );
+ vkCmdNextSubpass2 = PFN_vkCmdNextSubpass2( vkGetDeviceProcAddr( device, "vkCmdNextSubpass2" ) );
+ vkCmdEndRenderPass2 = PFN_vkCmdEndRenderPass2( vkGetDeviceProcAddr( device, "vkCmdEndRenderPass2" ) );
+ vkResetQueryPool = PFN_vkResetQueryPool( vkGetDeviceProcAddr( device, "vkResetQueryPool" ) );
+ vkGetSemaphoreCounterValue = PFN_vkGetSemaphoreCounterValue( vkGetDeviceProcAddr( device, "vkGetSemaphoreCounterValue" ) );
+ vkWaitSemaphores = PFN_vkWaitSemaphores( vkGetDeviceProcAddr( device, "vkWaitSemaphores" ) );
+ vkSignalSemaphore = PFN_vkSignalSemaphore( vkGetDeviceProcAddr( device, "vkSignalSemaphore" ) );
+ vkGetBufferDeviceAddress = PFN_vkGetBufferDeviceAddress( vkGetDeviceProcAddr( device, "vkGetBufferDeviceAddress" ) );
+ vkGetBufferOpaqueCaptureAddress = PFN_vkGetBufferOpaqueCaptureAddress( vkGetDeviceProcAddr( device, "vkGetBufferOpaqueCaptureAddress" ) );
+ vkGetDeviceMemoryOpaqueCaptureAddress =
+ PFN_vkGetDeviceMemoryOpaqueCaptureAddress( vkGetDeviceProcAddr( device, "vkGetDeviceMemoryOpaqueCaptureAddress" ) );
+
+ //=== VK_VERSION_1_3 ===
+ vkCreatePrivateDataSlot = PFN_vkCreatePrivateDataSlot( vkGetDeviceProcAddr( device, "vkCreatePrivateDataSlot" ) );
+ vkDestroyPrivateDataSlot = PFN_vkDestroyPrivateDataSlot( vkGetDeviceProcAddr( device, "vkDestroyPrivateDataSlot" ) );
+ vkSetPrivateData = PFN_vkSetPrivateData( vkGetDeviceProcAddr( device, "vkSetPrivateData" ) );
+ vkGetPrivateData = PFN_vkGetPrivateData( vkGetDeviceProcAddr( device, "vkGetPrivateData" ) );
+ vkCmdSetEvent2 = PFN_vkCmdSetEvent2( vkGetDeviceProcAddr( device, "vkCmdSetEvent2" ) );
+ vkCmdResetEvent2 = PFN_vkCmdResetEvent2( vkGetDeviceProcAddr( device, "vkCmdResetEvent2" ) );
+ vkCmdWaitEvents2 = PFN_vkCmdWaitEvents2( vkGetDeviceProcAddr( device, "vkCmdWaitEvents2" ) );
+ vkCmdPipelineBarrier2 = PFN_vkCmdPipelineBarrier2( vkGetDeviceProcAddr( device, "vkCmdPipelineBarrier2" ) );
+ vkCmdWriteTimestamp2 = PFN_vkCmdWriteTimestamp2( vkGetDeviceProcAddr( device, "vkCmdWriteTimestamp2" ) );
+ vkQueueSubmit2 = PFN_vkQueueSubmit2( vkGetDeviceProcAddr( device, "vkQueueSubmit2" ) );
+ vkCmdCopyBuffer2 = PFN_vkCmdCopyBuffer2( vkGetDeviceProcAddr( device, "vkCmdCopyBuffer2" ) );
+ vkCmdCopyImage2 = PFN_vkCmdCopyImage2( vkGetDeviceProcAddr( device, "vkCmdCopyImage2" ) );
+ vkCmdCopyBufferToImage2 = PFN_vkCmdCopyBufferToImage2( vkGetDeviceProcAddr( device, "vkCmdCopyBufferToImage2" ) );
+ vkCmdCopyImageToBuffer2 = PFN_vkCmdCopyImageToBuffer2( vkGetDeviceProcAddr( device, "vkCmdCopyImageToBuffer2" ) );
+ vkCmdBlitImage2 = PFN_vkCmdBlitImage2( vkGetDeviceProcAddr( device, "vkCmdBlitImage2" ) );
+ vkCmdResolveImage2 = PFN_vkCmdResolveImage2( vkGetDeviceProcAddr( device, "vkCmdResolveImage2" ) );
+ vkCmdBeginRendering = PFN_vkCmdBeginRendering( vkGetDeviceProcAddr( device, "vkCmdBeginRendering" ) );
+ vkCmdEndRendering = PFN_vkCmdEndRendering( vkGetDeviceProcAddr( device, "vkCmdEndRendering" ) );
+ vkCmdSetCullMode = PFN_vkCmdSetCullMode( vkGetDeviceProcAddr( device, "vkCmdSetCullMode" ) );
+ vkCmdSetFrontFace = PFN_vkCmdSetFrontFace( vkGetDeviceProcAddr( device, "vkCmdSetFrontFace" ) );
+ vkCmdSetPrimitiveTopology = PFN_vkCmdSetPrimitiveTopology( vkGetDeviceProcAddr( device, "vkCmdSetPrimitiveTopology" ) );
+ vkCmdSetViewportWithCount = PFN_vkCmdSetViewportWithCount( vkGetDeviceProcAddr( device, "vkCmdSetViewportWithCount" ) );
+ vkCmdSetScissorWithCount = PFN_vkCmdSetScissorWithCount( vkGetDeviceProcAddr( device, "vkCmdSetScissorWithCount" ) );
+ vkCmdBindVertexBuffers2 = PFN_vkCmdBindVertexBuffers2( vkGetDeviceProcAddr( device, "vkCmdBindVertexBuffers2" ) );
+ vkCmdSetDepthTestEnable = PFN_vkCmdSetDepthTestEnable( vkGetDeviceProcAddr( device, "vkCmdSetDepthTestEnable" ) );
+ vkCmdSetDepthWriteEnable = PFN_vkCmdSetDepthWriteEnable( vkGetDeviceProcAddr( device, "vkCmdSetDepthWriteEnable" ) );
+ vkCmdSetDepthCompareOp = PFN_vkCmdSetDepthCompareOp( vkGetDeviceProcAddr( device, "vkCmdSetDepthCompareOp" ) );
+ vkCmdSetDepthBoundsTestEnable = PFN_vkCmdSetDepthBoundsTestEnable( vkGetDeviceProcAddr( device, "vkCmdSetDepthBoundsTestEnable" ) );
+ vkCmdSetStencilTestEnable = PFN_vkCmdSetStencilTestEnable( vkGetDeviceProcAddr( device, "vkCmdSetStencilTestEnable" ) );
+ vkCmdSetStencilOp = PFN_vkCmdSetStencilOp( vkGetDeviceProcAddr( device, "vkCmdSetStencilOp" ) );
+ vkCmdSetRasterizerDiscardEnable = PFN_vkCmdSetRasterizerDiscardEnable( vkGetDeviceProcAddr( device, "vkCmdSetRasterizerDiscardEnable" ) );
+ vkCmdSetDepthBiasEnable = PFN_vkCmdSetDepthBiasEnable( vkGetDeviceProcAddr( device, "vkCmdSetDepthBiasEnable" ) );
+ vkCmdSetPrimitiveRestartEnable = PFN_vkCmdSetPrimitiveRestartEnable( vkGetDeviceProcAddr( device, "vkCmdSetPrimitiveRestartEnable" ) );
+ vkGetDeviceBufferMemoryRequirements = PFN_vkGetDeviceBufferMemoryRequirements( vkGetDeviceProcAddr( device, "vkGetDeviceBufferMemoryRequirements" ) );
+ vkGetDeviceImageMemoryRequirements = PFN_vkGetDeviceImageMemoryRequirements( vkGetDeviceProcAddr( device, "vkGetDeviceImageMemoryRequirements" ) );
+ vkGetDeviceImageSparseMemoryRequirements =
+ PFN_vkGetDeviceImageSparseMemoryRequirements( vkGetDeviceProcAddr( device, "vkGetDeviceImageSparseMemoryRequirements" ) );
+
+ //=== VK_KHR_swapchain ===
+ vkCreateSwapchainKHR = PFN_vkCreateSwapchainKHR( vkGetDeviceProcAddr( device, "vkCreateSwapchainKHR" ) );
+ vkDestroySwapchainKHR = PFN_vkDestroySwapchainKHR( vkGetDeviceProcAddr( device, "vkDestroySwapchainKHR" ) );
+ vkGetSwapchainImagesKHR = PFN_vkGetSwapchainImagesKHR( vkGetDeviceProcAddr( device, "vkGetSwapchainImagesKHR" ) );
+ vkAcquireNextImageKHR = PFN_vkAcquireNextImageKHR( vkGetDeviceProcAddr( device, "vkAcquireNextImageKHR" ) );
+ vkQueuePresentKHR = PFN_vkQueuePresentKHR( vkGetDeviceProcAddr( device, "vkQueuePresentKHR" ) );
+ vkGetDeviceGroupPresentCapabilitiesKHR =
+ PFN_vkGetDeviceGroupPresentCapabilitiesKHR( vkGetDeviceProcAddr( device, "vkGetDeviceGroupPresentCapabilitiesKHR" ) );
+ vkGetDeviceGroupSurfacePresentModesKHR =
+ PFN_vkGetDeviceGroupSurfacePresentModesKHR( vkGetDeviceProcAddr( device, "vkGetDeviceGroupSurfacePresentModesKHR" ) );
+ vkAcquireNextImage2KHR = PFN_vkAcquireNextImage2KHR( vkGetDeviceProcAddr( device, "vkAcquireNextImage2KHR" ) );
+
+ //=== VK_KHR_display_swapchain ===
+ vkCreateSharedSwapchainsKHR = PFN_vkCreateSharedSwapchainsKHR( vkGetDeviceProcAddr( device, "vkCreateSharedSwapchainsKHR" ) );
+
+ //=== VK_EXT_debug_marker ===
+ vkDebugMarkerSetObjectTagEXT = PFN_vkDebugMarkerSetObjectTagEXT( vkGetDeviceProcAddr( device, "vkDebugMarkerSetObjectTagEXT" ) );
+ vkDebugMarkerSetObjectNameEXT = PFN_vkDebugMarkerSetObjectNameEXT( vkGetDeviceProcAddr( device, "vkDebugMarkerSetObjectNameEXT" ) );
+ vkCmdDebugMarkerBeginEXT = PFN_vkCmdDebugMarkerBeginEXT( vkGetDeviceProcAddr( device, "vkCmdDebugMarkerBeginEXT" ) );
+ vkCmdDebugMarkerEndEXT = PFN_vkCmdDebugMarkerEndEXT( vkGetDeviceProcAddr( device, "vkCmdDebugMarkerEndEXT" ) );
+ vkCmdDebugMarkerInsertEXT = PFN_vkCmdDebugMarkerInsertEXT( vkGetDeviceProcAddr( device, "vkCmdDebugMarkerInsertEXT" ) );
+
+#if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_queue ===
+ vkCreateVideoSessionKHR = PFN_vkCreateVideoSessionKHR( vkGetDeviceProcAddr( device, "vkCreateVideoSessionKHR" ) );
+ vkDestroyVideoSessionKHR = PFN_vkDestroyVideoSessionKHR( vkGetDeviceProcAddr( device, "vkDestroyVideoSessionKHR" ) );
+ vkGetVideoSessionMemoryRequirementsKHR =
+ PFN_vkGetVideoSessionMemoryRequirementsKHR( vkGetDeviceProcAddr( device, "vkGetVideoSessionMemoryRequirementsKHR" ) );
+ vkBindVideoSessionMemoryKHR = PFN_vkBindVideoSessionMemoryKHR( vkGetDeviceProcAddr( device, "vkBindVideoSessionMemoryKHR" ) );
+ vkCreateVideoSessionParametersKHR = PFN_vkCreateVideoSessionParametersKHR( vkGetDeviceProcAddr( device, "vkCreateVideoSessionParametersKHR" ) );
+ vkUpdateVideoSessionParametersKHR = PFN_vkUpdateVideoSessionParametersKHR( vkGetDeviceProcAddr( device, "vkUpdateVideoSessionParametersKHR" ) );
+ vkDestroyVideoSessionParametersKHR = PFN_vkDestroyVideoSessionParametersKHR( vkGetDeviceProcAddr( device, "vkDestroyVideoSessionParametersKHR" ) );
+ vkCmdBeginVideoCodingKHR = PFN_vkCmdBeginVideoCodingKHR( vkGetDeviceProcAddr( device, "vkCmdBeginVideoCodingKHR" ) );
+ vkCmdEndVideoCodingKHR = PFN_vkCmdEndVideoCodingKHR( vkGetDeviceProcAddr( device, "vkCmdEndVideoCodingKHR" ) );
+ vkCmdControlVideoCodingKHR = PFN_vkCmdControlVideoCodingKHR( vkGetDeviceProcAddr( device, "vkCmdControlVideoCodingKHR" ) );
+#endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+#if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_decode_queue ===
+ vkCmdDecodeVideoKHR = PFN_vkCmdDecodeVideoKHR( vkGetDeviceProcAddr( device, "vkCmdDecodeVideoKHR" ) );
+#endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+ //=== VK_EXT_transform_feedback ===
+ vkCmdBindTransformFeedbackBuffersEXT = PFN_vkCmdBindTransformFeedbackBuffersEXT( vkGetDeviceProcAddr( device, "vkCmdBindTransformFeedbackBuffersEXT" ) );
+ vkCmdBeginTransformFeedbackEXT = PFN_vkCmdBeginTransformFeedbackEXT( vkGetDeviceProcAddr( device, "vkCmdBeginTransformFeedbackEXT" ) );
+ vkCmdEndTransformFeedbackEXT = PFN_vkCmdEndTransformFeedbackEXT( vkGetDeviceProcAddr( device, "vkCmdEndTransformFeedbackEXT" ) );
+ vkCmdBeginQueryIndexedEXT = PFN_vkCmdBeginQueryIndexedEXT( vkGetDeviceProcAddr( device, "vkCmdBeginQueryIndexedEXT" ) );
+ vkCmdEndQueryIndexedEXT = PFN_vkCmdEndQueryIndexedEXT( vkGetDeviceProcAddr( device, "vkCmdEndQueryIndexedEXT" ) );
+ vkCmdDrawIndirectByteCountEXT = PFN_vkCmdDrawIndirectByteCountEXT( vkGetDeviceProcAddr( device, "vkCmdDrawIndirectByteCountEXT" ) );
+
+ //=== VK_NVX_binary_import ===
+ vkCreateCuModuleNVX = PFN_vkCreateCuModuleNVX( vkGetDeviceProcAddr( device, "vkCreateCuModuleNVX" ) );
+ vkCreateCuFunctionNVX = PFN_vkCreateCuFunctionNVX( vkGetDeviceProcAddr( device, "vkCreateCuFunctionNVX" ) );
+ vkDestroyCuModuleNVX = PFN_vkDestroyCuModuleNVX( vkGetDeviceProcAddr( device, "vkDestroyCuModuleNVX" ) );
+ vkDestroyCuFunctionNVX = PFN_vkDestroyCuFunctionNVX( vkGetDeviceProcAddr( device, "vkDestroyCuFunctionNVX" ) );
+ vkCmdCuLaunchKernelNVX = PFN_vkCmdCuLaunchKernelNVX( vkGetDeviceProcAddr( device, "vkCmdCuLaunchKernelNVX" ) );
+
+ //=== VK_NVX_image_view_handle ===
+ vkGetImageViewHandleNVX = PFN_vkGetImageViewHandleNVX( vkGetDeviceProcAddr( device, "vkGetImageViewHandleNVX" ) );
+ vkGetImageViewAddressNVX = PFN_vkGetImageViewAddressNVX( vkGetDeviceProcAddr( device, "vkGetImageViewAddressNVX" ) );
+
+ //=== VK_AMD_draw_indirect_count ===
+ vkCmdDrawIndirectCountAMD = PFN_vkCmdDrawIndirectCountAMD( vkGetDeviceProcAddr( device, "vkCmdDrawIndirectCountAMD" ) );
+ if ( !vkCmdDrawIndirectCount )
+ vkCmdDrawIndirectCount = vkCmdDrawIndirectCountAMD;
+ vkCmdDrawIndexedIndirectCountAMD = PFN_vkCmdDrawIndexedIndirectCountAMD( vkGetDeviceProcAddr( device, "vkCmdDrawIndexedIndirectCountAMD" ) );
+ if ( !vkCmdDrawIndexedIndirectCount )
+ vkCmdDrawIndexedIndirectCount = vkCmdDrawIndexedIndirectCountAMD;
+
+ //=== VK_AMD_shader_info ===
+ vkGetShaderInfoAMD = PFN_vkGetShaderInfoAMD( vkGetDeviceProcAddr( device, "vkGetShaderInfoAMD" ) );
+
+ //=== VK_KHR_dynamic_rendering ===
+ vkCmdBeginRenderingKHR = PFN_vkCmdBeginRenderingKHR( vkGetDeviceProcAddr( device, "vkCmdBeginRenderingKHR" ) );
+ if ( !vkCmdBeginRendering )
+ vkCmdBeginRendering = vkCmdBeginRenderingKHR;
+ vkCmdEndRenderingKHR = PFN_vkCmdEndRenderingKHR( vkGetDeviceProcAddr( device, "vkCmdEndRenderingKHR" ) );
+ if ( !vkCmdEndRendering )
+ vkCmdEndRendering = vkCmdEndRenderingKHR;
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_NV_external_memory_win32 ===
+ vkGetMemoryWin32HandleNV = PFN_vkGetMemoryWin32HandleNV( vkGetDeviceProcAddr( device, "vkGetMemoryWin32HandleNV" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_device_group ===
+ vkGetDeviceGroupPeerMemoryFeaturesKHR =
+ PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR( vkGetDeviceProcAddr( device, "vkGetDeviceGroupPeerMemoryFeaturesKHR" ) );
+ if ( !vkGetDeviceGroupPeerMemoryFeatures )
+ vkGetDeviceGroupPeerMemoryFeatures = vkGetDeviceGroupPeerMemoryFeaturesKHR;
+ vkCmdSetDeviceMaskKHR = PFN_vkCmdSetDeviceMaskKHR( vkGetDeviceProcAddr( device, "vkCmdSetDeviceMaskKHR" ) );
+ if ( !vkCmdSetDeviceMask )
+ vkCmdSetDeviceMask = vkCmdSetDeviceMaskKHR;
+ vkCmdDispatchBaseKHR = PFN_vkCmdDispatchBaseKHR( vkGetDeviceProcAddr( device, "vkCmdDispatchBaseKHR" ) );
+ if ( !vkCmdDispatchBase )
+ vkCmdDispatchBase = vkCmdDispatchBaseKHR;
+
+ //=== VK_KHR_maintenance1 ===
+ vkTrimCommandPoolKHR = PFN_vkTrimCommandPoolKHR( vkGetDeviceProcAddr( device, "vkTrimCommandPoolKHR" ) );
+ if ( !vkTrimCommandPool )
+ vkTrimCommandPool = vkTrimCommandPoolKHR;
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_memory_win32 ===
+ vkGetMemoryWin32HandleKHR = PFN_vkGetMemoryWin32HandleKHR( vkGetDeviceProcAddr( device, "vkGetMemoryWin32HandleKHR" ) );
+ vkGetMemoryWin32HandlePropertiesKHR = PFN_vkGetMemoryWin32HandlePropertiesKHR( vkGetDeviceProcAddr( device, "vkGetMemoryWin32HandlePropertiesKHR" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_memory_fd ===
+ vkGetMemoryFdKHR = PFN_vkGetMemoryFdKHR( vkGetDeviceProcAddr( device, "vkGetMemoryFdKHR" ) );
+ vkGetMemoryFdPropertiesKHR = PFN_vkGetMemoryFdPropertiesKHR( vkGetDeviceProcAddr( device, "vkGetMemoryFdPropertiesKHR" ) );
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_semaphore_win32 ===
+ vkImportSemaphoreWin32HandleKHR = PFN_vkImportSemaphoreWin32HandleKHR( vkGetDeviceProcAddr( device, "vkImportSemaphoreWin32HandleKHR" ) );
+ vkGetSemaphoreWin32HandleKHR = PFN_vkGetSemaphoreWin32HandleKHR( vkGetDeviceProcAddr( device, "vkGetSemaphoreWin32HandleKHR" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_semaphore_fd ===
+ vkImportSemaphoreFdKHR = PFN_vkImportSemaphoreFdKHR( vkGetDeviceProcAddr( device, "vkImportSemaphoreFdKHR" ) );
+ vkGetSemaphoreFdKHR = PFN_vkGetSemaphoreFdKHR( vkGetDeviceProcAddr( device, "vkGetSemaphoreFdKHR" ) );
+
+ //=== VK_KHR_push_descriptor ===
+ vkCmdPushDescriptorSetKHR = PFN_vkCmdPushDescriptorSetKHR( vkGetDeviceProcAddr( device, "vkCmdPushDescriptorSetKHR" ) );
+ vkCmdPushDescriptorSetWithTemplateKHR =
+ PFN_vkCmdPushDescriptorSetWithTemplateKHR( vkGetDeviceProcAddr( device, "vkCmdPushDescriptorSetWithTemplateKHR" ) );
+
+ //=== VK_EXT_conditional_rendering ===
+ vkCmdBeginConditionalRenderingEXT = PFN_vkCmdBeginConditionalRenderingEXT( vkGetDeviceProcAddr( device, "vkCmdBeginConditionalRenderingEXT" ) );
+ vkCmdEndConditionalRenderingEXT = PFN_vkCmdEndConditionalRenderingEXT( vkGetDeviceProcAddr( device, "vkCmdEndConditionalRenderingEXT" ) );
+
+ //=== VK_KHR_descriptor_update_template ===
+ vkCreateDescriptorUpdateTemplateKHR = PFN_vkCreateDescriptorUpdateTemplateKHR( vkGetDeviceProcAddr( device, "vkCreateDescriptorUpdateTemplateKHR" ) );
+ if ( !vkCreateDescriptorUpdateTemplate )
+ vkCreateDescriptorUpdateTemplate = vkCreateDescriptorUpdateTemplateKHR;
+ vkDestroyDescriptorUpdateTemplateKHR = PFN_vkDestroyDescriptorUpdateTemplateKHR( vkGetDeviceProcAddr( device, "vkDestroyDescriptorUpdateTemplateKHR" ) );
+ if ( !vkDestroyDescriptorUpdateTemplate )
+ vkDestroyDescriptorUpdateTemplate = vkDestroyDescriptorUpdateTemplateKHR;
+ vkUpdateDescriptorSetWithTemplateKHR = PFN_vkUpdateDescriptorSetWithTemplateKHR( vkGetDeviceProcAddr( device, "vkUpdateDescriptorSetWithTemplateKHR" ) );
+ if ( !vkUpdateDescriptorSetWithTemplate )
+ vkUpdateDescriptorSetWithTemplate = vkUpdateDescriptorSetWithTemplateKHR;
+
+ //=== VK_NV_clip_space_w_scaling ===
+ vkCmdSetViewportWScalingNV = PFN_vkCmdSetViewportWScalingNV( vkGetDeviceProcAddr( device, "vkCmdSetViewportWScalingNV" ) );
+
+ //=== VK_EXT_display_control ===
+ vkDisplayPowerControlEXT = PFN_vkDisplayPowerControlEXT( vkGetDeviceProcAddr( device, "vkDisplayPowerControlEXT" ) );
+ vkRegisterDeviceEventEXT = PFN_vkRegisterDeviceEventEXT( vkGetDeviceProcAddr( device, "vkRegisterDeviceEventEXT" ) );
+ vkRegisterDisplayEventEXT = PFN_vkRegisterDisplayEventEXT( vkGetDeviceProcAddr( device, "vkRegisterDisplayEventEXT" ) );
+ vkGetSwapchainCounterEXT = PFN_vkGetSwapchainCounterEXT( vkGetDeviceProcAddr( device, "vkGetSwapchainCounterEXT" ) );
+
+ //=== VK_GOOGLE_display_timing ===
+ vkGetRefreshCycleDurationGOOGLE = PFN_vkGetRefreshCycleDurationGOOGLE( vkGetDeviceProcAddr( device, "vkGetRefreshCycleDurationGOOGLE" ) );
+ vkGetPastPresentationTimingGOOGLE = PFN_vkGetPastPresentationTimingGOOGLE( vkGetDeviceProcAddr( device, "vkGetPastPresentationTimingGOOGLE" ) );
+
+ //=== VK_EXT_discard_rectangles ===
+ vkCmdSetDiscardRectangleEXT = PFN_vkCmdSetDiscardRectangleEXT( vkGetDeviceProcAddr( device, "vkCmdSetDiscardRectangleEXT" ) );
+
+ //=== VK_EXT_hdr_metadata ===
+ vkSetHdrMetadataEXT = PFN_vkSetHdrMetadataEXT( vkGetDeviceProcAddr( device, "vkSetHdrMetadataEXT" ) );
+
+ //=== VK_KHR_create_renderpass2 ===
+ vkCreateRenderPass2KHR = PFN_vkCreateRenderPass2KHR( vkGetDeviceProcAddr( device, "vkCreateRenderPass2KHR" ) );
+ if ( !vkCreateRenderPass2 )
+ vkCreateRenderPass2 = vkCreateRenderPass2KHR;
+ vkCmdBeginRenderPass2KHR = PFN_vkCmdBeginRenderPass2KHR( vkGetDeviceProcAddr( device, "vkCmdBeginRenderPass2KHR" ) );
+ if ( !vkCmdBeginRenderPass2 )
+ vkCmdBeginRenderPass2 = vkCmdBeginRenderPass2KHR;
+ vkCmdNextSubpass2KHR = PFN_vkCmdNextSubpass2KHR( vkGetDeviceProcAddr( device, "vkCmdNextSubpass2KHR" ) );
+ if ( !vkCmdNextSubpass2 )
+ vkCmdNextSubpass2 = vkCmdNextSubpass2KHR;
+ vkCmdEndRenderPass2KHR = PFN_vkCmdEndRenderPass2KHR( vkGetDeviceProcAddr( device, "vkCmdEndRenderPass2KHR" ) );
+ if ( !vkCmdEndRenderPass2 )
+ vkCmdEndRenderPass2 = vkCmdEndRenderPass2KHR;
+
+ //=== VK_KHR_shared_presentable_image ===
+ vkGetSwapchainStatusKHR = PFN_vkGetSwapchainStatusKHR( vkGetDeviceProcAddr( device, "vkGetSwapchainStatusKHR" ) );
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_KHR_external_fence_win32 ===
+ vkImportFenceWin32HandleKHR = PFN_vkImportFenceWin32HandleKHR( vkGetDeviceProcAddr( device, "vkImportFenceWin32HandleKHR" ) );
+ vkGetFenceWin32HandleKHR = PFN_vkGetFenceWin32HandleKHR( vkGetDeviceProcAddr( device, "vkGetFenceWin32HandleKHR" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_external_fence_fd ===
+ vkImportFenceFdKHR = PFN_vkImportFenceFdKHR( vkGetDeviceProcAddr( device, "vkImportFenceFdKHR" ) );
+ vkGetFenceFdKHR = PFN_vkGetFenceFdKHR( vkGetDeviceProcAddr( device, "vkGetFenceFdKHR" ) );
+
+ //=== VK_KHR_performance_query ===
+ vkAcquireProfilingLockKHR = PFN_vkAcquireProfilingLockKHR( vkGetDeviceProcAddr( device, "vkAcquireProfilingLockKHR" ) );
+ vkReleaseProfilingLockKHR = PFN_vkReleaseProfilingLockKHR( vkGetDeviceProcAddr( device, "vkReleaseProfilingLockKHR" ) );
+
+ //=== VK_EXT_debug_utils ===
+ vkSetDebugUtilsObjectNameEXT = PFN_vkSetDebugUtilsObjectNameEXT( vkGetDeviceProcAddr( device, "vkSetDebugUtilsObjectNameEXT" ) );
+ vkSetDebugUtilsObjectTagEXT = PFN_vkSetDebugUtilsObjectTagEXT( vkGetDeviceProcAddr( device, "vkSetDebugUtilsObjectTagEXT" ) );
+ vkQueueBeginDebugUtilsLabelEXT = PFN_vkQueueBeginDebugUtilsLabelEXT( vkGetDeviceProcAddr( device, "vkQueueBeginDebugUtilsLabelEXT" ) );
+ vkQueueEndDebugUtilsLabelEXT = PFN_vkQueueEndDebugUtilsLabelEXT( vkGetDeviceProcAddr( device, "vkQueueEndDebugUtilsLabelEXT" ) );
+ vkQueueInsertDebugUtilsLabelEXT = PFN_vkQueueInsertDebugUtilsLabelEXT( vkGetDeviceProcAddr( device, "vkQueueInsertDebugUtilsLabelEXT" ) );
+ vkCmdBeginDebugUtilsLabelEXT = PFN_vkCmdBeginDebugUtilsLabelEXT( vkGetDeviceProcAddr( device, "vkCmdBeginDebugUtilsLabelEXT" ) );
+ vkCmdEndDebugUtilsLabelEXT = PFN_vkCmdEndDebugUtilsLabelEXT( vkGetDeviceProcAddr( device, "vkCmdEndDebugUtilsLabelEXT" ) );
+ vkCmdInsertDebugUtilsLabelEXT = PFN_vkCmdInsertDebugUtilsLabelEXT( vkGetDeviceProcAddr( device, "vkCmdInsertDebugUtilsLabelEXT" ) );
+
+#if defined( VK_USE_PLATFORM_ANDROID_KHR )
+ //=== VK_ANDROID_external_memory_android_hardware_buffer ===
+ vkGetAndroidHardwareBufferPropertiesANDROID =
+ PFN_vkGetAndroidHardwareBufferPropertiesANDROID( vkGetDeviceProcAddr( device, "vkGetAndroidHardwareBufferPropertiesANDROID" ) );
+ vkGetMemoryAndroidHardwareBufferANDROID =
+ PFN_vkGetMemoryAndroidHardwareBufferANDROID( vkGetDeviceProcAddr( device, "vkGetMemoryAndroidHardwareBufferANDROID" ) );
+#endif /*VK_USE_PLATFORM_ANDROID_KHR*/
+
+ //=== VK_EXT_sample_locations ===
+ vkCmdSetSampleLocationsEXT = PFN_vkCmdSetSampleLocationsEXT( vkGetDeviceProcAddr( device, "vkCmdSetSampleLocationsEXT" ) );
+
+ //=== VK_KHR_get_memory_requirements2 ===
+ vkGetImageMemoryRequirements2KHR = PFN_vkGetImageMemoryRequirements2KHR( vkGetDeviceProcAddr( device, "vkGetImageMemoryRequirements2KHR" ) );
+ if ( !vkGetImageMemoryRequirements2 )
+ vkGetImageMemoryRequirements2 = vkGetImageMemoryRequirements2KHR;
+ vkGetBufferMemoryRequirements2KHR = PFN_vkGetBufferMemoryRequirements2KHR( vkGetDeviceProcAddr( device, "vkGetBufferMemoryRequirements2KHR" ) );
+ if ( !vkGetBufferMemoryRequirements2 )
+ vkGetBufferMemoryRequirements2 = vkGetBufferMemoryRequirements2KHR;
+ vkGetImageSparseMemoryRequirements2KHR =
+ PFN_vkGetImageSparseMemoryRequirements2KHR( vkGetDeviceProcAddr( device, "vkGetImageSparseMemoryRequirements2KHR" ) );
+ if ( !vkGetImageSparseMemoryRequirements2 )
+ vkGetImageSparseMemoryRequirements2 = vkGetImageSparseMemoryRequirements2KHR;
+
+ //=== VK_KHR_acceleration_structure ===
+ vkCreateAccelerationStructureKHR = PFN_vkCreateAccelerationStructureKHR( vkGetDeviceProcAddr( device, "vkCreateAccelerationStructureKHR" ) );
+ vkDestroyAccelerationStructureKHR = PFN_vkDestroyAccelerationStructureKHR( vkGetDeviceProcAddr( device, "vkDestroyAccelerationStructureKHR" ) );
+ vkCmdBuildAccelerationStructuresKHR = PFN_vkCmdBuildAccelerationStructuresKHR( vkGetDeviceProcAddr( device, "vkCmdBuildAccelerationStructuresKHR" ) );
+ vkCmdBuildAccelerationStructuresIndirectKHR =
+ PFN_vkCmdBuildAccelerationStructuresIndirectKHR( vkGetDeviceProcAddr( device, "vkCmdBuildAccelerationStructuresIndirectKHR" ) );
+ vkBuildAccelerationStructuresKHR = PFN_vkBuildAccelerationStructuresKHR( vkGetDeviceProcAddr( device, "vkBuildAccelerationStructuresKHR" ) );
+ vkCopyAccelerationStructureKHR = PFN_vkCopyAccelerationStructureKHR( vkGetDeviceProcAddr( device, "vkCopyAccelerationStructureKHR" ) );
+ vkCopyAccelerationStructureToMemoryKHR =
+ PFN_vkCopyAccelerationStructureToMemoryKHR( vkGetDeviceProcAddr( device, "vkCopyAccelerationStructureToMemoryKHR" ) );
+ vkCopyMemoryToAccelerationStructureKHR =
+ PFN_vkCopyMemoryToAccelerationStructureKHR( vkGetDeviceProcAddr( device, "vkCopyMemoryToAccelerationStructureKHR" ) );
+ vkWriteAccelerationStructuresPropertiesKHR =
+ PFN_vkWriteAccelerationStructuresPropertiesKHR( vkGetDeviceProcAddr( device, "vkWriteAccelerationStructuresPropertiesKHR" ) );
+ vkCmdCopyAccelerationStructureKHR = PFN_vkCmdCopyAccelerationStructureKHR( vkGetDeviceProcAddr( device, "vkCmdCopyAccelerationStructureKHR" ) );
+ vkCmdCopyAccelerationStructureToMemoryKHR =
+ PFN_vkCmdCopyAccelerationStructureToMemoryKHR( vkGetDeviceProcAddr( device, "vkCmdCopyAccelerationStructureToMemoryKHR" ) );
+ vkCmdCopyMemoryToAccelerationStructureKHR =
+ PFN_vkCmdCopyMemoryToAccelerationStructureKHR( vkGetDeviceProcAddr( device, "vkCmdCopyMemoryToAccelerationStructureKHR" ) );
+ vkGetAccelerationStructureDeviceAddressKHR =
+ PFN_vkGetAccelerationStructureDeviceAddressKHR( vkGetDeviceProcAddr( device, "vkGetAccelerationStructureDeviceAddressKHR" ) );
+ vkCmdWriteAccelerationStructuresPropertiesKHR =
+ PFN_vkCmdWriteAccelerationStructuresPropertiesKHR( vkGetDeviceProcAddr( device, "vkCmdWriteAccelerationStructuresPropertiesKHR" ) );
+ vkGetDeviceAccelerationStructureCompatibilityKHR =
+ PFN_vkGetDeviceAccelerationStructureCompatibilityKHR( vkGetDeviceProcAddr( device, "vkGetDeviceAccelerationStructureCompatibilityKHR" ) );
+ vkGetAccelerationStructureBuildSizesKHR =
+ PFN_vkGetAccelerationStructureBuildSizesKHR( vkGetDeviceProcAddr( device, "vkGetAccelerationStructureBuildSizesKHR" ) );
+
+ //=== VK_KHR_sampler_ycbcr_conversion ===
+ vkCreateSamplerYcbcrConversionKHR = PFN_vkCreateSamplerYcbcrConversionKHR( vkGetDeviceProcAddr( device, "vkCreateSamplerYcbcrConversionKHR" ) );
+ if ( !vkCreateSamplerYcbcrConversion )
+ vkCreateSamplerYcbcrConversion = vkCreateSamplerYcbcrConversionKHR;
+ vkDestroySamplerYcbcrConversionKHR = PFN_vkDestroySamplerYcbcrConversionKHR( vkGetDeviceProcAddr( device, "vkDestroySamplerYcbcrConversionKHR" ) );
+ if ( !vkDestroySamplerYcbcrConversion )
+ vkDestroySamplerYcbcrConversion = vkDestroySamplerYcbcrConversionKHR;
+
+ //=== VK_KHR_bind_memory2 ===
+ vkBindBufferMemory2KHR = PFN_vkBindBufferMemory2KHR( vkGetDeviceProcAddr( device, "vkBindBufferMemory2KHR" ) );
+ if ( !vkBindBufferMemory2 )
+ vkBindBufferMemory2 = vkBindBufferMemory2KHR;
+ vkBindImageMemory2KHR = PFN_vkBindImageMemory2KHR( vkGetDeviceProcAddr( device, "vkBindImageMemory2KHR" ) );
+ if ( !vkBindImageMemory2 )
+ vkBindImageMemory2 = vkBindImageMemory2KHR;
+
+ //=== VK_EXT_image_drm_format_modifier ===
+ vkGetImageDrmFormatModifierPropertiesEXT =
+ PFN_vkGetImageDrmFormatModifierPropertiesEXT( vkGetDeviceProcAddr( device, "vkGetImageDrmFormatModifierPropertiesEXT" ) );
+
+ //=== VK_EXT_validation_cache ===
+ vkCreateValidationCacheEXT = PFN_vkCreateValidationCacheEXT( vkGetDeviceProcAddr( device, "vkCreateValidationCacheEXT" ) );
+ vkDestroyValidationCacheEXT = PFN_vkDestroyValidationCacheEXT( vkGetDeviceProcAddr( device, "vkDestroyValidationCacheEXT" ) );
+ vkMergeValidationCachesEXT = PFN_vkMergeValidationCachesEXT( vkGetDeviceProcAddr( device, "vkMergeValidationCachesEXT" ) );
+ vkGetValidationCacheDataEXT = PFN_vkGetValidationCacheDataEXT( vkGetDeviceProcAddr( device, "vkGetValidationCacheDataEXT" ) );
+
+ //=== VK_NV_shading_rate_image ===
+ vkCmdBindShadingRateImageNV = PFN_vkCmdBindShadingRateImageNV( vkGetDeviceProcAddr( device, "vkCmdBindShadingRateImageNV" ) );
+ vkCmdSetViewportShadingRatePaletteNV = PFN_vkCmdSetViewportShadingRatePaletteNV( vkGetDeviceProcAddr( device, "vkCmdSetViewportShadingRatePaletteNV" ) );
+ vkCmdSetCoarseSampleOrderNV = PFN_vkCmdSetCoarseSampleOrderNV( vkGetDeviceProcAddr( device, "vkCmdSetCoarseSampleOrderNV" ) );
+
+ //=== VK_NV_ray_tracing ===
+ vkCreateAccelerationStructureNV = PFN_vkCreateAccelerationStructureNV( vkGetDeviceProcAddr( device, "vkCreateAccelerationStructureNV" ) );
+ vkDestroyAccelerationStructureNV = PFN_vkDestroyAccelerationStructureNV( vkGetDeviceProcAddr( device, "vkDestroyAccelerationStructureNV" ) );
+ vkGetAccelerationStructureMemoryRequirementsNV =
+ PFN_vkGetAccelerationStructureMemoryRequirementsNV( vkGetDeviceProcAddr( device, "vkGetAccelerationStructureMemoryRequirementsNV" ) );
+ vkBindAccelerationStructureMemoryNV = PFN_vkBindAccelerationStructureMemoryNV( vkGetDeviceProcAddr( device, "vkBindAccelerationStructureMemoryNV" ) );
+ vkCmdBuildAccelerationStructureNV = PFN_vkCmdBuildAccelerationStructureNV( vkGetDeviceProcAddr( device, "vkCmdBuildAccelerationStructureNV" ) );
+ vkCmdCopyAccelerationStructureNV = PFN_vkCmdCopyAccelerationStructureNV( vkGetDeviceProcAddr( device, "vkCmdCopyAccelerationStructureNV" ) );
+ vkCmdTraceRaysNV = PFN_vkCmdTraceRaysNV( vkGetDeviceProcAddr( device, "vkCmdTraceRaysNV" ) );
+ vkCreateRayTracingPipelinesNV = PFN_vkCreateRayTracingPipelinesNV( vkGetDeviceProcAddr( device, "vkCreateRayTracingPipelinesNV" ) );
+ vkGetRayTracingShaderGroupHandlesNV = PFN_vkGetRayTracingShaderGroupHandlesNV( vkGetDeviceProcAddr( device, "vkGetRayTracingShaderGroupHandlesNV" ) );
+ if ( !vkGetRayTracingShaderGroupHandlesKHR )
+ vkGetRayTracingShaderGroupHandlesKHR = vkGetRayTracingShaderGroupHandlesNV;
+ vkGetAccelerationStructureHandleNV = PFN_vkGetAccelerationStructureHandleNV( vkGetDeviceProcAddr( device, "vkGetAccelerationStructureHandleNV" ) );
+ vkCmdWriteAccelerationStructuresPropertiesNV =
+ PFN_vkCmdWriteAccelerationStructuresPropertiesNV( vkGetDeviceProcAddr( device, "vkCmdWriteAccelerationStructuresPropertiesNV" ) );
+ vkCompileDeferredNV = PFN_vkCompileDeferredNV( vkGetDeviceProcAddr( device, "vkCompileDeferredNV" ) );
+
+ //=== VK_KHR_maintenance3 ===
+ vkGetDescriptorSetLayoutSupportKHR = PFN_vkGetDescriptorSetLayoutSupportKHR( vkGetDeviceProcAddr( device, "vkGetDescriptorSetLayoutSupportKHR" ) );
+ if ( !vkGetDescriptorSetLayoutSupport )
+ vkGetDescriptorSetLayoutSupport = vkGetDescriptorSetLayoutSupportKHR;
+
+ //=== VK_KHR_draw_indirect_count ===
+ vkCmdDrawIndirectCountKHR = PFN_vkCmdDrawIndirectCountKHR( vkGetDeviceProcAddr( device, "vkCmdDrawIndirectCountKHR" ) );
+ if ( !vkCmdDrawIndirectCount )
+ vkCmdDrawIndirectCount = vkCmdDrawIndirectCountKHR;
+ vkCmdDrawIndexedIndirectCountKHR = PFN_vkCmdDrawIndexedIndirectCountKHR( vkGetDeviceProcAddr( device, "vkCmdDrawIndexedIndirectCountKHR" ) );
+ if ( !vkCmdDrawIndexedIndirectCount )
+ vkCmdDrawIndexedIndirectCount = vkCmdDrawIndexedIndirectCountKHR;
+
+ //=== VK_EXT_external_memory_host ===
+ vkGetMemoryHostPointerPropertiesEXT = PFN_vkGetMemoryHostPointerPropertiesEXT( vkGetDeviceProcAddr( device, "vkGetMemoryHostPointerPropertiesEXT" ) );
+
+ //=== VK_AMD_buffer_marker ===
+ vkCmdWriteBufferMarkerAMD = PFN_vkCmdWriteBufferMarkerAMD( vkGetDeviceProcAddr( device, "vkCmdWriteBufferMarkerAMD" ) );
+
+ //=== VK_EXT_calibrated_timestamps ===
+ vkGetCalibratedTimestampsEXT = PFN_vkGetCalibratedTimestampsEXT( vkGetDeviceProcAddr( device, "vkGetCalibratedTimestampsEXT" ) );
+
+ //=== VK_NV_mesh_shader ===
+ vkCmdDrawMeshTasksNV = PFN_vkCmdDrawMeshTasksNV( vkGetDeviceProcAddr( device, "vkCmdDrawMeshTasksNV" ) );
+ vkCmdDrawMeshTasksIndirectNV = PFN_vkCmdDrawMeshTasksIndirectNV( vkGetDeviceProcAddr( device, "vkCmdDrawMeshTasksIndirectNV" ) );
+ vkCmdDrawMeshTasksIndirectCountNV = PFN_vkCmdDrawMeshTasksIndirectCountNV( vkGetDeviceProcAddr( device, "vkCmdDrawMeshTasksIndirectCountNV" ) );
+
+ //=== VK_NV_scissor_exclusive ===
+ vkCmdSetExclusiveScissorNV = PFN_vkCmdSetExclusiveScissorNV( vkGetDeviceProcAddr( device, "vkCmdSetExclusiveScissorNV" ) );
+
+ //=== VK_NV_device_diagnostic_checkpoints ===
+ vkCmdSetCheckpointNV = PFN_vkCmdSetCheckpointNV( vkGetDeviceProcAddr( device, "vkCmdSetCheckpointNV" ) );
+ vkGetQueueCheckpointDataNV = PFN_vkGetQueueCheckpointDataNV( vkGetDeviceProcAddr( device, "vkGetQueueCheckpointDataNV" ) );
+
+ //=== VK_KHR_timeline_semaphore ===
+ vkGetSemaphoreCounterValueKHR = PFN_vkGetSemaphoreCounterValueKHR( vkGetDeviceProcAddr( device, "vkGetSemaphoreCounterValueKHR" ) );
+ if ( !vkGetSemaphoreCounterValue )
+ vkGetSemaphoreCounterValue = vkGetSemaphoreCounterValueKHR;
+ vkWaitSemaphoresKHR = PFN_vkWaitSemaphoresKHR( vkGetDeviceProcAddr( device, "vkWaitSemaphoresKHR" ) );
+ if ( !vkWaitSemaphores )
+ vkWaitSemaphores = vkWaitSemaphoresKHR;
+ vkSignalSemaphoreKHR = PFN_vkSignalSemaphoreKHR( vkGetDeviceProcAddr( device, "vkSignalSemaphoreKHR" ) );
+ if ( !vkSignalSemaphore )
+ vkSignalSemaphore = vkSignalSemaphoreKHR;
+
+ //=== VK_INTEL_performance_query ===
+ vkInitializePerformanceApiINTEL = PFN_vkInitializePerformanceApiINTEL( vkGetDeviceProcAddr( device, "vkInitializePerformanceApiINTEL" ) );
+ vkUninitializePerformanceApiINTEL = PFN_vkUninitializePerformanceApiINTEL( vkGetDeviceProcAddr( device, "vkUninitializePerformanceApiINTEL" ) );
+ vkCmdSetPerformanceMarkerINTEL = PFN_vkCmdSetPerformanceMarkerINTEL( vkGetDeviceProcAddr( device, "vkCmdSetPerformanceMarkerINTEL" ) );
+ vkCmdSetPerformanceStreamMarkerINTEL = PFN_vkCmdSetPerformanceStreamMarkerINTEL( vkGetDeviceProcAddr( device, "vkCmdSetPerformanceStreamMarkerINTEL" ) );
+ vkCmdSetPerformanceOverrideINTEL = PFN_vkCmdSetPerformanceOverrideINTEL( vkGetDeviceProcAddr( device, "vkCmdSetPerformanceOverrideINTEL" ) );
+ vkAcquirePerformanceConfigurationINTEL =
+ PFN_vkAcquirePerformanceConfigurationINTEL( vkGetDeviceProcAddr( device, "vkAcquirePerformanceConfigurationINTEL" ) );
+ vkReleasePerformanceConfigurationINTEL =
+ PFN_vkReleasePerformanceConfigurationINTEL( vkGetDeviceProcAddr( device, "vkReleasePerformanceConfigurationINTEL" ) );
+ vkQueueSetPerformanceConfigurationINTEL =
+ PFN_vkQueueSetPerformanceConfigurationINTEL( vkGetDeviceProcAddr( device, "vkQueueSetPerformanceConfigurationINTEL" ) );
+ vkGetPerformanceParameterINTEL = PFN_vkGetPerformanceParameterINTEL( vkGetDeviceProcAddr( device, "vkGetPerformanceParameterINTEL" ) );
+
+ //=== VK_AMD_display_native_hdr ===
+ vkSetLocalDimmingAMD = PFN_vkSetLocalDimmingAMD( vkGetDeviceProcAddr( device, "vkSetLocalDimmingAMD" ) );
+
+ //=== VK_KHR_fragment_shading_rate ===
+ vkCmdSetFragmentShadingRateKHR = PFN_vkCmdSetFragmentShadingRateKHR( vkGetDeviceProcAddr( device, "vkCmdSetFragmentShadingRateKHR" ) );
+
+ //=== VK_EXT_buffer_device_address ===
+ vkGetBufferDeviceAddressEXT = PFN_vkGetBufferDeviceAddressEXT( vkGetDeviceProcAddr( device, "vkGetBufferDeviceAddressEXT" ) );
+ if ( !vkGetBufferDeviceAddress )
+ vkGetBufferDeviceAddress = vkGetBufferDeviceAddressEXT;
+
+ //=== VK_KHR_present_wait ===
+ vkWaitForPresentKHR = PFN_vkWaitForPresentKHR( vkGetDeviceProcAddr( device, "vkWaitForPresentKHR" ) );
+
+#if defined( VK_USE_PLATFORM_WIN32_KHR )
+ //=== VK_EXT_full_screen_exclusive ===
+ vkAcquireFullScreenExclusiveModeEXT = PFN_vkAcquireFullScreenExclusiveModeEXT( vkGetDeviceProcAddr( device, "vkAcquireFullScreenExclusiveModeEXT" ) );
+ vkReleaseFullScreenExclusiveModeEXT = PFN_vkReleaseFullScreenExclusiveModeEXT( vkGetDeviceProcAddr( device, "vkReleaseFullScreenExclusiveModeEXT" ) );
+ vkGetDeviceGroupSurfacePresentModes2EXT =
+ PFN_vkGetDeviceGroupSurfacePresentModes2EXT( vkGetDeviceProcAddr( device, "vkGetDeviceGroupSurfacePresentModes2EXT" ) );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+ //=== VK_KHR_buffer_device_address ===
+ vkGetBufferDeviceAddressKHR = PFN_vkGetBufferDeviceAddressKHR( vkGetDeviceProcAddr( device, "vkGetBufferDeviceAddressKHR" ) );
+ if ( !vkGetBufferDeviceAddress )
+ vkGetBufferDeviceAddress = vkGetBufferDeviceAddressKHR;
+ vkGetBufferOpaqueCaptureAddressKHR = PFN_vkGetBufferOpaqueCaptureAddressKHR( vkGetDeviceProcAddr( device, "vkGetBufferOpaqueCaptureAddressKHR" ) );
+ if ( !vkGetBufferOpaqueCaptureAddress )
+ vkGetBufferOpaqueCaptureAddress = vkGetBufferOpaqueCaptureAddressKHR;
+ vkGetDeviceMemoryOpaqueCaptureAddressKHR =
+ PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR( vkGetDeviceProcAddr( device, "vkGetDeviceMemoryOpaqueCaptureAddressKHR" ) );
+ if ( !vkGetDeviceMemoryOpaqueCaptureAddress )
+ vkGetDeviceMemoryOpaqueCaptureAddress = vkGetDeviceMemoryOpaqueCaptureAddressKHR;
+
+ //=== VK_EXT_line_rasterization ===
+ vkCmdSetLineStippleEXT = PFN_vkCmdSetLineStippleEXT( vkGetDeviceProcAddr( device, "vkCmdSetLineStippleEXT" ) );
+
+ //=== VK_EXT_host_query_reset ===
+ vkResetQueryPoolEXT = PFN_vkResetQueryPoolEXT( vkGetDeviceProcAddr( device, "vkResetQueryPoolEXT" ) );
+ if ( !vkResetQueryPool )
+ vkResetQueryPool = vkResetQueryPoolEXT;
+
+ //=== VK_EXT_extended_dynamic_state ===
+ vkCmdSetCullModeEXT = PFN_vkCmdSetCullModeEXT( vkGetDeviceProcAddr( device, "vkCmdSetCullModeEXT" ) );
+ if ( !vkCmdSetCullMode )
+ vkCmdSetCullMode = vkCmdSetCullModeEXT;
+ vkCmdSetFrontFaceEXT = PFN_vkCmdSetFrontFaceEXT( vkGetDeviceProcAddr( device, "vkCmdSetFrontFaceEXT" ) );
+ if ( !vkCmdSetFrontFace )
+ vkCmdSetFrontFace = vkCmdSetFrontFaceEXT;
+ vkCmdSetPrimitiveTopologyEXT = PFN_vkCmdSetPrimitiveTopologyEXT( vkGetDeviceProcAddr( device, "vkCmdSetPrimitiveTopologyEXT" ) );
+ if ( !vkCmdSetPrimitiveTopology )
+ vkCmdSetPrimitiveTopology = vkCmdSetPrimitiveTopologyEXT;
+ vkCmdSetViewportWithCountEXT = PFN_vkCmdSetViewportWithCountEXT( vkGetDeviceProcAddr( device, "vkCmdSetViewportWithCountEXT" ) );
+ if ( !vkCmdSetViewportWithCount )
+ vkCmdSetViewportWithCount = vkCmdSetViewportWithCountEXT;
+ vkCmdSetScissorWithCountEXT = PFN_vkCmdSetScissorWithCountEXT( vkGetDeviceProcAddr( device, "vkCmdSetScissorWithCountEXT" ) );
+ if ( !vkCmdSetScissorWithCount )
+ vkCmdSetScissorWithCount = vkCmdSetScissorWithCountEXT;
+ vkCmdBindVertexBuffers2EXT = PFN_vkCmdBindVertexBuffers2EXT( vkGetDeviceProcAddr( device, "vkCmdBindVertexBuffers2EXT" ) );
+ if ( !vkCmdBindVertexBuffers2 )
+ vkCmdBindVertexBuffers2 = vkCmdBindVertexBuffers2EXT;
+ vkCmdSetDepthTestEnableEXT = PFN_vkCmdSetDepthTestEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetDepthTestEnableEXT" ) );
+ if ( !vkCmdSetDepthTestEnable )
+ vkCmdSetDepthTestEnable = vkCmdSetDepthTestEnableEXT;
+ vkCmdSetDepthWriteEnableEXT = PFN_vkCmdSetDepthWriteEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetDepthWriteEnableEXT" ) );
+ if ( !vkCmdSetDepthWriteEnable )
+ vkCmdSetDepthWriteEnable = vkCmdSetDepthWriteEnableEXT;
+ vkCmdSetDepthCompareOpEXT = PFN_vkCmdSetDepthCompareOpEXT( vkGetDeviceProcAddr( device, "vkCmdSetDepthCompareOpEXT" ) );
+ if ( !vkCmdSetDepthCompareOp )
+ vkCmdSetDepthCompareOp = vkCmdSetDepthCompareOpEXT;
+ vkCmdSetDepthBoundsTestEnableEXT = PFN_vkCmdSetDepthBoundsTestEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetDepthBoundsTestEnableEXT" ) );
+ if ( !vkCmdSetDepthBoundsTestEnable )
+ vkCmdSetDepthBoundsTestEnable = vkCmdSetDepthBoundsTestEnableEXT;
+ vkCmdSetStencilTestEnableEXT = PFN_vkCmdSetStencilTestEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetStencilTestEnableEXT" ) );
+ if ( !vkCmdSetStencilTestEnable )
+ vkCmdSetStencilTestEnable = vkCmdSetStencilTestEnableEXT;
+ vkCmdSetStencilOpEXT = PFN_vkCmdSetStencilOpEXT( vkGetDeviceProcAddr( device, "vkCmdSetStencilOpEXT" ) );
+ if ( !vkCmdSetStencilOp )
+ vkCmdSetStencilOp = vkCmdSetStencilOpEXT;
+
+ //=== VK_KHR_deferred_host_operations ===
+ vkCreateDeferredOperationKHR = PFN_vkCreateDeferredOperationKHR( vkGetDeviceProcAddr( device, "vkCreateDeferredOperationKHR" ) );
+ vkDestroyDeferredOperationKHR = PFN_vkDestroyDeferredOperationKHR( vkGetDeviceProcAddr( device, "vkDestroyDeferredOperationKHR" ) );
+ vkGetDeferredOperationMaxConcurrencyKHR =
+ PFN_vkGetDeferredOperationMaxConcurrencyKHR( vkGetDeviceProcAddr( device, "vkGetDeferredOperationMaxConcurrencyKHR" ) );
+ vkGetDeferredOperationResultKHR = PFN_vkGetDeferredOperationResultKHR( vkGetDeviceProcAddr( device, "vkGetDeferredOperationResultKHR" ) );
+ vkDeferredOperationJoinKHR = PFN_vkDeferredOperationJoinKHR( vkGetDeviceProcAddr( device, "vkDeferredOperationJoinKHR" ) );
+
+ //=== VK_KHR_pipeline_executable_properties ===
+ vkGetPipelineExecutablePropertiesKHR = PFN_vkGetPipelineExecutablePropertiesKHR( vkGetDeviceProcAddr( device, "vkGetPipelineExecutablePropertiesKHR" ) );
+ vkGetPipelineExecutableStatisticsKHR = PFN_vkGetPipelineExecutableStatisticsKHR( vkGetDeviceProcAddr( device, "vkGetPipelineExecutableStatisticsKHR" ) );
+ vkGetPipelineExecutableInternalRepresentationsKHR =
+ PFN_vkGetPipelineExecutableInternalRepresentationsKHR( vkGetDeviceProcAddr( device, "vkGetPipelineExecutableInternalRepresentationsKHR" ) );
+
+ //=== VK_NV_device_generated_commands ===
+ vkGetGeneratedCommandsMemoryRequirementsNV =
+ PFN_vkGetGeneratedCommandsMemoryRequirementsNV( vkGetDeviceProcAddr( device, "vkGetGeneratedCommandsMemoryRequirementsNV" ) );
+ vkCmdPreprocessGeneratedCommandsNV = PFN_vkCmdPreprocessGeneratedCommandsNV( vkGetDeviceProcAddr( device, "vkCmdPreprocessGeneratedCommandsNV" ) );
+ vkCmdExecuteGeneratedCommandsNV = PFN_vkCmdExecuteGeneratedCommandsNV( vkGetDeviceProcAddr( device, "vkCmdExecuteGeneratedCommandsNV" ) );
+ vkCmdBindPipelineShaderGroupNV = PFN_vkCmdBindPipelineShaderGroupNV( vkGetDeviceProcAddr( device, "vkCmdBindPipelineShaderGroupNV" ) );
+ vkCreateIndirectCommandsLayoutNV = PFN_vkCreateIndirectCommandsLayoutNV( vkGetDeviceProcAddr( device, "vkCreateIndirectCommandsLayoutNV" ) );
+ vkDestroyIndirectCommandsLayoutNV = PFN_vkDestroyIndirectCommandsLayoutNV( vkGetDeviceProcAddr( device, "vkDestroyIndirectCommandsLayoutNV" ) );
+
+ //=== VK_EXT_private_data ===
+ vkCreatePrivateDataSlotEXT = PFN_vkCreatePrivateDataSlotEXT( vkGetDeviceProcAddr( device, "vkCreatePrivateDataSlotEXT" ) );
+ if ( !vkCreatePrivateDataSlot )
+ vkCreatePrivateDataSlot = vkCreatePrivateDataSlotEXT;
+ vkDestroyPrivateDataSlotEXT = PFN_vkDestroyPrivateDataSlotEXT( vkGetDeviceProcAddr( device, "vkDestroyPrivateDataSlotEXT" ) );
+ if ( !vkDestroyPrivateDataSlot )
+ vkDestroyPrivateDataSlot = vkDestroyPrivateDataSlotEXT;
+ vkSetPrivateDataEXT = PFN_vkSetPrivateDataEXT( vkGetDeviceProcAddr( device, "vkSetPrivateDataEXT" ) );
+ if ( !vkSetPrivateData )
+ vkSetPrivateData = vkSetPrivateDataEXT;
+ vkGetPrivateDataEXT = PFN_vkGetPrivateDataEXT( vkGetDeviceProcAddr( device, "vkGetPrivateDataEXT" ) );
+ if ( !vkGetPrivateData )
+ vkGetPrivateData = vkGetPrivateDataEXT;
+
+#if defined( VK_ENABLE_BETA_EXTENSIONS )
+ //=== VK_KHR_video_encode_queue ===
+ vkCmdEncodeVideoKHR = PFN_vkCmdEncodeVideoKHR( vkGetDeviceProcAddr( device, "vkCmdEncodeVideoKHR" ) );
+#endif /*VK_ENABLE_BETA_EXTENSIONS*/
+
+#if defined( VK_USE_PLATFORM_METAL_EXT )
+ //=== VK_EXT_metal_objects ===
+ vkExportMetalObjectsEXT = PFN_vkExportMetalObjectsEXT( vkGetDeviceProcAddr( device, "vkExportMetalObjectsEXT" ) );
+#endif /*VK_USE_PLATFORM_METAL_EXT*/
+
+ //=== VK_KHR_synchronization2 ===
+ vkCmdSetEvent2KHR = PFN_vkCmdSetEvent2KHR( vkGetDeviceProcAddr( device, "vkCmdSetEvent2KHR" ) );
+ if ( !vkCmdSetEvent2 )
+ vkCmdSetEvent2 = vkCmdSetEvent2KHR;
+ vkCmdResetEvent2KHR = PFN_vkCmdResetEvent2KHR( vkGetDeviceProcAddr( device, "vkCmdResetEvent2KHR" ) );
+ if ( !vkCmdResetEvent2 )
+ vkCmdResetEvent2 = vkCmdResetEvent2KHR;
+ vkCmdWaitEvents2KHR = PFN_vkCmdWaitEvents2KHR( vkGetDeviceProcAddr( device, "vkCmdWaitEvents2KHR" ) );
+ if ( !vkCmdWaitEvents2 )
+ vkCmdWaitEvents2 = vkCmdWaitEvents2KHR;
+ vkCmdPipelineBarrier2KHR = PFN_vkCmdPipelineBarrier2KHR( vkGetDeviceProcAddr( device, "vkCmdPipelineBarrier2KHR" ) );
+ if ( !vkCmdPipelineBarrier2 )
+ vkCmdPipelineBarrier2 = vkCmdPipelineBarrier2KHR;
+ vkCmdWriteTimestamp2KHR = PFN_vkCmdWriteTimestamp2KHR( vkGetDeviceProcAddr( device, "vkCmdWriteTimestamp2KHR" ) );
+ if ( !vkCmdWriteTimestamp2 )
+ vkCmdWriteTimestamp2 = vkCmdWriteTimestamp2KHR;
+ vkQueueSubmit2KHR = PFN_vkQueueSubmit2KHR( vkGetDeviceProcAddr( device, "vkQueueSubmit2KHR" ) );
+ if ( !vkQueueSubmit2 )
+ vkQueueSubmit2 = vkQueueSubmit2KHR;
+ vkCmdWriteBufferMarker2AMD = PFN_vkCmdWriteBufferMarker2AMD( vkGetDeviceProcAddr( device, "vkCmdWriteBufferMarker2AMD" ) );
+ vkGetQueueCheckpointData2NV = PFN_vkGetQueueCheckpointData2NV( vkGetDeviceProcAddr( device, "vkGetQueueCheckpointData2NV" ) );
+
+ //=== VK_NV_fragment_shading_rate_enums ===
+ vkCmdSetFragmentShadingRateEnumNV = PFN_vkCmdSetFragmentShadingRateEnumNV( vkGetDeviceProcAddr( device, "vkCmdSetFragmentShadingRateEnumNV" ) );
+
+ //=== VK_EXT_mesh_shader ===
+ vkCmdDrawMeshTasksEXT = PFN_vkCmdDrawMeshTasksEXT( vkGetDeviceProcAddr( device, "vkCmdDrawMeshTasksEXT" ) );
+ vkCmdDrawMeshTasksIndirectEXT = PFN_vkCmdDrawMeshTasksIndirectEXT( vkGetDeviceProcAddr( device, "vkCmdDrawMeshTasksIndirectEXT" ) );
+ vkCmdDrawMeshTasksIndirectCountEXT = PFN_vkCmdDrawMeshTasksIndirectCountEXT( vkGetDeviceProcAddr( device, "vkCmdDrawMeshTasksIndirectCountEXT" ) );
+
+ //=== VK_KHR_copy_commands2 ===
+ vkCmdCopyBuffer2KHR = PFN_vkCmdCopyBuffer2KHR( vkGetDeviceProcAddr( device, "vkCmdCopyBuffer2KHR" ) );
+ if ( !vkCmdCopyBuffer2 )
+ vkCmdCopyBuffer2 = vkCmdCopyBuffer2KHR;
+ vkCmdCopyImage2KHR = PFN_vkCmdCopyImage2KHR( vkGetDeviceProcAddr( device, "vkCmdCopyImage2KHR" ) );
+ if ( !vkCmdCopyImage2 )
+ vkCmdCopyImage2 = vkCmdCopyImage2KHR;
+ vkCmdCopyBufferToImage2KHR = PFN_vkCmdCopyBufferToImage2KHR( vkGetDeviceProcAddr( device, "vkCmdCopyBufferToImage2KHR" ) );
+ if ( !vkCmdCopyBufferToImage2 )
+ vkCmdCopyBufferToImage2 = vkCmdCopyBufferToImage2KHR;
+ vkCmdCopyImageToBuffer2KHR = PFN_vkCmdCopyImageToBuffer2KHR( vkGetDeviceProcAddr( device, "vkCmdCopyImageToBuffer2KHR" ) );
+ if ( !vkCmdCopyImageToBuffer2 )
+ vkCmdCopyImageToBuffer2 = vkCmdCopyImageToBuffer2KHR;
+ vkCmdBlitImage2KHR = PFN_vkCmdBlitImage2KHR( vkGetDeviceProcAddr( device, "vkCmdBlitImage2KHR" ) );
+ if ( !vkCmdBlitImage2 )
+ vkCmdBlitImage2 = vkCmdBlitImage2KHR;
+ vkCmdResolveImage2KHR = PFN_vkCmdResolveImage2KHR( vkGetDeviceProcAddr( device, "vkCmdResolveImage2KHR" ) );
+ if ( !vkCmdResolveImage2 )
+ vkCmdResolveImage2 = vkCmdResolveImage2KHR;
+
+ //=== VK_EXT_image_compression_control ===
+ vkGetImageSubresourceLayout2EXT = PFN_vkGetImageSubresourceLayout2EXT( vkGetDeviceProcAddr( device, "vkGetImageSubresourceLayout2EXT" ) );
+
+ //=== VK_EXT_device_fault ===
+ vkGetDeviceFaultInfoEXT = PFN_vkGetDeviceFaultInfoEXT( vkGetDeviceProcAddr( device, "vkGetDeviceFaultInfoEXT" ) );
+
+ //=== VK_KHR_ray_tracing_pipeline ===
+ vkCmdTraceRaysKHR = PFN_vkCmdTraceRaysKHR( vkGetDeviceProcAddr( device, "vkCmdTraceRaysKHR" ) );
+ vkCreateRayTracingPipelinesKHR = PFN_vkCreateRayTracingPipelinesKHR( vkGetDeviceProcAddr( device, "vkCreateRayTracingPipelinesKHR" ) );
+ vkGetRayTracingShaderGroupHandlesKHR = PFN_vkGetRayTracingShaderGroupHandlesKHR( vkGetDeviceProcAddr( device, "vkGetRayTracingShaderGroupHandlesKHR" ) );
+ vkGetRayTracingCaptureReplayShaderGroupHandlesKHR =
+ PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR( vkGetDeviceProcAddr( device, "vkGetRayTracingCaptureReplayShaderGroupHandlesKHR" ) );
+ vkCmdTraceRaysIndirectKHR = PFN_vkCmdTraceRaysIndirectKHR( vkGetDeviceProcAddr( device, "vkCmdTraceRaysIndirectKHR" ) );
+ vkGetRayTracingShaderGroupStackSizeKHR =
+ PFN_vkGetRayTracingShaderGroupStackSizeKHR( vkGetDeviceProcAddr( device, "vkGetRayTracingShaderGroupStackSizeKHR" ) );
+ vkCmdSetRayTracingPipelineStackSizeKHR =
+ PFN_vkCmdSetRayTracingPipelineStackSizeKHR( vkGetDeviceProcAddr( device, "vkCmdSetRayTracingPipelineStackSizeKHR" ) );
+
+ //=== VK_EXT_vertex_input_dynamic_state ===
+ vkCmdSetVertexInputEXT = PFN_vkCmdSetVertexInputEXT( vkGetDeviceProcAddr( device, "vkCmdSetVertexInputEXT" ) );
+
+#if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_external_memory ===
+ vkGetMemoryZirconHandleFUCHSIA = PFN_vkGetMemoryZirconHandleFUCHSIA( vkGetDeviceProcAddr( device, "vkGetMemoryZirconHandleFUCHSIA" ) );
+ vkGetMemoryZirconHandlePropertiesFUCHSIA =
+ PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA( vkGetDeviceProcAddr( device, "vkGetMemoryZirconHandlePropertiesFUCHSIA" ) );
+#endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+#if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_external_semaphore ===
+ vkImportSemaphoreZirconHandleFUCHSIA = PFN_vkImportSemaphoreZirconHandleFUCHSIA( vkGetDeviceProcAddr( device, "vkImportSemaphoreZirconHandleFUCHSIA" ) );
+ vkGetSemaphoreZirconHandleFUCHSIA = PFN_vkGetSemaphoreZirconHandleFUCHSIA( vkGetDeviceProcAddr( device, "vkGetSemaphoreZirconHandleFUCHSIA" ) );
+#endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+#if defined( VK_USE_PLATFORM_FUCHSIA )
+ //=== VK_FUCHSIA_buffer_collection ===
+ vkCreateBufferCollectionFUCHSIA = PFN_vkCreateBufferCollectionFUCHSIA( vkGetDeviceProcAddr( device, "vkCreateBufferCollectionFUCHSIA" ) );
+ vkSetBufferCollectionImageConstraintsFUCHSIA =
+ PFN_vkSetBufferCollectionImageConstraintsFUCHSIA( vkGetDeviceProcAddr( device, "vkSetBufferCollectionImageConstraintsFUCHSIA" ) );
+ vkSetBufferCollectionBufferConstraintsFUCHSIA =
+ PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA( vkGetDeviceProcAddr( device, "vkSetBufferCollectionBufferConstraintsFUCHSIA" ) );
+ vkDestroyBufferCollectionFUCHSIA = PFN_vkDestroyBufferCollectionFUCHSIA( vkGetDeviceProcAddr( device, "vkDestroyBufferCollectionFUCHSIA" ) );
+ vkGetBufferCollectionPropertiesFUCHSIA =
+ PFN_vkGetBufferCollectionPropertiesFUCHSIA( vkGetDeviceProcAddr( device, "vkGetBufferCollectionPropertiesFUCHSIA" ) );
+#endif /*VK_USE_PLATFORM_FUCHSIA*/
+
+ //=== VK_HUAWEI_subpass_shading ===
+ vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI =
+ PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI( vkGetDeviceProcAddr( device, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI" ) );
+ vkCmdSubpassShadingHUAWEI = PFN_vkCmdSubpassShadingHUAWEI( vkGetDeviceProcAddr( device, "vkCmdSubpassShadingHUAWEI" ) );
+
+ //=== VK_HUAWEI_invocation_mask ===
+ vkCmdBindInvocationMaskHUAWEI = PFN_vkCmdBindInvocationMaskHUAWEI( vkGetDeviceProcAddr( device, "vkCmdBindInvocationMaskHUAWEI" ) );
+
+ //=== VK_NV_external_memory_rdma ===
+ vkGetMemoryRemoteAddressNV = PFN_vkGetMemoryRemoteAddressNV( vkGetDeviceProcAddr( device, "vkGetMemoryRemoteAddressNV" ) );
+
+ //=== VK_EXT_pipeline_properties ===
+ vkGetPipelinePropertiesEXT = PFN_vkGetPipelinePropertiesEXT( vkGetDeviceProcAddr( device, "vkGetPipelinePropertiesEXT" ) );
+
+ //=== VK_EXT_extended_dynamic_state2 ===
+ vkCmdSetPatchControlPointsEXT = PFN_vkCmdSetPatchControlPointsEXT( vkGetDeviceProcAddr( device, "vkCmdSetPatchControlPointsEXT" ) );
+ vkCmdSetRasterizerDiscardEnableEXT = PFN_vkCmdSetRasterizerDiscardEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetRasterizerDiscardEnableEXT" ) );
+ if ( !vkCmdSetRasterizerDiscardEnable )
+ vkCmdSetRasterizerDiscardEnable = vkCmdSetRasterizerDiscardEnableEXT;
+ vkCmdSetDepthBiasEnableEXT = PFN_vkCmdSetDepthBiasEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetDepthBiasEnableEXT" ) );
+ if ( !vkCmdSetDepthBiasEnable )
+ vkCmdSetDepthBiasEnable = vkCmdSetDepthBiasEnableEXT;
+ vkCmdSetLogicOpEXT = PFN_vkCmdSetLogicOpEXT( vkGetDeviceProcAddr( device, "vkCmdSetLogicOpEXT" ) );
+ vkCmdSetPrimitiveRestartEnableEXT = PFN_vkCmdSetPrimitiveRestartEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetPrimitiveRestartEnableEXT" ) );
+ if ( !vkCmdSetPrimitiveRestartEnable )
+ vkCmdSetPrimitiveRestartEnable = vkCmdSetPrimitiveRestartEnableEXT;
+
+ //=== VK_EXT_color_write_enable ===
+ vkCmdSetColorWriteEnableEXT = PFN_vkCmdSetColorWriteEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetColorWriteEnableEXT" ) );
+
+ //=== VK_KHR_ray_tracing_maintenance1 ===
+ vkCmdTraceRaysIndirect2KHR = PFN_vkCmdTraceRaysIndirect2KHR( vkGetDeviceProcAddr( device, "vkCmdTraceRaysIndirect2KHR" ) );
+
+ //=== VK_EXT_multi_draw ===
+ vkCmdDrawMultiEXT = PFN_vkCmdDrawMultiEXT( vkGetDeviceProcAddr( device, "vkCmdDrawMultiEXT" ) );
+ vkCmdDrawMultiIndexedEXT = PFN_vkCmdDrawMultiIndexedEXT( vkGetDeviceProcAddr( device, "vkCmdDrawMultiIndexedEXT" ) );
+
+ //=== VK_EXT_opacity_micromap ===
+ vkCreateMicromapEXT = PFN_vkCreateMicromapEXT( vkGetDeviceProcAddr( device, "vkCreateMicromapEXT" ) );
+ vkDestroyMicromapEXT = PFN_vkDestroyMicromapEXT( vkGetDeviceProcAddr( device, "vkDestroyMicromapEXT" ) );
+ vkCmdBuildMicromapsEXT = PFN_vkCmdBuildMicromapsEXT( vkGetDeviceProcAddr( device, "vkCmdBuildMicromapsEXT" ) );
+ vkBuildMicromapsEXT = PFN_vkBuildMicromapsEXT( vkGetDeviceProcAddr( device, "vkBuildMicromapsEXT" ) );
+ vkCopyMicromapEXT = PFN_vkCopyMicromapEXT( vkGetDeviceProcAddr( device, "vkCopyMicromapEXT" ) );
+ vkCopyMicromapToMemoryEXT = PFN_vkCopyMicromapToMemoryEXT( vkGetDeviceProcAddr( device, "vkCopyMicromapToMemoryEXT" ) );
+ vkCopyMemoryToMicromapEXT = PFN_vkCopyMemoryToMicromapEXT( vkGetDeviceProcAddr( device, "vkCopyMemoryToMicromapEXT" ) );
+ vkWriteMicromapsPropertiesEXT = PFN_vkWriteMicromapsPropertiesEXT( vkGetDeviceProcAddr( device, "vkWriteMicromapsPropertiesEXT" ) );
+ vkCmdCopyMicromapEXT = PFN_vkCmdCopyMicromapEXT( vkGetDeviceProcAddr( device, "vkCmdCopyMicromapEXT" ) );
+ vkCmdCopyMicromapToMemoryEXT = PFN_vkCmdCopyMicromapToMemoryEXT( vkGetDeviceProcAddr( device, "vkCmdCopyMicromapToMemoryEXT" ) );
+ vkCmdCopyMemoryToMicromapEXT = PFN_vkCmdCopyMemoryToMicromapEXT( vkGetDeviceProcAddr( device, "vkCmdCopyMemoryToMicromapEXT" ) );
+ vkCmdWriteMicromapsPropertiesEXT = PFN_vkCmdWriteMicromapsPropertiesEXT( vkGetDeviceProcAddr( device, "vkCmdWriteMicromapsPropertiesEXT" ) );
+ vkGetDeviceMicromapCompatibilityEXT = PFN_vkGetDeviceMicromapCompatibilityEXT( vkGetDeviceProcAddr( device, "vkGetDeviceMicromapCompatibilityEXT" ) );
+ vkGetMicromapBuildSizesEXT = PFN_vkGetMicromapBuildSizesEXT( vkGetDeviceProcAddr( device, "vkGetMicromapBuildSizesEXT" ) );
+
+ //=== VK_EXT_pageable_device_local_memory ===
+ vkSetDeviceMemoryPriorityEXT = PFN_vkSetDeviceMemoryPriorityEXT( vkGetDeviceProcAddr( device, "vkSetDeviceMemoryPriorityEXT" ) );
+
+ //=== VK_KHR_maintenance4 ===
+ vkGetDeviceBufferMemoryRequirementsKHR =
+ PFN_vkGetDeviceBufferMemoryRequirementsKHR( vkGetDeviceProcAddr( device, "vkGetDeviceBufferMemoryRequirementsKHR" ) );
+ if ( !vkGetDeviceBufferMemoryRequirements )
+ vkGetDeviceBufferMemoryRequirements = vkGetDeviceBufferMemoryRequirementsKHR;
+ vkGetDeviceImageMemoryRequirementsKHR =
+ PFN_vkGetDeviceImageMemoryRequirementsKHR( vkGetDeviceProcAddr( device, "vkGetDeviceImageMemoryRequirementsKHR" ) );
+ if ( !vkGetDeviceImageMemoryRequirements )
+ vkGetDeviceImageMemoryRequirements = vkGetDeviceImageMemoryRequirementsKHR;
+ vkGetDeviceImageSparseMemoryRequirementsKHR =
+ PFN_vkGetDeviceImageSparseMemoryRequirementsKHR( vkGetDeviceProcAddr( device, "vkGetDeviceImageSparseMemoryRequirementsKHR" ) );
+ if ( !vkGetDeviceImageSparseMemoryRequirements )
+ vkGetDeviceImageSparseMemoryRequirements = vkGetDeviceImageSparseMemoryRequirementsKHR;
+
+ //=== VK_VALVE_descriptor_set_host_mapping ===
+ vkGetDescriptorSetLayoutHostMappingInfoVALVE =
+ PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE( vkGetDeviceProcAddr( device, "vkGetDescriptorSetLayoutHostMappingInfoVALVE" ) );
+ vkGetDescriptorSetHostMappingVALVE = PFN_vkGetDescriptorSetHostMappingVALVE( vkGetDeviceProcAddr( device, "vkGetDescriptorSetHostMappingVALVE" ) );
+
+ //=== VK_EXT_extended_dynamic_state3 ===
+ vkCmdSetTessellationDomainOriginEXT = PFN_vkCmdSetTessellationDomainOriginEXT( vkGetDeviceProcAddr( device, "vkCmdSetTessellationDomainOriginEXT" ) );
+ vkCmdSetDepthClampEnableEXT = PFN_vkCmdSetDepthClampEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetDepthClampEnableEXT" ) );
+ vkCmdSetPolygonModeEXT = PFN_vkCmdSetPolygonModeEXT( vkGetDeviceProcAddr( device, "vkCmdSetPolygonModeEXT" ) );
+ vkCmdSetRasterizationSamplesEXT = PFN_vkCmdSetRasterizationSamplesEXT( vkGetDeviceProcAddr( device, "vkCmdSetRasterizationSamplesEXT" ) );
+ vkCmdSetSampleMaskEXT = PFN_vkCmdSetSampleMaskEXT( vkGetDeviceProcAddr( device, "vkCmdSetSampleMaskEXT" ) );
+ vkCmdSetAlphaToCoverageEnableEXT = PFN_vkCmdSetAlphaToCoverageEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetAlphaToCoverageEnableEXT" ) );
+ vkCmdSetAlphaToOneEnableEXT = PFN_vkCmdSetAlphaToOneEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetAlphaToOneEnableEXT" ) );
+ vkCmdSetLogicOpEnableEXT = PFN_vkCmdSetLogicOpEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetLogicOpEnableEXT" ) );
+ vkCmdSetColorBlendEnableEXT = PFN_vkCmdSetColorBlendEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetColorBlendEnableEXT" ) );
+ vkCmdSetColorBlendEquationEXT = PFN_vkCmdSetColorBlendEquationEXT( vkGetDeviceProcAddr( device, "vkCmdSetColorBlendEquationEXT" ) );
+ vkCmdSetColorWriteMaskEXT = PFN_vkCmdSetColorWriteMaskEXT( vkGetDeviceProcAddr( device, "vkCmdSetColorWriteMaskEXT" ) );
+ vkCmdSetRasterizationStreamEXT = PFN_vkCmdSetRasterizationStreamEXT( vkGetDeviceProcAddr( device, "vkCmdSetRasterizationStreamEXT" ) );
+ vkCmdSetConservativeRasterizationModeEXT =
+ PFN_vkCmdSetConservativeRasterizationModeEXT( vkGetDeviceProcAddr( device, "vkCmdSetConservativeRasterizationModeEXT" ) );
+ vkCmdSetExtraPrimitiveOverestimationSizeEXT =
+ PFN_vkCmdSetExtraPrimitiveOverestimationSizeEXT( vkGetDeviceProcAddr( device, "vkCmdSetExtraPrimitiveOverestimationSizeEXT" ) );
+ vkCmdSetDepthClipEnableEXT = PFN_vkCmdSetDepthClipEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetDepthClipEnableEXT" ) );
+ vkCmdSetSampleLocationsEnableEXT = PFN_vkCmdSetSampleLocationsEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetSampleLocationsEnableEXT" ) );
+ vkCmdSetColorBlendAdvancedEXT = PFN_vkCmdSetColorBlendAdvancedEXT( vkGetDeviceProcAddr( device, "vkCmdSetColorBlendAdvancedEXT" ) );
+ vkCmdSetProvokingVertexModeEXT = PFN_vkCmdSetProvokingVertexModeEXT( vkGetDeviceProcAddr( device, "vkCmdSetProvokingVertexModeEXT" ) );
+ vkCmdSetLineRasterizationModeEXT = PFN_vkCmdSetLineRasterizationModeEXT( vkGetDeviceProcAddr( device, "vkCmdSetLineRasterizationModeEXT" ) );
+ vkCmdSetLineStippleEnableEXT = PFN_vkCmdSetLineStippleEnableEXT( vkGetDeviceProcAddr( device, "vkCmdSetLineStippleEnableEXT" ) );
+ vkCmdSetDepthClipNegativeOneToOneEXT = PFN_vkCmdSetDepthClipNegativeOneToOneEXT( vkGetDeviceProcAddr( device, "vkCmdSetDepthClipNegativeOneToOneEXT" ) );
+ vkCmdSetViewportWScalingEnableNV = PFN_vkCmdSetViewportWScalingEnableNV( vkGetDeviceProcAddr( device, "vkCmdSetViewportWScalingEnableNV" ) );
+ vkCmdSetViewportSwizzleNV = PFN_vkCmdSetViewportSwizzleNV( vkGetDeviceProcAddr( device, "vkCmdSetViewportSwizzleNV" ) );
+ vkCmdSetCoverageToColorEnableNV = PFN_vkCmdSetCoverageToColorEnableNV( vkGetDeviceProcAddr( device, "vkCmdSetCoverageToColorEnableNV" ) );
+ vkCmdSetCoverageToColorLocationNV = PFN_vkCmdSetCoverageToColorLocationNV( vkGetDeviceProcAddr( device, "vkCmdSetCoverageToColorLocationNV" ) );
+ vkCmdSetCoverageModulationModeNV = PFN_vkCmdSetCoverageModulationModeNV( vkGetDeviceProcAddr( device, "vkCmdSetCoverageModulationModeNV" ) );
+ vkCmdSetCoverageModulationTableEnableNV =
+ PFN_vkCmdSetCoverageModulationTableEnableNV( vkGetDeviceProcAddr( device, "vkCmdSetCoverageModulationTableEnableNV" ) );
+ vkCmdSetCoverageModulationTableNV = PFN_vkCmdSetCoverageModulationTableNV( vkGetDeviceProcAddr( device, "vkCmdSetCoverageModulationTableNV" ) );
+ vkCmdSetShadingRateImageEnableNV = PFN_vkCmdSetShadingRateImageEnableNV( vkGetDeviceProcAddr( device, "vkCmdSetShadingRateImageEnableNV" ) );
+ vkCmdSetRepresentativeFragmentTestEnableNV =
+ PFN_vkCmdSetRepresentativeFragmentTestEnableNV( vkGetDeviceProcAddr( device, "vkCmdSetRepresentativeFragmentTestEnableNV" ) );
+ vkCmdSetCoverageReductionModeNV = PFN_vkCmdSetCoverageReductionModeNV( vkGetDeviceProcAddr( device, "vkCmdSetCoverageReductionModeNV" ) );
+
+ //=== VK_EXT_shader_module_identifier ===
+ vkGetShaderModuleIdentifierEXT = PFN_vkGetShaderModuleIdentifierEXT( vkGetDeviceProcAddr( device, "vkGetShaderModuleIdentifierEXT" ) );
+ vkGetShaderModuleCreateInfoIdentifierEXT =
+ PFN_vkGetShaderModuleCreateInfoIdentifierEXT( vkGetDeviceProcAddr( device, "vkGetShaderModuleCreateInfoIdentifierEXT" ) );
+
+ //=== VK_NV_optical_flow ===
+ vkCreateOpticalFlowSessionNV = PFN_vkCreateOpticalFlowSessionNV( vkGetDeviceProcAddr( device, "vkCreateOpticalFlowSessionNV" ) );
+ vkDestroyOpticalFlowSessionNV = PFN_vkDestroyOpticalFlowSessionNV( vkGetDeviceProcAddr( device, "vkDestroyOpticalFlowSessionNV" ) );
+ vkBindOpticalFlowSessionImageNV = PFN_vkBindOpticalFlowSessionImageNV( vkGetDeviceProcAddr( device, "vkBindOpticalFlowSessionImageNV" ) );
+ vkCmdOpticalFlowExecuteNV = PFN_vkCmdOpticalFlowExecuteNV( vkGetDeviceProcAddr( device, "vkCmdOpticalFlowExecuteNV" ) );
+
+ //=== VK_QCOM_tile_properties ===
+ vkGetFramebufferTilePropertiesQCOM = PFN_vkGetFramebufferTilePropertiesQCOM( vkGetDeviceProcAddr( device, "vkGetFramebufferTilePropertiesQCOM" ) );
+ vkGetDynamicRenderingTilePropertiesQCOM =
+ PFN_vkGetDynamicRenderingTilePropertiesQCOM( vkGetDeviceProcAddr( device, "vkGetDynamicRenderingTilePropertiesQCOM" ) );
+ }
+ };
+} // namespace VULKAN_HPP_NAMESPACE
+#endif
diff --git a/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan_core.h b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan_core.h
new file mode 100644
index 0000000000..b7fddd1906
--- /dev/null
+++ b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan_core.h
@@ -0,0 +1,16027 @@
+#ifndef VULKAN_CORE_H_
+#define VULKAN_CORE_H_ 1
+
+/*
+** Copyright 2015-2022 The Khronos Group Inc.
+**
+** SPDX-License-Identifier: Apache-2.0
+*/
+
+/*
+** This header is generated from the Khronos Vulkan XML API Registry.
+**
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#define VK_VERSION_1_0 1
+#include "vk_platform.h"
+
+#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
+
+
+#ifndef VK_USE_64_BIT_PTR_DEFINES
+ #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
+ #define VK_USE_64_BIT_PTR_DEFINES 1
+ #else
+ #define VK_USE_64_BIT_PTR_DEFINES 0
+ #endif
+#endif
+
+
+#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE
+ #if (VK_USE_64_BIT_PTR_DEFINES==1)
+ #if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L))
+ #define VK_NULL_HANDLE nullptr
+ #else
+ #define VK_NULL_HANDLE ((void*)0)
+ #endif
+ #else
+ #define VK_NULL_HANDLE 0ULL
+ #endif
+#endif
+#ifndef VK_NULL_HANDLE
+ #define VK_NULL_HANDLE 0
+#endif
+
+
+#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE
+ #if (VK_USE_64_BIT_PTR_DEFINES==1)
+ #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
+ #else
+ #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
+ #endif
+#endif
+
+// DEPRECATED: This define is deprecated. VK_MAKE_API_VERSION should be used instead.
+#define VK_MAKE_VERSION(major, minor, patch) \
+ ((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch)))
+
+// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead.
+//#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) // Patch version should always be set to 0
+
+#define VK_MAKE_API_VERSION(variant, major, minor, patch) \
+ ((((uint32_t)(variant)) << 29) | (((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch)))
+
+// Vulkan 1.0 version number
+#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0
+
+// Version of this file
+#define VK_HEADER_VERSION 231
+
+// Complete version of this file
+#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION)
+
+// DEPRECATED: This define is deprecated. VK_API_VERSION_MAJOR should be used instead.
+#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22)
+
+// DEPRECATED: This define is deprecated. VK_API_VERSION_MINOR should be used instead.
+#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU)
+
+// DEPRECATED: This define is deprecated. VK_API_VERSION_PATCH should be used instead.
+#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU)
+
+#define VK_API_VERSION_VARIANT(version) ((uint32_t)(version) >> 29)
+#define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22) & 0x7FU)
+#define VK_API_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU)
+#define VK_API_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU)
+typedef uint32_t VkBool32;
+typedef uint64_t VkDeviceAddress;
+typedef uint64_t VkDeviceSize;
+typedef uint32_t VkFlags;
+typedef uint32_t VkSampleMask;
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage)
+VK_DEFINE_HANDLE(VkInstance)
+VK_DEFINE_HANDLE(VkPhysicalDevice)
+VK_DEFINE_HANDLE(VkDevice)
+VK_DEFINE_HANDLE(VkQueue)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore)
+VK_DEFINE_HANDLE(VkCommandBuffer)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool)
+#define VK_ATTACHMENT_UNUSED (~0U)
+#define VK_FALSE 0U
+#define VK_LOD_CLAMP_NONE 1000.0F
+#define VK_QUEUE_FAMILY_IGNORED (~0U)
+#define VK_REMAINING_ARRAY_LAYERS (~0U)
+#define VK_REMAINING_MIP_LEVELS (~0U)
+#define VK_SUBPASS_EXTERNAL (~0U)
+#define VK_TRUE 1U
+#define VK_WHOLE_SIZE (~0ULL)
+#define VK_MAX_MEMORY_TYPES 32U
+#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256U
+#define VK_UUID_SIZE 16U
+#define VK_MAX_EXTENSION_NAME_SIZE 256U
+#define VK_MAX_DESCRIPTION_SIZE 256U
+#define VK_MAX_MEMORY_HEAPS 16U
+
+typedef enum VkResult {
+ VK_SUCCESS = 0,
+ VK_NOT_READY = 1,
+ VK_TIMEOUT = 2,
+ VK_EVENT_SET = 3,
+ VK_EVENT_RESET = 4,
+ VK_INCOMPLETE = 5,
+ VK_ERROR_OUT_OF_HOST_MEMORY = -1,
+ VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
+ VK_ERROR_INITIALIZATION_FAILED = -3,
+ VK_ERROR_DEVICE_LOST = -4,
+ VK_ERROR_MEMORY_MAP_FAILED = -5,
+ VK_ERROR_LAYER_NOT_PRESENT = -6,
+ VK_ERROR_EXTENSION_NOT_PRESENT = -7,
+ VK_ERROR_FEATURE_NOT_PRESENT = -8,
+ VK_ERROR_INCOMPATIBLE_DRIVER = -9,
+ VK_ERROR_TOO_MANY_OBJECTS = -10,
+ VK_ERROR_FORMAT_NOT_SUPPORTED = -11,
+ VK_ERROR_FRAGMENTED_POOL = -12,
+ VK_ERROR_UNKNOWN = -13,
+ VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000,
+ VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003,
+ VK_ERROR_FRAGMENTATION = -1000161000,
+ VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000,
+ VK_PIPELINE_COMPILE_REQUIRED = 1000297000,
+ VK_ERROR_SURFACE_LOST_KHR = -1000000000,
+ VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001,
+ VK_SUBOPTIMAL_KHR = 1000001003,
+ VK_ERROR_OUT_OF_DATE_KHR = -1000001004,
+ VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
+ VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
+ VK_ERROR_INVALID_SHADER_NV = -1000012000,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR = -1000023000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR = -1000023001,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR = -1000023002,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR = -1000023003,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR = -1000023004,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR = -1000023005,
+#endif
+ VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000,
+ VK_ERROR_NOT_PERMITTED_KHR = -1000174001,
+ VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000,
+ VK_THREAD_IDLE_KHR = 1000268000,
+ VK_THREAD_DONE_KHR = 1000268001,
+ VK_OPERATION_DEFERRED_KHR = 1000268002,
+ VK_OPERATION_NOT_DEFERRED_KHR = 1000268003,
+ VK_ERROR_COMPRESSION_EXHAUSTED_EXT = -1000338000,
+ VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY,
+ VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE,
+ VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION,
+ VK_ERROR_NOT_PERMITTED_EXT = VK_ERROR_NOT_PERMITTED_KHR,
+ VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
+ VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS,
+ VK_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED,
+ VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED,
+ VK_RESULT_MAX_ENUM = 0x7FFFFFFF
+} VkResult;
+
+typedef enum VkStructureType {
+ VK_STRUCTURE_TYPE_APPLICATION_INFO = 0,
+ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1,
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2,
+ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3,
+ VK_STRUCTURE_TYPE_SUBMIT_INFO = 4,
+ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5,
+ VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6,
+ VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7,
+ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8,
+ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9,
+ VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10,
+ VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11,
+ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12,
+ VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13,
+ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14,
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15,
+ VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16,
+ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17,
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18,
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19,
+ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20,
+ VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21,
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22,
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23,
+ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24,
+ VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25,
+ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26,
+ VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27,
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28,
+ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29,
+ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30,
+ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34,
+ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35,
+ VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36,
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37,
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38,
+ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42,
+ VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43,
+ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44,
+ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45,
+ VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46,
+ VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47,
+ VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000,
+ VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO = 1000157000,
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO = 1000157001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000,
+ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS = 1000127000,
+ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001,
+ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO = 1000060000,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO = 1000060005,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006,
+ VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013,
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001,
+ VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000,
+ VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001,
+ VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002,
+ VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 = 1000146003,
+ VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 = 1000059000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001,
+ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 = 1000059002,
+ VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 = 1000059003,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004,
+ VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2 = 1000059005,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006,
+ VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000,
+ VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001,
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002,
+ VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003,
+ VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000,
+ VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO = 1000145000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002,
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2 = 1000145003,
+ VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000,
+ VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO = 1000156001,
+ VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002,
+ VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004,
+ VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000,
+ VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002,
+ VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES = 1000071003,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004,
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000,
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001,
+ VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO = 1000072002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000,
+ VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES = 1000112001,
+ VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO = 1000113000,
+ VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO = 1000077000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000,
+ VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52,
+ VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000,
+ VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000,
+ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001,
+ VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002,
+ VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003,
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004,
+ VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005,
+ VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000,
+ VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000,
+ VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000,
+ VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000,
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001,
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002,
+ VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000,
+ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001,
+ VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001,
+ VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO = 1000207002,
+ VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003,
+ VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO = 1000207004,
+ VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO = 1000207005,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000,
+ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO = 1000244001,
+ VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002,
+ VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003,
+ VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES = 53,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES = 54,
+ VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES = 1000245000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES = 1000295000,
+ VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO = 1000295001,
+ VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO = 1000295002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000,
+ VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 = 1000314000,
+ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 = 1000314001,
+ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 = 1000314002,
+ VK_STRUCTURE_TYPE_DEPENDENCY_INFO = 1000314003,
+ VK_STRUCTURE_TYPE_SUBMIT_INFO_2 = 1000314004,
+ VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO = 1000314005,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO = 1000314006,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES = 1000314007,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000,
+ VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 = 1000337000,
+ VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2 = 1000337001,
+ VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 = 1000337002,
+ VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2 = 1000337003,
+ VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 = 1000337004,
+ VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2 = 1000337005,
+ VK_STRUCTURE_TYPE_BUFFER_COPY_2 = 1000337006,
+ VK_STRUCTURE_TYPE_IMAGE_COPY_2 = 1000337007,
+ VK_STRUCTURE_TYPE_IMAGE_BLIT_2 = 1000337008,
+ VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 = 1000337009,
+ VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2 = 1000337010,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES = 1000225000,
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO = 1000225001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES = 1000225002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES = 1000138000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES = 1000138001,
+ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK = 1000138002,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO = 1000138003,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000,
+ VK_STRUCTURE_TYPE_RENDERING_INFO = 1000044000,
+ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO = 1000044001,
+ VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO = 1000044002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES = 1000044003,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO = 1000044004,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001,
+ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 = 1000360000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001,
+ VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002,
+ VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003,
+ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000,
+ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007,
+ VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008,
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009,
+ VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012,
+ VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR = 1000002000,
+ VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001,
+ VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR = 1000003000,
+ VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
+ VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
+ VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
+ VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000,
+ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
+ VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000,
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000,
+ VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000,
+ VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001,
+ VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR = 1000023000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR = 1000023001,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR = 1000023002,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_SESSION_MEMORY_REQUIREMENTS_KHR = 1000023003,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_BIND_VIDEO_SESSION_MEMORY_INFO_KHR = 1000023004,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR = 1000023005,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000023006,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_UPDATE_INFO_KHR = 1000023007,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR = 1000023008,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR = 1000023009,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR = 1000023010,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR = 1000023011,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR = 1000023012,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR = 1000023013,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR = 1000023014,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR = 1000023015,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_KHR = 1000023016,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR = 1000024000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR = 1000024001,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_USAGE_INFO_KHR = 1000024002,
+#endif
+ VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000,
+ VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001,
+ VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001,
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002,
+ VK_STRUCTURE_TYPE_CU_MODULE_CREATE_INFO_NVX = 1000029000,
+ VK_STRUCTURE_TYPE_CU_FUNCTION_CREATE_INFO_NVX = 1000029001,
+ VK_STRUCTURE_TYPE_CU_LAUNCH_INFO_NVX = 1000029002,
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000,
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_CAPABILITIES_EXT = 1000038000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038001,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038002,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038003,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038004,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_INFO_EXT = 1000038005,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_INFO_EXT = 1000038006,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_EXT = 1000038007,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_INFO_EXT = 1000038008,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_LAYER_INFO_EXT = 1000038009,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_REFERENCE_LISTS_INFO_EXT = 1000038010,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_CAPABILITIES_EXT = 1000039000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000039001,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000039002,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_VCL_FRAME_INFO_EXT = 1000039003,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_EXT = 1000039004,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_NALU_SLICE_SEGMENT_INFO_EXT = 1000039005,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_EMIT_PICTURE_PARAMETERS_INFO_EXT = 1000039006,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_EXT = 1000039007,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_REFERENCE_LISTS_INFO_EXT = 1000039008,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_EXT = 1000039009,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_EXT = 1000039010,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_EXT = 1000040000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040001,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_EXT = 1000040003,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040004,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040005,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040006,
+#endif
+ VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000,
+ VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000044006,
+ VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT = 1000044007,
+ VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD = 1000044008,
+ VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_ATTRIBUTES_INFO_NVX = 1000044009,
+ VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000,
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000,
+ VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001,
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000,
+ VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001,
+ VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000,
+ VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000,
+ VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000,
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001,
+ VK_STRUCTURE_TYPE_PIPELINE_ROBUSTNESS_CREATE_INFO_EXT = 1000068000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT = 1000068001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES_EXT = 1000068002,
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000,
+ VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001,
+ VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002,
+ VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003,
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR = 1000074000,
+ VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR = 1000074001,
+ VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR = 1000074002,
+ VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000,
+ VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000,
+ VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001,
+ VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002,
+ VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003,
+ VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000,
+ VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001,
+ VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002,
+ VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000,
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000,
+ VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT = 1000090000,
+ VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000,
+ VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT = 1000091001,
+ VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT = 1000091002,
+ VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003,
+ VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000,
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000,
+ VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000,
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000,
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001,
+ VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000,
+ VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000,
+ VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000,
+ VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001,
+ VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002,
+ VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR = 1000115000,
+ VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR = 1000115001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR = 1000116000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR = 1000116001,
+ VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR = 1000116002,
+ VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR = 1000116003,
+ VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR = 1000116004,
+ VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR = 1000116005,
+ VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_DESCRIPTION_KHR = 1000116006,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000,
+ VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001,
+ VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002,
+ VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR = 1000121000,
+ VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001,
+ VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002,
+ VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR = 1000121003,
+ VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004,
+ VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000,
+ VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
+ VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000,
+ VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT = 1000128001,
+ VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT = 1000128002,
+ VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003,
+ VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004,
+ VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID = 1000129000,
+ VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID = 1000129001,
+ VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID = 1000129002,
+ VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003,
+ VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004,
+ VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005,
+ VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID = 1000129006,
+ VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000,
+ VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001,
+ VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003,
+ VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001,
+ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002,
+ VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000,
+ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR = 1000150007,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR = 1000150000,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR = 1000150002,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR = 1000150003,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR = 1000150004,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR = 1000150005,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR = 1000150006,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_VERSION_INFO_KHR = 1000150009,
+ VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR = 1000150010,
+ VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR = 1000150011,
+ VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR = 1000150012,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR = 1000150013,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR = 1000150014,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR = 1000150020,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR = 1000347000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR = 1000347001,
+ VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR = 1000150015,
+ VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR = 1000150016,
+ VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR = 1000150018,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR = 1000348013,
+ VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV = 1000154000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV = 1000154001,
+ VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002,
+ VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003,
+ VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004,
+ VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005,
+ VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT = 1000158006,
+ VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000,
+ VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR = 1000163000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR = 1000163001,
+#endif
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002,
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005,
+ VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001,
+ VK_STRUCTURE_TYPE_GEOMETRY_NV = 1000165003,
+ VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV = 1000165004,
+ VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV = 1000165005,
+ VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006,
+ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009,
+ VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV = 1000165012,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000,
+ VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000,
+ VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001,
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000,
+ VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000,
+ VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000,
+ VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_EXT = 1000187000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187001,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187002,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_EXT = 1000187003,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187004,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187005,
+#endif
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR = 1000174000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR = 1000388000,
+ VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR = 1000388001,
+ VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000,
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002,
+ VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000,
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002,
+ VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000,
+ VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000,
+ VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000,
+ VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001,
+ VK_STRUCTURE_TYPE_PERFORMANCE_MARKER_INFO_INTEL = 1000210002,
+ VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003,
+ VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004,
+ VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000,
+ VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000,
+ VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001,
+ VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000,
+ VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001,
+ VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002,
+ VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000,
+ VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR = 1000226003,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR = 1000226004,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD = 1000227000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD = 1000229000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT = 1000234000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000,
+ VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001,
+ VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000,
+ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002,
+ VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000,
+ VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV = 1000250000,
+ VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV = 1000250001,
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT = 1000254000,
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT = 1000254001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT = 1000254002,
+ VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000,
+ VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002,
+ VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001,
+ VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000,
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT = 1000260000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT = 1000267000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000,
+ VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR = 1000269001,
+ VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR = 1000269002,
+ VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR = 1000269003,
+ VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004,
+ VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000,
+ VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001,
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002,
+ VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_NV = 1000277003,
+ VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV = 1000277004,
+ VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_NV = 1000277005,
+ VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV = 1000277006,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000,
+ VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000,
+ VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT = 1000284001,
+ VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT = 1000284002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001,
+ VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002,
+ VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_BARRIER_FEATURES_NV = 1000292000,
+ VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_PRESENT_BARRIER_NV = 1000292001,
+ VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_BARRIER_CREATE_INFO_NV = 1000292002,
+ VK_STRUCTURE_TYPE_PRESENT_ID_KHR = 1000294000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR = 1000299000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_INFO_KHR = 1000299001,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR = 1000299002,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR = 1000299003,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_USAGE_INFO_KHR = 1000299004,
+#endif
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000,
+ VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001,
+ VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECT_CREATE_INFO_EXT = 1000311000,
+ VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECTS_INFO_EXT = 1000311001,
+ VK_STRUCTURE_TYPE_EXPORT_METAL_DEVICE_INFO_EXT = 1000311002,
+ VK_STRUCTURE_TYPE_EXPORT_METAL_COMMAND_QUEUE_INFO_EXT = 1000311003,
+ VK_STRUCTURE_TYPE_EXPORT_METAL_BUFFER_INFO_EXT = 1000311004,
+ VK_STRUCTURE_TYPE_IMPORT_METAL_BUFFER_INFO_EXT = 1000311005,
+ VK_STRUCTURE_TYPE_EXPORT_METAL_TEXTURE_INFO_EXT = 1000311006,
+ VK_STRUCTURE_TYPE_IMPORT_METAL_TEXTURE_INFO_EXT = 1000311007,
+ VK_STRUCTURE_TYPE_EXPORT_METAL_IO_SURFACE_INFO_EXT = 1000311008,
+ VK_STRUCTURE_TYPE_IMPORT_METAL_IO_SURFACE_INFO_EXT = 1000311009,
+ VK_STRUCTURE_TYPE_EXPORT_METAL_SHARED_EVENT_INFO_EXT = 1000311010,
+ VK_STRUCTURE_TYPE_IMPORT_METAL_SHARED_EVENT_INFO_EXT = 1000311011,
+ VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008,
+ VK_STRUCTURE_TYPE_CHECKPOINT_DATA_2_NV = 1000314009,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT = 1000320000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT = 1000320001,
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT = 1000320002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD = 1000321000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR = 1000203000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_PROPERTIES_KHR = 1000322000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR = 1000323000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001,
+ VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_MOTION_TRIANGLES_DATA_NV = 1000327000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV = 1000327001,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MOTION_INFO_NV = 1000327002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT = 1000328000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_EXT = 1000328001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT = 1000330000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001,
+ VK_STRUCTURE_TYPE_COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR = 1000336000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT = 1000338000,
+ VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT = 1000338001,
+ VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_EXT = 1000338002,
+ VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_EXT = 1000338003,
+ VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT = 1000338004,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT = 1000339000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT = 1000341000,
+ VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT = 1000341001,
+ VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT = 1000341002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT = 1000344000,
+ VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT = 1000352000,
+ VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001,
+ VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ADDRESS_BINDING_REPORT_FEATURES_EXT = 1000354000,
+ VK_STRUCTURE_TYPE_DEVICE_ADDRESS_BINDING_CALLBACK_DATA_EXT = 1000354001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT = 1000355000,
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT = 1000355001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000,
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000,
+ VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001,
+ VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002,
+ VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000,
+ VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001,
+ VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA = 1000366000,
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA = 1000366001,
+ VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA = 1000366002,
+ VK_STRUCTURE_TYPE_BUFFER_COLLECTION_PROPERTIES_FUCHSIA = 1000366003,
+ VK_STRUCTURE_TYPE_BUFFER_CONSTRAINTS_INFO_FUCHSIA = 1000366004,
+ VK_STRUCTURE_TYPE_BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA = 1000366005,
+ VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA = 1000366006,
+ VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA = 1000366007,
+ VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA = 1000366008,
+ VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA = 1000366009,
+ VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI = 1000370000,
+ VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV = 1000371000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001,
+ VK_STRUCTURE_TYPE_PIPELINE_PROPERTIES_IDENTIFIER_EXT = 1000372000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT = 1000372001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT = 1000376000,
+ VK_STRUCTURE_TYPE_SUBPASS_RESOLVE_PERFORMANCE_QUERY_EXT = 1000376001,
+ VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT = 1000376002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000,
+ VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000,
+ VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT = 1000382000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MAINTENANCE_1_FEATURES_KHR = 1000386000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT = 1000391000,
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT = 1000391001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT = 1000393000,
+ VK_STRUCTURE_TYPE_MICROMAP_BUILD_INFO_EXT = 1000396000,
+ VK_STRUCTURE_TYPE_MICROMAP_VERSION_INFO_EXT = 1000396001,
+ VK_STRUCTURE_TYPE_COPY_MICROMAP_INFO_EXT = 1000396002,
+ VK_STRUCTURE_TYPE_COPY_MICROMAP_TO_MEMORY_INFO_EXT = 1000396003,
+ VK_STRUCTURE_TYPE_COPY_MEMORY_TO_MICROMAP_INFO_EXT = 1000396004,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_FEATURES_EXT = 1000396005,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_PROPERTIES_EXT = 1000396006,
+ VK_STRUCTURE_TYPE_MICROMAP_CREATE_INFO_EXT = 1000396007,
+ VK_STRUCTURE_TYPE_MICROMAP_BUILD_SIZES_INFO_EXT = 1000396008,
+ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_TRIANGLES_OPACITY_MICROMAP_EXT = 1000396009,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT = 1000411000,
+ VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT = 1000411001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE = 1000420000,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_BINDING_REFERENCE_VALVE = 1000420001,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_HOST_MAPPING_INFO_VALVE = 1000420002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_EXT = 1000421000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT = 1000422000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM = 1000425000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM = 1000425001,
+ VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM = 1000425002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV = 1000430000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT = 1000437000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM = 1000440000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_PROPERTIES_QCOM = 1000440001,
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_SAMPLE_WEIGHT_CREATE_INFO_QCOM = 1000440002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT = 1000455000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_PROPERTIES_EXT = 1000455001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_MERGE_FEEDBACK_FEATURES_EXT = 1000458000,
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_CONTROL_EXT = 1000458001,
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000458002,
+ VK_STRUCTURE_TYPE_RENDER_PASS_SUBPASS_FEEDBACK_CREATE_INFO_EXT = 1000458003,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT = 1000462000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT = 1000462001,
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT = 1000462002,
+ VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT = 1000462003,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT = 1000342000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV = 1000464000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_PROPERTIES_NV = 1000464001,
+ VK_STRUCTURE_TYPE_OPTICAL_FLOW_IMAGE_FORMAT_INFO_NV = 1000464002,
+ VK_STRUCTURE_TYPE_OPTICAL_FLOW_IMAGE_FORMAT_PROPERTIES_NV = 1000464003,
+ VK_STRUCTURE_TYPE_OPTICAL_FLOW_SESSION_CREATE_INFO_NV = 1000464004,
+ VK_STRUCTURE_TYPE_OPTICAL_FLOW_EXECUTE_INFO_NV = 1000464005,
+ VK_STRUCTURE_TYPE_OPTICAL_FLOW_SESSION_CREATE_PRIVATE_DATA_INFO_NV = 1000464010,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT = 1000465000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT = 1000466000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM = 1000484000,
+ VK_STRUCTURE_TYPE_TILE_PROPERTIES_QCOM = 1000484001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC = 1000485000,
+ VK_STRUCTURE_TYPE_AMIGO_PROFILING_SUBMIT_INFO_SEC = 1000485001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT = 1000351000,
+ VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT = 1000351002,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_FEATURES_ARM = 1000497000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_PROPERTIES_ARM = 1000497001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES,
+ VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
+ VK_STRUCTURE_TYPE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_INFO,
+ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
+ VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO,
+ VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_NV = VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD,
+ VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
+ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
+ VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
+ VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2,
+ VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
+ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO,
+ VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO,
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES,
+ VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
+ VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
+ VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES,
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
+ VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
+ VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES,
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO,
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,
+ VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,
+ VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
+ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
+ VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
+ VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
+ VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
+ VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
+ VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
+ VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES,
+ VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR,
+ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
+ VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES,
+ VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES,
+ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO,
+ VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
+ VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
+ VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
+ VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
+ VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2,
+ VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
+ VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
+ VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
+ VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO,
+ VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
+ VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES,
+ VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
+ VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT,
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES,
+ VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES,
+ VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES,
+ VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
+ VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
+ VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO,
+ VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES,
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES,
+ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT,
+ VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT,
+ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES,
+ VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES,
+ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
+ VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO,
+ VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO,
+ VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES,
+ VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES,
+ VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2,
+ VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
+ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
+ VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
+ VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR = VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
+ VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES,
+ VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2,
+ VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2,
+ VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2,
+ VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2,
+ VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2,
+ VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2,
+ VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_COPY_2,
+ VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_IMAGE_COPY_2,
+ VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = VK_STRUCTURE_TYPE_IMAGE_BLIT_2,
+ VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2,
+ VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT,
+ VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE = VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT,
+ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
+ VK_STRUCTURE_TYPE_PIPELINE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR,
+ VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES,
+ VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS,
+ VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS,
+ VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkStructureType;
+
+typedef enum VkPipelineCacheHeaderVersion {
+ VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1,
+ VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineCacheHeaderVersion;
+
+typedef enum VkImageLayout {
+ VK_IMAGE_LAYOUT_UNDEFINED = 0,
+ VK_IMAGE_LAYOUT_GENERAL = 1,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2,
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3,
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5,
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7,
+ VK_IMAGE_LAYOUT_PREINITIALIZED = 8,
+ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000,
+ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001,
+ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000,
+ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001,
+ VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002,
+ VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003,
+ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL = 1000314000,
+ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL = 1000314001,
+ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR = 1000024000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR = 1000024001,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR = 1000024002,
+#endif
+ VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000,
+ VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000,
+ VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR = 1000164003,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR = 1000299000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR = 1000299001,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR = 1000299002,
+#endif
+ VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT = 1000339000,
+ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,
+ VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR,
+ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,
+ VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,
+ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
+ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL,
+ VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF
+} VkImageLayout;
+
+typedef enum VkObjectType {
+ VK_OBJECT_TYPE_UNKNOWN = 0,
+ VK_OBJECT_TYPE_INSTANCE = 1,
+ VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2,
+ VK_OBJECT_TYPE_DEVICE = 3,
+ VK_OBJECT_TYPE_QUEUE = 4,
+ VK_OBJECT_TYPE_SEMAPHORE = 5,
+ VK_OBJECT_TYPE_COMMAND_BUFFER = 6,
+ VK_OBJECT_TYPE_FENCE = 7,
+ VK_OBJECT_TYPE_DEVICE_MEMORY = 8,
+ VK_OBJECT_TYPE_BUFFER = 9,
+ VK_OBJECT_TYPE_IMAGE = 10,
+ VK_OBJECT_TYPE_EVENT = 11,
+ VK_OBJECT_TYPE_QUERY_POOL = 12,
+ VK_OBJECT_TYPE_BUFFER_VIEW = 13,
+ VK_OBJECT_TYPE_IMAGE_VIEW = 14,
+ VK_OBJECT_TYPE_SHADER_MODULE = 15,
+ VK_OBJECT_TYPE_PIPELINE_CACHE = 16,
+ VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17,
+ VK_OBJECT_TYPE_RENDER_PASS = 18,
+ VK_OBJECT_TYPE_PIPELINE = 19,
+ VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20,
+ VK_OBJECT_TYPE_SAMPLER = 21,
+ VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22,
+ VK_OBJECT_TYPE_DESCRIPTOR_SET = 23,
+ VK_OBJECT_TYPE_FRAMEBUFFER = 24,
+ VK_OBJECT_TYPE_COMMAND_POOL = 25,
+ VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000,
+ VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000,
+ VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000,
+ VK_OBJECT_TYPE_SURFACE_KHR = 1000000000,
+ VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000,
+ VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000,
+ VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001,
+ VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_OBJECT_TYPE_VIDEO_SESSION_KHR = 1000023000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR = 1000023001,
+#endif
+ VK_OBJECT_TYPE_CU_MODULE_NVX = 1000029000,
+ VK_OBJECT_TYPE_CU_FUNCTION_NVX = 1000029001,
+ VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000,
+ VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000,
+ VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000,
+ VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000,
+ VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000,
+ VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000,
+ VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV = 1000277000,
+ VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = 1000366000,
+ VK_OBJECT_TYPE_MICROMAP_EXT = 1000396000,
+ VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV = 1000464000,
+ VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE,
+ VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,
+ VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = VK_OBJECT_TYPE_PRIVATE_DATA_SLOT,
+ VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkObjectType;
+
+typedef enum VkVendorId {
+ VK_VENDOR_ID_VIV = 0x10001,
+ VK_VENDOR_ID_VSI = 0x10002,
+ VK_VENDOR_ID_KAZAN = 0x10003,
+ VK_VENDOR_ID_CODEPLAY = 0x10004,
+ VK_VENDOR_ID_MESA = 0x10005,
+ VK_VENDOR_ID_POCL = 0x10006,
+ VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF
+} VkVendorId;
+
+typedef enum VkSystemAllocationScope {
+ VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1,
+ VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4,
+ VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF
+} VkSystemAllocationScope;
+
+typedef enum VkInternalAllocationType {
+ VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0,
+ VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkInternalAllocationType;
+
+typedef enum VkFormat {
+ VK_FORMAT_UNDEFINED = 0,
+ VK_FORMAT_R4G4_UNORM_PACK8 = 1,
+ VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2,
+ VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3,
+ VK_FORMAT_R5G6B5_UNORM_PACK16 = 4,
+ VK_FORMAT_B5G6R5_UNORM_PACK16 = 5,
+ VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6,
+ VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7,
+ VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8,
+ VK_FORMAT_R8_UNORM = 9,
+ VK_FORMAT_R8_SNORM = 10,
+ VK_FORMAT_R8_USCALED = 11,
+ VK_FORMAT_R8_SSCALED = 12,
+ VK_FORMAT_R8_UINT = 13,
+ VK_FORMAT_R8_SINT = 14,
+ VK_FORMAT_R8_SRGB = 15,
+ VK_FORMAT_R8G8_UNORM = 16,
+ VK_FORMAT_R8G8_SNORM = 17,
+ VK_FORMAT_R8G8_USCALED = 18,
+ VK_FORMAT_R8G8_SSCALED = 19,
+ VK_FORMAT_R8G8_UINT = 20,
+ VK_FORMAT_R8G8_SINT = 21,
+ VK_FORMAT_R8G8_SRGB = 22,
+ VK_FORMAT_R8G8B8_UNORM = 23,
+ VK_FORMAT_R8G8B8_SNORM = 24,
+ VK_FORMAT_R8G8B8_USCALED = 25,
+ VK_FORMAT_R8G8B8_SSCALED = 26,
+ VK_FORMAT_R8G8B8_UINT = 27,
+ VK_FORMAT_R8G8B8_SINT = 28,
+ VK_FORMAT_R8G8B8_SRGB = 29,
+ VK_FORMAT_B8G8R8_UNORM = 30,
+ VK_FORMAT_B8G8R8_SNORM = 31,
+ VK_FORMAT_B8G8R8_USCALED = 32,
+ VK_FORMAT_B8G8R8_SSCALED = 33,
+ VK_FORMAT_B8G8R8_UINT = 34,
+ VK_FORMAT_B8G8R8_SINT = 35,
+ VK_FORMAT_B8G8R8_SRGB = 36,
+ VK_FORMAT_R8G8B8A8_UNORM = 37,
+ VK_FORMAT_R8G8B8A8_SNORM = 38,
+ VK_FORMAT_R8G8B8A8_USCALED = 39,
+ VK_FORMAT_R8G8B8A8_SSCALED = 40,
+ VK_FORMAT_R8G8B8A8_UINT = 41,
+ VK_FORMAT_R8G8B8A8_SINT = 42,
+ VK_FORMAT_R8G8B8A8_SRGB = 43,
+ VK_FORMAT_B8G8R8A8_UNORM = 44,
+ VK_FORMAT_B8G8R8A8_SNORM = 45,
+ VK_FORMAT_B8G8R8A8_USCALED = 46,
+ VK_FORMAT_B8G8R8A8_SSCALED = 47,
+ VK_FORMAT_B8G8R8A8_UINT = 48,
+ VK_FORMAT_B8G8R8A8_SINT = 49,
+ VK_FORMAT_B8G8R8A8_SRGB = 50,
+ VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51,
+ VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52,
+ VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53,
+ VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54,
+ VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55,
+ VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56,
+ VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57,
+ VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58,
+ VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59,
+ VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60,
+ VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61,
+ VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62,
+ VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63,
+ VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64,
+ VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65,
+ VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66,
+ VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67,
+ VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68,
+ VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69,
+ VK_FORMAT_R16_UNORM = 70,
+ VK_FORMAT_R16_SNORM = 71,
+ VK_FORMAT_R16_USCALED = 72,
+ VK_FORMAT_R16_SSCALED = 73,
+ VK_FORMAT_R16_UINT = 74,
+ VK_FORMAT_R16_SINT = 75,
+ VK_FORMAT_R16_SFLOAT = 76,
+ VK_FORMAT_R16G16_UNORM = 77,
+ VK_FORMAT_R16G16_SNORM = 78,
+ VK_FORMAT_R16G16_USCALED = 79,
+ VK_FORMAT_R16G16_SSCALED = 80,
+ VK_FORMAT_R16G16_UINT = 81,
+ VK_FORMAT_R16G16_SINT = 82,
+ VK_FORMAT_R16G16_SFLOAT = 83,
+ VK_FORMAT_R16G16B16_UNORM = 84,
+ VK_FORMAT_R16G16B16_SNORM = 85,
+ VK_FORMAT_R16G16B16_USCALED = 86,
+ VK_FORMAT_R16G16B16_SSCALED = 87,
+ VK_FORMAT_R16G16B16_UINT = 88,
+ VK_FORMAT_R16G16B16_SINT = 89,
+ VK_FORMAT_R16G16B16_SFLOAT = 90,
+ VK_FORMAT_R16G16B16A16_UNORM = 91,
+ VK_FORMAT_R16G16B16A16_SNORM = 92,
+ VK_FORMAT_R16G16B16A16_USCALED = 93,
+ VK_FORMAT_R16G16B16A16_SSCALED = 94,
+ VK_FORMAT_R16G16B16A16_UINT = 95,
+ VK_FORMAT_R16G16B16A16_SINT = 96,
+ VK_FORMAT_R16G16B16A16_SFLOAT = 97,
+ VK_FORMAT_R32_UINT = 98,
+ VK_FORMAT_R32_SINT = 99,
+ VK_FORMAT_R32_SFLOAT = 100,
+ VK_FORMAT_R32G32_UINT = 101,
+ VK_FORMAT_R32G32_SINT = 102,
+ VK_FORMAT_R32G32_SFLOAT = 103,
+ VK_FORMAT_R32G32B32_UINT = 104,
+ VK_FORMAT_R32G32B32_SINT = 105,
+ VK_FORMAT_R32G32B32_SFLOAT = 106,
+ VK_FORMAT_R32G32B32A32_UINT = 107,
+ VK_FORMAT_R32G32B32A32_SINT = 108,
+ VK_FORMAT_R32G32B32A32_SFLOAT = 109,
+ VK_FORMAT_R64_UINT = 110,
+ VK_FORMAT_R64_SINT = 111,
+ VK_FORMAT_R64_SFLOAT = 112,
+ VK_FORMAT_R64G64_UINT = 113,
+ VK_FORMAT_R64G64_SINT = 114,
+ VK_FORMAT_R64G64_SFLOAT = 115,
+ VK_FORMAT_R64G64B64_UINT = 116,
+ VK_FORMAT_R64G64B64_SINT = 117,
+ VK_FORMAT_R64G64B64_SFLOAT = 118,
+ VK_FORMAT_R64G64B64A64_UINT = 119,
+ VK_FORMAT_R64G64B64A64_SINT = 120,
+ VK_FORMAT_R64G64B64A64_SFLOAT = 121,
+ VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122,
+ VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123,
+ VK_FORMAT_D16_UNORM = 124,
+ VK_FORMAT_X8_D24_UNORM_PACK32 = 125,
+ VK_FORMAT_D32_SFLOAT = 126,
+ VK_FORMAT_S8_UINT = 127,
+ VK_FORMAT_D16_UNORM_S8_UINT = 128,
+ VK_FORMAT_D24_UNORM_S8_UINT = 129,
+ VK_FORMAT_D32_SFLOAT_S8_UINT = 130,
+ VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131,
+ VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132,
+ VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133,
+ VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134,
+ VK_FORMAT_BC2_UNORM_BLOCK = 135,
+ VK_FORMAT_BC2_SRGB_BLOCK = 136,
+ VK_FORMAT_BC3_UNORM_BLOCK = 137,
+ VK_FORMAT_BC3_SRGB_BLOCK = 138,
+ VK_FORMAT_BC4_UNORM_BLOCK = 139,
+ VK_FORMAT_BC4_SNORM_BLOCK = 140,
+ VK_FORMAT_BC5_UNORM_BLOCK = 141,
+ VK_FORMAT_BC5_SNORM_BLOCK = 142,
+ VK_FORMAT_BC6H_UFLOAT_BLOCK = 143,
+ VK_FORMAT_BC6H_SFLOAT_BLOCK = 144,
+ VK_FORMAT_BC7_UNORM_BLOCK = 145,
+ VK_FORMAT_BC7_SRGB_BLOCK = 146,
+ VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147,
+ VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148,
+ VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149,
+ VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150,
+ VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151,
+ VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152,
+ VK_FORMAT_EAC_R11_UNORM_BLOCK = 153,
+ VK_FORMAT_EAC_R11_SNORM_BLOCK = 154,
+ VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155,
+ VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156,
+ VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157,
+ VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158,
+ VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159,
+ VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160,
+ VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161,
+ VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162,
+ VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163,
+ VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164,
+ VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165,
+ VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166,
+ VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167,
+ VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168,
+ VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169,
+ VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170,
+ VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171,
+ VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172,
+ VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173,
+ VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174,
+ VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175,
+ VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176,
+ VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177,
+ VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178,
+ VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179,
+ VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180,
+ VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181,
+ VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182,
+ VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183,
+ VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184,
+ VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000,
+ VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001,
+ VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002,
+ VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003,
+ VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004,
+ VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005,
+ VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006,
+ VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007,
+ VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008,
+ VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009,
+ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010,
+ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011,
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012,
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013,
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014,
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015,
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016,
+ VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017,
+ VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018,
+ VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019,
+ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020,
+ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021,
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022,
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023,
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024,
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025,
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026,
+ VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027,
+ VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028,
+ VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029,
+ VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030,
+ VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031,
+ VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032,
+ VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033,
+ VK_FORMAT_G8_B8R8_2PLANE_444_UNORM = 1000330000,
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001,
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002,
+ VK_FORMAT_G16_B16R16_2PLANE_444_UNORM = 1000330003,
+ VK_FORMAT_A4R4G4B4_UNORM_PACK16 = 1000340000,
+ VK_FORMAT_A4B4G4R4_UNORM_PACK16 = 1000340001,
+ VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK = 1000066000,
+ VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK = 1000066001,
+ VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK = 1000066002,
+ VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK = 1000066003,
+ VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK = 1000066004,
+ VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK = 1000066005,
+ VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK = 1000066006,
+ VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK = 1000066007,
+ VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK = 1000066008,
+ VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK = 1000066009,
+ VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK = 1000066010,
+ VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011,
+ VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012,
+ VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013,
+ VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000,
+ VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001,
+ VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002,
+ VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003,
+ VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004,
+ VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005,
+ VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006,
+ VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007,
+ VK_FORMAT_R16G16_S10_5_NV = 1000464000,
+ VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK,
+ VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK,
+ VK_FORMAT_G8B8G8R8_422_UNORM_KHR = VK_FORMAT_G8B8G8R8_422_UNORM,
+ VK_FORMAT_B8G8R8G8_422_UNORM_KHR = VK_FORMAT_B8G8R8G8_422_UNORM,
+ VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
+ VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
+ VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
+ VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
+ VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
+ VK_FORMAT_R10X6_UNORM_PACK16_KHR = VK_FORMAT_R10X6_UNORM_PACK16,
+ VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR = VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
+ VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR = VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
+ VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
+ VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
+ VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
+ VK_FORMAT_R12X4_UNORM_PACK16_KHR = VK_FORMAT_R12X4_UNORM_PACK16,
+ VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR = VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
+ VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR = VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
+ VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
+ VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
+ VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
+ VK_FORMAT_G16B16G16R16_422_UNORM_KHR = VK_FORMAT_G16B16G16R16_422_UNORM,
+ VK_FORMAT_B16G16R16G16_422_UNORM_KHR = VK_FORMAT_B16G16R16G16_422_UNORM,
+ VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
+ VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
+ VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
+ VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
+ VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
+ VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM,
+ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16,
+ VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16,
+ VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM,
+ VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = VK_FORMAT_A4R4G4B4_UNORM_PACK16,
+ VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = VK_FORMAT_A4B4G4R4_UNORM_PACK16,
+ VK_FORMAT_MAX_ENUM = 0x7FFFFFFF
+} VkFormat;
+
+typedef enum VkImageTiling {
+ VK_IMAGE_TILING_OPTIMAL = 0,
+ VK_IMAGE_TILING_LINEAR = 1,
+ VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT = 1000158000,
+ VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF
+} VkImageTiling;
+
+typedef enum VkImageType {
+ VK_IMAGE_TYPE_1D = 0,
+ VK_IMAGE_TYPE_2D = 1,
+ VK_IMAGE_TYPE_3D = 2,
+ VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkImageType;
+
+typedef enum VkPhysicalDeviceType {
+ VK_PHYSICAL_DEVICE_TYPE_OTHER = 0,
+ VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1,
+ VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2,
+ VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3,
+ VK_PHYSICAL_DEVICE_TYPE_CPU = 4,
+ VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkPhysicalDeviceType;
+
+typedef enum VkQueryType {
+ VK_QUERY_TYPE_OCCLUSION = 0,
+ VK_QUERY_TYPE_PIPELINE_STATISTICS = 1,
+ VK_QUERY_TYPE_TIMESTAMP = 2,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR = 1000023000,
+#endif
+ VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT = 1000028004,
+ VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR = 1000116000,
+ VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR = 1000150000,
+ VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR = 1000150001,
+ VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000,
+ VK_QUERY_TYPE_PERFORMANCE_QUERY_INTEL = 1000210000,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_QUERY_TYPE_VIDEO_ENCODE_BITSTREAM_BUFFER_RANGE_KHR = 1000299000,
+#endif
+ VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT = 1000328000,
+ VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT = 1000382000,
+ VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR = 1000386000,
+ VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR = 1000386001,
+ VK_QUERY_TYPE_MICROMAP_SERIALIZATION_SIZE_EXT = 1000396000,
+ VK_QUERY_TYPE_MICROMAP_COMPACTED_SIZE_EXT = 1000396001,
+ VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkQueryType;
+
+typedef enum VkSharingMode {
+ VK_SHARING_MODE_EXCLUSIVE = 0,
+ VK_SHARING_MODE_CONCURRENT = 1,
+ VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkSharingMode;
+
+typedef enum VkComponentSwizzle {
+ VK_COMPONENT_SWIZZLE_IDENTITY = 0,
+ VK_COMPONENT_SWIZZLE_ZERO = 1,
+ VK_COMPONENT_SWIZZLE_ONE = 2,
+ VK_COMPONENT_SWIZZLE_R = 3,
+ VK_COMPONENT_SWIZZLE_G = 4,
+ VK_COMPONENT_SWIZZLE_B = 5,
+ VK_COMPONENT_SWIZZLE_A = 6,
+ VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF
+} VkComponentSwizzle;
+
+typedef enum VkImageViewType {
+ VK_IMAGE_VIEW_TYPE_1D = 0,
+ VK_IMAGE_VIEW_TYPE_2D = 1,
+ VK_IMAGE_VIEW_TYPE_3D = 2,
+ VK_IMAGE_VIEW_TYPE_CUBE = 3,
+ VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4,
+ VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5,
+ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6,
+ VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkImageViewType;
+
+typedef enum VkBlendFactor {
+ VK_BLEND_FACTOR_ZERO = 0,
+ VK_BLEND_FACTOR_ONE = 1,
+ VK_BLEND_FACTOR_SRC_COLOR = 2,
+ VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3,
+ VK_BLEND_FACTOR_DST_COLOR = 4,
+ VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5,
+ VK_BLEND_FACTOR_SRC_ALPHA = 6,
+ VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7,
+ VK_BLEND_FACTOR_DST_ALPHA = 8,
+ VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9,
+ VK_BLEND_FACTOR_CONSTANT_COLOR = 10,
+ VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11,
+ VK_BLEND_FACTOR_CONSTANT_ALPHA = 12,
+ VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13,
+ VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14,
+ VK_BLEND_FACTOR_SRC1_COLOR = 15,
+ VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16,
+ VK_BLEND_FACTOR_SRC1_ALPHA = 17,
+ VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18,
+ VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF
+} VkBlendFactor;
+
+typedef enum VkBlendOp {
+ VK_BLEND_OP_ADD = 0,
+ VK_BLEND_OP_SUBTRACT = 1,
+ VK_BLEND_OP_REVERSE_SUBTRACT = 2,
+ VK_BLEND_OP_MIN = 3,
+ VK_BLEND_OP_MAX = 4,
+ VK_BLEND_OP_ZERO_EXT = 1000148000,
+ VK_BLEND_OP_SRC_EXT = 1000148001,
+ VK_BLEND_OP_DST_EXT = 1000148002,
+ VK_BLEND_OP_SRC_OVER_EXT = 1000148003,
+ VK_BLEND_OP_DST_OVER_EXT = 1000148004,
+ VK_BLEND_OP_SRC_IN_EXT = 1000148005,
+ VK_BLEND_OP_DST_IN_EXT = 1000148006,
+ VK_BLEND_OP_SRC_OUT_EXT = 1000148007,
+ VK_BLEND_OP_DST_OUT_EXT = 1000148008,
+ VK_BLEND_OP_SRC_ATOP_EXT = 1000148009,
+ VK_BLEND_OP_DST_ATOP_EXT = 1000148010,
+ VK_BLEND_OP_XOR_EXT = 1000148011,
+ VK_BLEND_OP_MULTIPLY_EXT = 1000148012,
+ VK_BLEND_OP_SCREEN_EXT = 1000148013,
+ VK_BLEND_OP_OVERLAY_EXT = 1000148014,
+ VK_BLEND_OP_DARKEN_EXT = 1000148015,
+ VK_BLEND_OP_LIGHTEN_EXT = 1000148016,
+ VK_BLEND_OP_COLORDODGE_EXT = 1000148017,
+ VK_BLEND_OP_COLORBURN_EXT = 1000148018,
+ VK_BLEND_OP_HARDLIGHT_EXT = 1000148019,
+ VK_BLEND_OP_SOFTLIGHT_EXT = 1000148020,
+ VK_BLEND_OP_DIFFERENCE_EXT = 1000148021,
+ VK_BLEND_OP_EXCLUSION_EXT = 1000148022,
+ VK_BLEND_OP_INVERT_EXT = 1000148023,
+ VK_BLEND_OP_INVERT_RGB_EXT = 1000148024,
+ VK_BLEND_OP_LINEARDODGE_EXT = 1000148025,
+ VK_BLEND_OP_LINEARBURN_EXT = 1000148026,
+ VK_BLEND_OP_VIVIDLIGHT_EXT = 1000148027,
+ VK_BLEND_OP_LINEARLIGHT_EXT = 1000148028,
+ VK_BLEND_OP_PINLIGHT_EXT = 1000148029,
+ VK_BLEND_OP_HARDMIX_EXT = 1000148030,
+ VK_BLEND_OP_HSL_HUE_EXT = 1000148031,
+ VK_BLEND_OP_HSL_SATURATION_EXT = 1000148032,
+ VK_BLEND_OP_HSL_COLOR_EXT = 1000148033,
+ VK_BLEND_OP_HSL_LUMINOSITY_EXT = 1000148034,
+ VK_BLEND_OP_PLUS_EXT = 1000148035,
+ VK_BLEND_OP_PLUS_CLAMPED_EXT = 1000148036,
+ VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT = 1000148037,
+ VK_BLEND_OP_PLUS_DARKER_EXT = 1000148038,
+ VK_BLEND_OP_MINUS_EXT = 1000148039,
+ VK_BLEND_OP_MINUS_CLAMPED_EXT = 1000148040,
+ VK_BLEND_OP_CONTRAST_EXT = 1000148041,
+ VK_BLEND_OP_INVERT_OVG_EXT = 1000148042,
+ VK_BLEND_OP_RED_EXT = 1000148043,
+ VK_BLEND_OP_GREEN_EXT = 1000148044,
+ VK_BLEND_OP_BLUE_EXT = 1000148045,
+ VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF
+} VkBlendOp;
+
+typedef enum VkCompareOp {
+ VK_COMPARE_OP_NEVER = 0,
+ VK_COMPARE_OP_LESS = 1,
+ VK_COMPARE_OP_EQUAL = 2,
+ VK_COMPARE_OP_LESS_OR_EQUAL = 3,
+ VK_COMPARE_OP_GREATER = 4,
+ VK_COMPARE_OP_NOT_EQUAL = 5,
+ VK_COMPARE_OP_GREATER_OR_EQUAL = 6,
+ VK_COMPARE_OP_ALWAYS = 7,
+ VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF
+} VkCompareOp;
+
+typedef enum VkDynamicState {
+ VK_DYNAMIC_STATE_VIEWPORT = 0,
+ VK_DYNAMIC_STATE_SCISSOR = 1,
+ VK_DYNAMIC_STATE_LINE_WIDTH = 2,
+ VK_DYNAMIC_STATE_DEPTH_BIAS = 3,
+ VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4,
+ VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5,
+ VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6,
+ VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7,
+ VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8,
+ VK_DYNAMIC_STATE_CULL_MODE = 1000267000,
+ VK_DYNAMIC_STATE_FRONT_FACE = 1000267001,
+ VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = 1000267002,
+ VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT = 1000267003,
+ VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT = 1000267004,
+ VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE = 1000267005,
+ VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE = 1000267006,
+ VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE = 1000267007,
+ VK_DYNAMIC_STATE_DEPTH_COMPARE_OP = 1000267008,
+ VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE = 1000267009,
+ VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE = 1000267010,
+ VK_DYNAMIC_STATE_STENCIL_OP = 1000267011,
+ VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE = 1000377001,
+ VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE = 1000377002,
+ VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004,
+ VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000,
+ VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000,
+ VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000,
+ VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR = 1000347000,
+ VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1000164004,
+ VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006,
+ VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001,
+ VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR = 1000226000,
+ VK_DYNAMIC_STATE_LINE_STIPPLE_EXT = 1000259000,
+ VK_DYNAMIC_STATE_VERTEX_INPUT_EXT = 1000352000,
+ VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT = 1000377000,
+ VK_DYNAMIC_STATE_LOGIC_OP_EXT = 1000377003,
+ VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT = 1000381000,
+ VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT = 1000455002,
+ VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT = 1000455003,
+ VK_DYNAMIC_STATE_POLYGON_MODE_EXT = 1000455004,
+ VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT = 1000455005,
+ VK_DYNAMIC_STATE_SAMPLE_MASK_EXT = 1000455006,
+ VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT = 1000455007,
+ VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT = 1000455008,
+ VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT = 1000455009,
+ VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT = 1000455010,
+ VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT = 1000455011,
+ VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT = 1000455012,
+ VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT = 1000455013,
+ VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT = 1000455014,
+ VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT = 1000455015,
+ VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT = 1000455016,
+ VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT = 1000455017,
+ VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT = 1000455018,
+ VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT = 1000455019,
+ VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT = 1000455020,
+ VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT = 1000455021,
+ VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT = 1000455022,
+ VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV = 1000455023,
+ VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV = 1000455024,
+ VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV = 1000455025,
+ VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV = 1000455026,
+ VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV = 1000455027,
+ VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV = 1000455028,
+ VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV = 1000455029,
+ VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV = 1000455030,
+ VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV = 1000455031,
+ VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV = 1000455032,
+ VK_DYNAMIC_STATE_CULL_MODE_EXT = VK_DYNAMIC_STATE_CULL_MODE,
+ VK_DYNAMIC_STATE_FRONT_FACE_EXT = VK_DYNAMIC_STATE_FRONT_FACE,
+ VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY,
+ VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT,
+ VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,
+ VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE,
+ VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE,
+ VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE,
+ VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP,
+ VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE,
+ VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE,
+ VK_DYNAMIC_STATE_STENCIL_OP_EXT = VK_DYNAMIC_STATE_STENCIL_OP,
+ VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE,
+ VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE,
+ VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE,
+ VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF
+} VkDynamicState;
+
+typedef enum VkFrontFace {
+ VK_FRONT_FACE_COUNTER_CLOCKWISE = 0,
+ VK_FRONT_FACE_CLOCKWISE = 1,
+ VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF
+} VkFrontFace;
+
+typedef enum VkVertexInputRate {
+ VK_VERTEX_INPUT_RATE_VERTEX = 0,
+ VK_VERTEX_INPUT_RATE_INSTANCE = 1,
+ VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF
+} VkVertexInputRate;
+
+typedef enum VkPrimitiveTopology {
+ VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0,
+ VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1,
+ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2,
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3,
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4,
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5,
+ VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6,
+ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7,
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8,
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9,
+ VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10,
+ VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF
+} VkPrimitiveTopology;
+
+typedef enum VkPolygonMode {
+ VK_POLYGON_MODE_FILL = 0,
+ VK_POLYGON_MODE_LINE = 1,
+ VK_POLYGON_MODE_POINT = 2,
+ VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000,
+ VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkPolygonMode;
+
+typedef enum VkStencilOp {
+ VK_STENCIL_OP_KEEP = 0,
+ VK_STENCIL_OP_ZERO = 1,
+ VK_STENCIL_OP_REPLACE = 2,
+ VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3,
+ VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4,
+ VK_STENCIL_OP_INVERT = 5,
+ VK_STENCIL_OP_INCREMENT_AND_WRAP = 6,
+ VK_STENCIL_OP_DECREMENT_AND_WRAP = 7,
+ VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF
+} VkStencilOp;
+
+typedef enum VkLogicOp {
+ VK_LOGIC_OP_CLEAR = 0,
+ VK_LOGIC_OP_AND = 1,
+ VK_LOGIC_OP_AND_REVERSE = 2,
+ VK_LOGIC_OP_COPY = 3,
+ VK_LOGIC_OP_AND_INVERTED = 4,
+ VK_LOGIC_OP_NO_OP = 5,
+ VK_LOGIC_OP_XOR = 6,
+ VK_LOGIC_OP_OR = 7,
+ VK_LOGIC_OP_NOR = 8,
+ VK_LOGIC_OP_EQUIVALENT = 9,
+ VK_LOGIC_OP_INVERT = 10,
+ VK_LOGIC_OP_OR_REVERSE = 11,
+ VK_LOGIC_OP_COPY_INVERTED = 12,
+ VK_LOGIC_OP_OR_INVERTED = 13,
+ VK_LOGIC_OP_NAND = 14,
+ VK_LOGIC_OP_SET = 15,
+ VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF
+} VkLogicOp;
+
+typedef enum VkBorderColor {
+ VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0,
+ VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1,
+ VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2,
+ VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3,
+ VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4,
+ VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5,
+ VK_BORDER_COLOR_FLOAT_CUSTOM_EXT = 1000287003,
+ VK_BORDER_COLOR_INT_CUSTOM_EXT = 1000287004,
+ VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF
+} VkBorderColor;
+
+typedef enum VkFilter {
+ VK_FILTER_NEAREST = 0,
+ VK_FILTER_LINEAR = 1,
+ VK_FILTER_CUBIC_EXT = 1000015000,
+ VK_FILTER_CUBIC_IMG = VK_FILTER_CUBIC_EXT,
+ VK_FILTER_MAX_ENUM = 0x7FFFFFFF
+} VkFilter;
+
+typedef enum VkSamplerAddressMode {
+ VK_SAMPLER_ADDRESS_MODE_REPEAT = 0,
+ VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1,
+ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2,
+ VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3,
+ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4,
+ VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE_KHR = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE,
+ VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkSamplerAddressMode;
+
+typedef enum VkSamplerMipmapMode {
+ VK_SAMPLER_MIPMAP_MODE_NEAREST = 0,
+ VK_SAMPLER_MIPMAP_MODE_LINEAR = 1,
+ VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkSamplerMipmapMode;
+
+typedef enum VkDescriptorType {
+ VK_DESCRIPTOR_TYPE_SAMPLER = 0,
+ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1,
+ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2,
+ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3,
+ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4,
+ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5,
+ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6,
+ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7,
+ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8,
+ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9,
+ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10,
+ VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK = 1000138000,
+ VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000,
+ VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000,
+ VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM = 1000440000,
+ VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM = 1000440001,
+ VK_DESCRIPTOR_TYPE_MUTABLE_EXT = 1000351000,
+ VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK,
+ VK_DESCRIPTOR_TYPE_MUTABLE_VALVE = VK_DESCRIPTOR_TYPE_MUTABLE_EXT,
+ VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorType;
+
+typedef enum VkAttachmentLoadOp {
+ VK_ATTACHMENT_LOAD_OP_LOAD = 0,
+ VK_ATTACHMENT_LOAD_OP_CLEAR = 1,
+ VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2,
+ VK_ATTACHMENT_LOAD_OP_NONE_EXT = 1000400000,
+ VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF
+} VkAttachmentLoadOp;
+
+typedef enum VkAttachmentStoreOp {
+ VK_ATTACHMENT_STORE_OP_STORE = 0,
+ VK_ATTACHMENT_STORE_OP_DONT_CARE = 1,
+ VK_ATTACHMENT_STORE_OP_NONE = 1000301000,
+ VK_ATTACHMENT_STORE_OP_NONE_KHR = VK_ATTACHMENT_STORE_OP_NONE,
+ VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE,
+ VK_ATTACHMENT_STORE_OP_NONE_EXT = VK_ATTACHMENT_STORE_OP_NONE,
+ VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF
+} VkAttachmentStoreOp;
+
+typedef enum VkPipelineBindPoint {
+ VK_PIPELINE_BIND_POINT_GRAPHICS = 0,
+ VK_PIPELINE_BIND_POINT_COMPUTE = 1,
+ VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR = 1000165000,
+ VK_PIPELINE_BIND_POINT_SUBPASS_SHADING_HUAWEI = 1000369003,
+ VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR,
+ VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineBindPoint;
+
+typedef enum VkCommandBufferLevel {
+ VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0,
+ VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1,
+ VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF
+} VkCommandBufferLevel;
+
+typedef enum VkIndexType {
+ VK_INDEX_TYPE_UINT16 = 0,
+ VK_INDEX_TYPE_UINT32 = 1,
+ VK_INDEX_TYPE_NONE_KHR = 1000165000,
+ VK_INDEX_TYPE_UINT8_EXT = 1000265000,
+ VK_INDEX_TYPE_NONE_NV = VK_INDEX_TYPE_NONE_KHR,
+ VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkIndexType;
+
+typedef enum VkSubpassContents {
+ VK_SUBPASS_CONTENTS_INLINE = 0,
+ VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1,
+ VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF
+} VkSubpassContents;
+
+typedef enum VkAccessFlagBits {
+ VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001,
+ VK_ACCESS_INDEX_READ_BIT = 0x00000002,
+ VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004,
+ VK_ACCESS_UNIFORM_READ_BIT = 0x00000008,
+ VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010,
+ VK_ACCESS_SHADER_READ_BIT = 0x00000020,
+ VK_ACCESS_SHADER_WRITE_BIT = 0x00000040,
+ VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080,
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100,
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200,
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400,
+ VK_ACCESS_TRANSFER_READ_BIT = 0x00000800,
+ VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000,
+ VK_ACCESS_HOST_READ_BIT = 0x00002000,
+ VK_ACCESS_HOST_WRITE_BIT = 0x00004000,
+ VK_ACCESS_MEMORY_READ_BIT = 0x00008000,
+ VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000,
+ VK_ACCESS_NONE = 0,
+ VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000,
+ VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000,
+ VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000,
+ VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000,
+ VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000,
+ VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000,
+ VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000,
+ VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000,
+ VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000,
+ VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000,
+ VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000,
+ VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR,
+ VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR,
+ VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
+ VK_ACCESS_NONE_KHR = VK_ACCESS_NONE,
+ VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkAccessFlagBits;
+typedef VkFlags VkAccessFlags;
+
+typedef enum VkImageAspectFlagBits {
+ VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001,
+ VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002,
+ VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004,
+ VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008,
+ VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010,
+ VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020,
+ VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040,
+ VK_IMAGE_ASPECT_NONE = 0,
+ VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080,
+ VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100,
+ VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200,
+ VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT = 0x00000400,
+ VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT,
+ VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT,
+ VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT,
+ VK_IMAGE_ASPECT_NONE_KHR = VK_IMAGE_ASPECT_NONE,
+ VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkImageAspectFlagBits;
+typedef VkFlags VkImageAspectFlags;
+
+typedef enum VkFormatFeatureFlagBits {
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001,
+ VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 0x00000002,
+ VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004,
+ VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008,
+ VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 0x00000010,
+ VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020,
+ VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 0x00000040,
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 0x00000080,
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100,
+ VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200,
+ VK_FORMAT_FEATURE_BLIT_SRC_BIT = 0x00000400,
+ VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000,
+ VK_FORMAT_FEATURE_TRANSFER_SRC_BIT = 0x00004000,
+ VK_FORMAT_FEATURE_TRANSFER_DST_BIT = 0x00008000,
+ VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000,
+ VK_FORMAT_FEATURE_DISJOINT_BIT = 0x00400000,
+ VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_FORMAT_FEATURE_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_FORMAT_FEATURE_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000,
+#endif
+ VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000,
+ VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000,
+ VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_FORMAT_FEATURE_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_FORMAT_FEATURE_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000,
+#endif
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT,
+ VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT,
+ VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_DST_BIT,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT,
+ VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT,
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT,
+ VK_FORMAT_FEATURE_DISJOINT_BIT_KHR = VK_FORMAT_FEATURE_DISJOINT_BIT,
+ VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT,
+ VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkFormatFeatureFlagBits;
+typedef VkFlags VkFormatFeatureFlags;
+
+typedef enum VkImageCreateFlagBits {
+ VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001,
+ VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002,
+ VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
+ VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008,
+ VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010,
+ VK_IMAGE_CREATE_ALIAS_BIT = 0x00000400,
+ VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT = 0x00000040,
+ VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT = 0x00000020,
+ VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT = 0x00000080,
+ VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 0x00000100,
+ VK_IMAGE_CREATE_PROTECTED_BIT = 0x00000800,
+ VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200,
+ VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000,
+ VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000,
+ VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000,
+ VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT = 0x00040000,
+ VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT = 0x00020000,
+ VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM = 0x00008000,
+ VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT,
+ VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT,
+ VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT,
+ VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT,
+ VK_IMAGE_CREATE_DISJOINT_BIT_KHR = VK_IMAGE_CREATE_DISJOINT_BIT,
+ VK_IMAGE_CREATE_ALIAS_BIT_KHR = VK_IMAGE_CREATE_ALIAS_BIT,
+ VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkImageCreateFlagBits;
+typedef VkFlags VkImageCreateFlags;
+
+typedef enum VkSampleCountFlagBits {
+ VK_SAMPLE_COUNT_1_BIT = 0x00000001,
+ VK_SAMPLE_COUNT_2_BIT = 0x00000002,
+ VK_SAMPLE_COUNT_4_BIT = 0x00000004,
+ VK_SAMPLE_COUNT_8_BIT = 0x00000008,
+ VK_SAMPLE_COUNT_16_BIT = 0x00000010,
+ VK_SAMPLE_COUNT_32_BIT = 0x00000020,
+ VK_SAMPLE_COUNT_64_BIT = 0x00000040,
+ VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSampleCountFlagBits;
+typedef VkFlags VkSampleCountFlags;
+
+typedef enum VkImageUsageFlagBits {
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001,
+ VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002,
+ VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004,
+ VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008,
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010,
+ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020,
+ VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040,
+ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR = 0x00000400,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR = 0x00000800,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR = 0x00001000,
+#endif
+ VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200,
+ VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00000100,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR = 0x00002000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR = 0x00004000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR = 0x00008000,
+#endif
+ VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x00080000,
+ VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI = 0x00040000,
+ VK_IMAGE_USAGE_SAMPLE_WEIGHT_BIT_QCOM = 0x00100000,
+ VK_IMAGE_USAGE_SAMPLE_BLOCK_MATCH_BIT_QCOM = 0x00200000,
+ VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR,
+ VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkImageUsageFlagBits;
+typedef VkFlags VkImageUsageFlags;
+
+typedef enum VkInstanceCreateFlagBits {
+ VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR = 0x00000001,
+ VK_INSTANCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkInstanceCreateFlagBits;
+typedef VkFlags VkInstanceCreateFlags;
+
+typedef enum VkMemoryHeapFlagBits {
+ VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001,
+ VK_MEMORY_HEAP_MULTI_INSTANCE_BIT = 0x00000002,
+ VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHR = VK_MEMORY_HEAP_MULTI_INSTANCE_BIT,
+ VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkMemoryHeapFlagBits;
+typedef VkFlags VkMemoryHeapFlags;
+
+typedef enum VkMemoryPropertyFlagBits {
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001,
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002,
+ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004,
+ VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008,
+ VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010,
+ VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020,
+ VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD = 0x00000040,
+ VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD = 0x00000080,
+ VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV = 0x00000100,
+ VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkMemoryPropertyFlagBits;
+typedef VkFlags VkMemoryPropertyFlags;
+
+typedef enum VkQueueFlagBits {
+ VK_QUEUE_GRAPHICS_BIT = 0x00000001,
+ VK_QUEUE_COMPUTE_BIT = 0x00000002,
+ VK_QUEUE_TRANSFER_BIT = 0x00000004,
+ VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008,
+ VK_QUEUE_PROTECTED_BIT = 0x00000010,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_QUEUE_VIDEO_DECODE_BIT_KHR = 0x00000020,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_QUEUE_VIDEO_ENCODE_BIT_KHR = 0x00000040,
+#endif
+ VK_QUEUE_OPTICAL_FLOW_BIT_NV = 0x00000100,
+ VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkQueueFlagBits;
+typedef VkFlags VkQueueFlags;
+typedef VkFlags VkDeviceCreateFlags;
+
+typedef enum VkDeviceQueueCreateFlagBits {
+ VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 0x00000001,
+ VK_DEVICE_QUEUE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkDeviceQueueCreateFlagBits;
+typedef VkFlags VkDeviceQueueCreateFlags;
+
+typedef enum VkPipelineStageFlagBits {
+ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001,
+ VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002,
+ VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004,
+ VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008,
+ VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010,
+ VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020,
+ VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040,
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080,
+ VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100,
+ VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400,
+ VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800,
+ VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000,
+ VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000,
+ VK_PIPELINE_STAGE_HOST_BIT = 0x00004000,
+ VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000,
+ VK_PIPELINE_STAGE_NONE = 0,
+ VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000,
+ VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000,
+ VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000,
+ VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR = 0x00200000,
+ VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000,
+ VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000,
+ VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = 0x00020000,
+ VK_PIPELINE_STAGE_TASK_SHADER_BIT_EXT = 0x00080000,
+ VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT = 0x00100000,
+ VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR,
+ VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
+ VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
+ VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = VK_PIPELINE_STAGE_TASK_SHADER_BIT_EXT,
+ VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
+ VK_PIPELINE_STAGE_NONE_KHR = VK_PIPELINE_STAGE_NONE,
+ VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineStageFlagBits;
+typedef VkFlags VkPipelineStageFlags;
+typedef VkFlags VkMemoryMapFlags;
+
+typedef enum VkSparseMemoryBindFlagBits {
+ VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001,
+ VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSparseMemoryBindFlagBits;
+typedef VkFlags VkSparseMemoryBindFlags;
+
+typedef enum VkSparseImageFormatFlagBits {
+ VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001,
+ VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 0x00000002,
+ VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 0x00000004,
+ VK_SPARSE_IMAGE_FORMAT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSparseImageFormatFlagBits;
+typedef VkFlags VkSparseImageFormatFlags;
+
+typedef enum VkFenceCreateFlagBits {
+ VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001,
+ VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkFenceCreateFlagBits;
+typedef VkFlags VkFenceCreateFlags;
+typedef VkFlags VkSemaphoreCreateFlags;
+
+typedef enum VkEventCreateFlagBits {
+ VK_EVENT_CREATE_DEVICE_ONLY_BIT = 0x00000001,
+ VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = VK_EVENT_CREATE_DEVICE_ONLY_BIT,
+ VK_EVENT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkEventCreateFlagBits;
+typedef VkFlags VkEventCreateFlags;
+
+typedef enum VkQueryPipelineStatisticFlagBits {
+ VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 0x00000001,
+ VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT = 0x00000002,
+ VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT = 0x00000004,
+ VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT = 0x00000008,
+ VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT = 0x00000010,
+ VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT = 0x00000020,
+ VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT = 0x00000040,
+ VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 0x00000080,
+ VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 0x00000100,
+ VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 0x00000200,
+ VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 0x00000400,
+ VK_QUERY_PIPELINE_STATISTIC_TASK_SHADER_INVOCATIONS_BIT_EXT = 0x00000800,
+ VK_QUERY_PIPELINE_STATISTIC_MESH_SHADER_INVOCATIONS_BIT_EXT = 0x00001000,
+ VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkQueryPipelineStatisticFlagBits;
+typedef VkFlags VkQueryPipelineStatisticFlags;
+typedef VkFlags VkQueryPoolCreateFlags;
+
+typedef enum VkQueryResultFlagBits {
+ VK_QUERY_RESULT_64_BIT = 0x00000001,
+ VK_QUERY_RESULT_WAIT_BIT = 0x00000002,
+ VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 0x00000004,
+ VK_QUERY_RESULT_PARTIAL_BIT = 0x00000008,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_QUERY_RESULT_WITH_STATUS_BIT_KHR = 0x00000010,
+#endif
+ VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkQueryResultFlagBits;
+typedef VkFlags VkQueryResultFlags;
+
+typedef enum VkBufferCreateFlagBits {
+ VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 0x00000001,
+ VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002,
+ VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
+ VK_BUFFER_CREATE_PROTECTED_BIT = 0x00000008,
+ VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000010,
+ VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
+ VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
+ VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkBufferCreateFlagBits;
+typedef VkFlags VkBufferCreateFlags;
+
+typedef enum VkBufferUsageFlagBits {
+ VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 0x00000001,
+ VK_BUFFER_USAGE_TRANSFER_DST_BIT = 0x00000002,
+ VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004,
+ VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 0x00000008,
+ VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 0x00000010,
+ VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020,
+ VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040,
+ VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080,
+ VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100,
+ VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT = 0x00020000,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR = 0x00002000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR = 0x00004000,
+#endif
+ VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800,
+ VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000,
+ VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200,
+ VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR = 0x00080000,
+ VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR = 0x00100000,
+ VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR = 0x00000400,
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR = 0x00008000,
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+ VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR = 0x00010000,
+#endif
+ VK_BUFFER_USAGE_MICROMAP_BUILD_INPUT_READ_ONLY_BIT_EXT = 0x00800000,
+ VK_BUFFER_USAGE_MICROMAP_STORAGE_BIT_EXT = 0x01000000,
+ VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR,
+ VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+ VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+ VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkBufferUsageFlagBits;
+typedef VkFlags VkBufferUsageFlags;
+typedef VkFlags VkBufferViewCreateFlags;
+
+typedef enum VkImageViewCreateFlagBits {
+ VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT = 0x00000001,
+ VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DEFERRED_BIT_EXT = 0x00000002,
+ VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkImageViewCreateFlagBits;
+typedef VkFlags VkImageViewCreateFlags;
+typedef VkFlags VkShaderModuleCreateFlags;
+
+typedef enum VkPipelineCacheCreateFlagBits {
+ VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001,
+ VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT,
+ VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineCacheCreateFlagBits;
+typedef VkFlags VkPipelineCacheCreateFlags;
+
+typedef enum VkColorComponentFlagBits {
+ VK_COLOR_COMPONENT_R_BIT = 0x00000001,
+ VK_COLOR_COMPONENT_G_BIT = 0x00000002,
+ VK_COLOR_COMPONENT_B_BIT = 0x00000004,
+ VK_COLOR_COMPONENT_A_BIT = 0x00000008,
+ VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkColorComponentFlagBits;
+typedef VkFlags VkColorComponentFlags;
+
+typedef enum VkPipelineCreateFlagBits {
+ VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001,
+ VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002,
+ VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004,
+ VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008,
+ VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 0x00000010,
+ VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT = 0x00000100,
+ VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT = 0x00000200,
+ VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000,
+ VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000,
+ VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000,
+ VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000,
+ VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000,
+ VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_BIT_KHR = 0x00020000,
+ VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR = 0x00001000,
+ VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR = 0x00002000,
+ VK_PIPELINE_CREATE_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR = 0x00080000,
+ VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV = 0x00000020,
+ VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR = 0x00000040,
+ VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080,
+ VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV = 0x00040000,
+ VK_PIPELINE_CREATE_LIBRARY_BIT_KHR = 0x00000800,
+ VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT = 0x00800000,
+ VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT = 0x00000400,
+ VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000,
+ VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x02000000,
+ VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x04000000,
+ VK_PIPELINE_CREATE_RAY_TRACING_OPACITY_MICROMAP_BIT_EXT = 0x01000000,
+ VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT = 0x08000000,
+ VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT = 0x40000000,
+ VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT,
+ VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR,
+ VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT,
+ VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT,
+ VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE,
+ VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT,
+ VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT,
+ VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineCreateFlagBits;
+typedef VkFlags VkPipelineCreateFlags;
+
+typedef enum VkPipelineShaderStageCreateFlagBits {
+ VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT = 0x00000001,
+ VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT = 0x00000002,
+ VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT,
+ VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT,
+ VK_PIPELINE_SHADER_STAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineShaderStageCreateFlagBits;
+typedef VkFlags VkPipelineShaderStageCreateFlags;
+
+typedef enum VkShaderStageFlagBits {
+ VK_SHADER_STAGE_VERTEX_BIT = 0x00000001,
+ VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002,
+ VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004,
+ VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008,
+ VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010,
+ VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020,
+ VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F,
+ VK_SHADER_STAGE_ALL = 0x7FFFFFFF,
+ VK_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100,
+ VK_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200,
+ VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400,
+ VK_SHADER_STAGE_MISS_BIT_KHR = 0x00000800,
+ VK_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000,
+ VK_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000,
+ VK_SHADER_STAGE_TASK_BIT_EXT = 0x00000040,
+ VK_SHADER_STAGE_MESH_BIT_EXT = 0x00000080,
+ VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI = 0x00004000,
+ VK_SHADER_STAGE_RAYGEN_BIT_NV = VK_SHADER_STAGE_RAYGEN_BIT_KHR,
+ VK_SHADER_STAGE_ANY_HIT_BIT_NV = VK_SHADER_STAGE_ANY_HIT_BIT_KHR,
+ VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,
+ VK_SHADER_STAGE_MISS_BIT_NV = VK_SHADER_STAGE_MISS_BIT_KHR,
+ VK_SHADER_STAGE_INTERSECTION_BIT_NV = VK_SHADER_STAGE_INTERSECTION_BIT_KHR,
+ VK_SHADER_STAGE_CALLABLE_BIT_NV = VK_SHADER_STAGE_CALLABLE_BIT_KHR,
+ VK_SHADER_STAGE_TASK_BIT_NV = VK_SHADER_STAGE_TASK_BIT_EXT,
+ VK_SHADER_STAGE_MESH_BIT_NV = VK_SHADER_STAGE_MESH_BIT_EXT,
+ VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkShaderStageFlagBits;
+
+typedef enum VkCullModeFlagBits {
+ VK_CULL_MODE_NONE = 0,
+ VK_CULL_MODE_FRONT_BIT = 0x00000001,
+ VK_CULL_MODE_BACK_BIT = 0x00000002,
+ VK_CULL_MODE_FRONT_AND_BACK = 0x00000003,
+ VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkCullModeFlagBits;
+typedef VkFlags VkCullModeFlags;
+typedef VkFlags VkPipelineVertexInputStateCreateFlags;
+typedef VkFlags VkPipelineInputAssemblyStateCreateFlags;
+typedef VkFlags VkPipelineTessellationStateCreateFlags;
+typedef VkFlags VkPipelineViewportStateCreateFlags;
+typedef VkFlags VkPipelineRasterizationStateCreateFlags;
+typedef VkFlags VkPipelineMultisampleStateCreateFlags;
+
+typedef enum VkPipelineDepthStencilStateCreateFlagBits {
+ VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT = 0x00000001,
+ VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT = 0x00000002,
+ VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT,
+ VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT,
+ VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineDepthStencilStateCreateFlagBits;
+typedef VkFlags VkPipelineDepthStencilStateCreateFlags;
+
+typedef enum VkPipelineColorBlendStateCreateFlagBits {
+ VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT = 0x00000001,
+ VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM = VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT,
+ VK_PIPELINE_COLOR_BLEND_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineColorBlendStateCreateFlagBits;
+typedef VkFlags VkPipelineColorBlendStateCreateFlags;
+typedef VkFlags VkPipelineDynamicStateCreateFlags;
+
+typedef enum VkPipelineLayoutCreateFlagBits {
+ VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT = 0x00000002,
+ VK_PIPELINE_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineLayoutCreateFlagBits;
+typedef VkFlags VkPipelineLayoutCreateFlags;
+typedef VkFlags VkShaderStageFlags;
+
+typedef enum VkSamplerCreateFlagBits {
+ VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT = 0x00000001,
+ VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT = 0x00000002,
+ VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT = 0x00000004,
+ VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM = 0x00000010,
+ VK_SAMPLER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSamplerCreateFlagBits;
+typedef VkFlags VkSamplerCreateFlags;
+
+typedef enum VkDescriptorPoolCreateFlagBits {
+ VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001,
+ VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT = 0x00000002,
+ VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT = 0x00000004,
+ VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
+ VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE = VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT,
+ VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorPoolCreateFlagBits;
+typedef VkFlags VkDescriptorPoolCreateFlags;
+typedef VkFlags VkDescriptorPoolResetFlags;
+
+typedef enum VkDescriptorSetLayoutCreateFlagBits {
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT = 0x00000002,
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001,
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT = 0x00000004,
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE = VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT,
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorSetLayoutCreateFlagBits;
+typedef VkFlags VkDescriptorSetLayoutCreateFlags;
+
+typedef enum VkAttachmentDescriptionFlagBits {
+ VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001,
+ VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkAttachmentDescriptionFlagBits;
+typedef VkFlags VkAttachmentDescriptionFlags;
+
+typedef enum VkDependencyFlagBits {
+ VK_DEPENDENCY_BY_REGION_BIT = 0x00000001,
+ VK_DEPENDENCY_DEVICE_GROUP_BIT = 0x00000004,
+ VK_DEPENDENCY_VIEW_LOCAL_BIT = 0x00000002,
+ VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT = 0x00000008,
+ VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR = VK_DEPENDENCY_VIEW_LOCAL_BIT,
+ VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR = VK_DEPENDENCY_DEVICE_GROUP_BIT,
+ VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkDependencyFlagBits;
+typedef VkFlags VkDependencyFlags;
+
+typedef enum VkFramebufferCreateFlagBits {
+ VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 0x00000001,
+ VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT,
+ VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkFramebufferCreateFlagBits;
+typedef VkFlags VkFramebufferCreateFlags;
+
+typedef enum VkRenderPassCreateFlagBits {
+ VK_RENDER_PASS_CREATE_TRANSFORM_BIT_QCOM = 0x00000002,
+ VK_RENDER_PASS_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkRenderPassCreateFlagBits;
+typedef VkFlags VkRenderPassCreateFlags;
+
+typedef enum VkSubpassDescriptionFlagBits {
+ VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX = 0x00000001,
+ VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002,
+ VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM = 0x00000004,
+ VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM = 0x00000008,
+ VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT = 0x00000010,
+ VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT = 0x00000020,
+ VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT = 0x00000040,
+ VK_SUBPASS_DESCRIPTION_ENABLE_LEGACY_DITHERING_BIT_EXT = 0x00000080,
+ VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT,
+ VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT,
+ VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT,
+ VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSubpassDescriptionFlagBits;
+typedef VkFlags VkSubpassDescriptionFlags;
+
+typedef enum VkCommandPoolCreateFlagBits {
+ VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001,
+ VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002,
+ VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 0x00000004,
+ VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkCommandPoolCreateFlagBits;
+typedef VkFlags VkCommandPoolCreateFlags;
+
+typedef enum VkCommandPoolResetFlagBits {
+ VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001,
+ VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkCommandPoolResetFlagBits;
+typedef VkFlags VkCommandPoolResetFlags;
+
+typedef enum VkCommandBufferUsageFlagBits {
+ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001,
+ VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 0x00000002,
+ VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 0x00000004,
+ VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkCommandBufferUsageFlagBits;
+typedef VkFlags VkCommandBufferUsageFlags;
+
+typedef enum VkQueryControlFlagBits {
+ VK_QUERY_CONTROL_PRECISE_BIT = 0x00000001,
+ VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkQueryControlFlagBits;
+typedef VkFlags VkQueryControlFlags;
+
+typedef enum VkCommandBufferResetFlagBits {
+ VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001,
+ VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkCommandBufferResetFlagBits;
+typedef VkFlags VkCommandBufferResetFlags;
+
+typedef enum VkStencilFaceFlagBits {
+ VK_STENCIL_FACE_FRONT_BIT = 0x00000001,
+ VK_STENCIL_FACE_BACK_BIT = 0x00000002,
+ VK_STENCIL_FACE_FRONT_AND_BACK = 0x00000003,
+ VK_STENCIL_FRONT_AND_BACK = VK_STENCIL_FACE_FRONT_AND_BACK,
+ VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkStencilFaceFlagBits;
+typedef VkFlags VkStencilFaceFlags;
+typedef struct VkExtent2D {
+ uint32_t width;
+ uint32_t height;
+} VkExtent2D;
+
+typedef struct VkExtent3D {
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth;
+} VkExtent3D;
+
+typedef struct VkOffset2D {
+ int32_t x;
+ int32_t y;
+} VkOffset2D;
+
+typedef struct VkOffset3D {
+ int32_t x;
+ int32_t y;
+ int32_t z;
+} VkOffset3D;
+
+typedef struct VkRect2D {
+ VkOffset2D offset;
+ VkExtent2D extent;
+} VkRect2D;
+
+typedef struct VkBaseInStructure {
+ VkStructureType sType;
+ const struct VkBaseInStructure* pNext;
+} VkBaseInStructure;
+
+typedef struct VkBaseOutStructure {
+ VkStructureType sType;
+ struct VkBaseOutStructure* pNext;
+} VkBaseOutStructure;
+
+typedef struct VkBufferMemoryBarrier {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccessFlags srcAccessMask;
+ VkAccessFlags dstAccessMask;
+ uint32_t srcQueueFamilyIndex;
+ uint32_t dstQueueFamilyIndex;
+ VkBuffer buffer;
+ VkDeviceSize offset;
+ VkDeviceSize size;
+} VkBufferMemoryBarrier;
+
+typedef struct VkDispatchIndirectCommand {
+ uint32_t x;
+ uint32_t y;
+ uint32_t z;
+} VkDispatchIndirectCommand;
+
+typedef struct VkDrawIndexedIndirectCommand {
+ uint32_t indexCount;
+ uint32_t instanceCount;
+ uint32_t firstIndex;
+ int32_t vertexOffset;
+ uint32_t firstInstance;
+} VkDrawIndexedIndirectCommand;
+
+typedef struct VkDrawIndirectCommand {
+ uint32_t vertexCount;
+ uint32_t instanceCount;
+ uint32_t firstVertex;
+ uint32_t firstInstance;
+} VkDrawIndirectCommand;
+
+typedef struct VkImageSubresourceRange {
+ VkImageAspectFlags aspectMask;
+ uint32_t baseMipLevel;
+ uint32_t levelCount;
+ uint32_t baseArrayLayer;
+ uint32_t layerCount;
+} VkImageSubresourceRange;
+
+typedef struct VkImageMemoryBarrier {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccessFlags srcAccessMask;
+ VkAccessFlags dstAccessMask;
+ VkImageLayout oldLayout;
+ VkImageLayout newLayout;
+ uint32_t srcQueueFamilyIndex;
+ uint32_t dstQueueFamilyIndex;
+ VkImage image;
+ VkImageSubresourceRange subresourceRange;
+} VkImageMemoryBarrier;
+
+typedef struct VkMemoryBarrier {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccessFlags srcAccessMask;
+ VkAccessFlags dstAccessMask;
+} VkMemoryBarrier;
+
+typedef struct VkPipelineCacheHeaderVersionOne {
+ uint32_t headerSize;
+ VkPipelineCacheHeaderVersion headerVersion;
+ uint32_t vendorID;
+ uint32_t deviceID;
+ uint8_t pipelineCacheUUID[VK_UUID_SIZE];
+} VkPipelineCacheHeaderVersionOne;
+
+typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)(
+ void* pUserData,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope allocationScope);
+
+typedef void (VKAPI_PTR *PFN_vkFreeFunction)(
+ void* pUserData,
+ void* pMemory);
+
+typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)(
+ void* pUserData,
+ size_t size,
+ VkInternalAllocationType allocationType,
+ VkSystemAllocationScope allocationScope);
+
+typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)(
+ void* pUserData,
+ size_t size,
+ VkInternalAllocationType allocationType,
+ VkSystemAllocationScope allocationScope);
+
+typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)(
+ void* pUserData,
+ void* pOriginal,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope allocationScope);
+
+typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void);
+typedef struct VkAllocationCallbacks {
+ void* pUserData;
+ PFN_vkAllocationFunction pfnAllocation;
+ PFN_vkReallocationFunction pfnReallocation;
+ PFN_vkFreeFunction pfnFree;
+ PFN_vkInternalAllocationNotification pfnInternalAllocation;
+ PFN_vkInternalFreeNotification pfnInternalFree;
+} VkAllocationCallbacks;
+
+typedef struct VkApplicationInfo {
+ VkStructureType sType;
+ const void* pNext;
+ const char* pApplicationName;
+ uint32_t applicationVersion;
+ const char* pEngineName;
+ uint32_t engineVersion;
+ uint32_t apiVersion;
+} VkApplicationInfo;
+
+typedef struct VkFormatProperties {
+ VkFormatFeatureFlags linearTilingFeatures;
+ VkFormatFeatureFlags optimalTilingFeatures;
+ VkFormatFeatureFlags bufferFeatures;
+} VkFormatProperties;
+
+typedef struct VkImageFormatProperties {
+ VkExtent3D maxExtent;
+ uint32_t maxMipLevels;
+ uint32_t maxArrayLayers;
+ VkSampleCountFlags sampleCounts;
+ VkDeviceSize maxResourceSize;
+} VkImageFormatProperties;
+
+typedef struct VkInstanceCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkInstanceCreateFlags flags;
+ const VkApplicationInfo* pApplicationInfo;
+ uint32_t enabledLayerCount;
+ const char* const* ppEnabledLayerNames;
+ uint32_t enabledExtensionCount;
+ const char* const* ppEnabledExtensionNames;
+} VkInstanceCreateInfo;
+
+typedef struct VkMemoryHeap {
+ VkDeviceSize size;
+ VkMemoryHeapFlags flags;
+} VkMemoryHeap;
+
+typedef struct VkMemoryType {
+ VkMemoryPropertyFlags propertyFlags;
+ uint32_t heapIndex;
+} VkMemoryType;
+
+typedef struct VkPhysicalDeviceFeatures {
+ VkBool32 robustBufferAccess;
+ VkBool32 fullDrawIndexUint32;
+ VkBool32 imageCubeArray;
+ VkBool32 independentBlend;
+ VkBool32 geometryShader;
+ VkBool32 tessellationShader;
+ VkBool32 sampleRateShading;
+ VkBool32 dualSrcBlend;
+ VkBool32 logicOp;
+ VkBool32 multiDrawIndirect;
+ VkBool32 drawIndirectFirstInstance;
+ VkBool32 depthClamp;
+ VkBool32 depthBiasClamp;
+ VkBool32 fillModeNonSolid;
+ VkBool32 depthBounds;
+ VkBool32 wideLines;
+ VkBool32 largePoints;
+ VkBool32 alphaToOne;
+ VkBool32 multiViewport;
+ VkBool32 samplerAnisotropy;
+ VkBool32 textureCompressionETC2;
+ VkBool32 textureCompressionASTC_LDR;
+ VkBool32 textureCompressionBC;
+ VkBool32 occlusionQueryPrecise;
+ VkBool32 pipelineStatisticsQuery;
+ VkBool32 vertexPipelineStoresAndAtomics;
+ VkBool32 fragmentStoresAndAtomics;
+ VkBool32 shaderTessellationAndGeometryPointSize;
+ VkBool32 shaderImageGatherExtended;
+ VkBool32 shaderStorageImageExtendedFormats;
+ VkBool32 shaderStorageImageMultisample;
+ VkBool32 shaderStorageImageReadWithoutFormat;
+ VkBool32 shaderStorageImageWriteWithoutFormat;
+ VkBool32 shaderUniformBufferArrayDynamicIndexing;
+ VkBool32 shaderSampledImageArrayDynamicIndexing;
+ VkBool32 shaderStorageBufferArrayDynamicIndexing;
+ VkBool32 shaderStorageImageArrayDynamicIndexing;
+ VkBool32 shaderClipDistance;
+ VkBool32 shaderCullDistance;
+ VkBool32 shaderFloat64;
+ VkBool32 shaderInt64;
+ VkBool32 shaderInt16;
+ VkBool32 shaderResourceResidency;
+ VkBool32 shaderResourceMinLod;
+ VkBool32 sparseBinding;
+ VkBool32 sparseResidencyBuffer;
+ VkBool32 sparseResidencyImage2D;
+ VkBool32 sparseResidencyImage3D;
+ VkBool32 sparseResidency2Samples;
+ VkBool32 sparseResidency4Samples;
+ VkBool32 sparseResidency8Samples;
+ VkBool32 sparseResidency16Samples;
+ VkBool32 sparseResidencyAliased;
+ VkBool32 variableMultisampleRate;
+ VkBool32 inheritedQueries;
+} VkPhysicalDeviceFeatures;
+
+typedef struct VkPhysicalDeviceLimits {
+ uint32_t maxImageDimension1D;
+ uint32_t maxImageDimension2D;
+ uint32_t maxImageDimension3D;
+ uint32_t maxImageDimensionCube;
+ uint32_t maxImageArrayLayers;
+ uint32_t maxTexelBufferElements;
+ uint32_t maxUniformBufferRange;
+ uint32_t maxStorageBufferRange;
+ uint32_t maxPushConstantsSize;
+ uint32_t maxMemoryAllocationCount;
+ uint32_t maxSamplerAllocationCount;
+ VkDeviceSize bufferImageGranularity;
+ VkDeviceSize sparseAddressSpaceSize;
+ uint32_t maxBoundDescriptorSets;
+ uint32_t maxPerStageDescriptorSamplers;
+ uint32_t maxPerStageDescriptorUniformBuffers;
+ uint32_t maxPerStageDescriptorStorageBuffers;
+ uint32_t maxPerStageDescriptorSampledImages;
+ uint32_t maxPerStageDescriptorStorageImages;
+ uint32_t maxPerStageDescriptorInputAttachments;
+ uint32_t maxPerStageResources;
+ uint32_t maxDescriptorSetSamplers;
+ uint32_t maxDescriptorSetUniformBuffers;
+ uint32_t maxDescriptorSetUniformBuffersDynamic;
+ uint32_t maxDescriptorSetStorageBuffers;
+ uint32_t maxDescriptorSetStorageBuffersDynamic;
+ uint32_t maxDescriptorSetSampledImages;
+ uint32_t maxDescriptorSetStorageImages;
+ uint32_t maxDescriptorSetInputAttachments;
+ uint32_t maxVertexInputAttributes;
+ uint32_t maxVertexInputBindings;
+ uint32_t maxVertexInputAttributeOffset;
+ uint32_t maxVertexInputBindingStride;
+ uint32_t maxVertexOutputComponents;
+ uint32_t maxTessellationGenerationLevel;
+ uint32_t maxTessellationPatchSize;
+ uint32_t maxTessellationControlPerVertexInputComponents;
+ uint32_t maxTessellationControlPerVertexOutputComponents;
+ uint32_t maxTessellationControlPerPatchOutputComponents;
+ uint32_t maxTessellationControlTotalOutputComponents;
+ uint32_t maxTessellationEvaluationInputComponents;
+ uint32_t maxTessellationEvaluationOutputComponents;
+ uint32_t maxGeometryShaderInvocations;
+ uint32_t maxGeometryInputComponents;
+ uint32_t maxGeometryOutputComponents;
+ uint32_t maxGeometryOutputVertices;
+ uint32_t maxGeometryTotalOutputComponents;
+ uint32_t maxFragmentInputComponents;
+ uint32_t maxFragmentOutputAttachments;
+ uint32_t maxFragmentDualSrcAttachments;
+ uint32_t maxFragmentCombinedOutputResources;
+ uint32_t maxComputeSharedMemorySize;
+ uint32_t maxComputeWorkGroupCount[3];
+ uint32_t maxComputeWorkGroupInvocations;
+ uint32_t maxComputeWorkGroupSize[3];
+ uint32_t subPixelPrecisionBits;
+ uint32_t subTexelPrecisionBits;
+ uint32_t mipmapPrecisionBits;
+ uint32_t maxDrawIndexedIndexValue;
+ uint32_t maxDrawIndirectCount;
+ float maxSamplerLodBias;
+ float maxSamplerAnisotropy;
+ uint32_t maxViewports;
+ uint32_t maxViewportDimensions[2];
+ float viewportBoundsRange[2];
+ uint32_t viewportSubPixelBits;
+ size_t minMemoryMapAlignment;
+ VkDeviceSize minTexelBufferOffsetAlignment;
+ VkDeviceSize minUniformBufferOffsetAlignment;
+ VkDeviceSize minStorageBufferOffsetAlignment;
+ int32_t minTexelOffset;
+ uint32_t maxTexelOffset;
+ int32_t minTexelGatherOffset;
+ uint32_t maxTexelGatherOffset;
+ float minInterpolationOffset;
+ float maxInterpolationOffset;
+ uint32_t subPixelInterpolationOffsetBits;
+ uint32_t maxFramebufferWidth;
+ uint32_t maxFramebufferHeight;
+ uint32_t maxFramebufferLayers;
+ VkSampleCountFlags framebufferColorSampleCounts;
+ VkSampleCountFlags framebufferDepthSampleCounts;
+ VkSampleCountFlags framebufferStencilSampleCounts;
+ VkSampleCountFlags framebufferNoAttachmentsSampleCounts;
+ uint32_t maxColorAttachments;
+ VkSampleCountFlags sampledImageColorSampleCounts;
+ VkSampleCountFlags sampledImageIntegerSampleCounts;
+ VkSampleCountFlags sampledImageDepthSampleCounts;
+ VkSampleCountFlags sampledImageStencilSampleCounts;
+ VkSampleCountFlags storageImageSampleCounts;
+ uint32_t maxSampleMaskWords;
+ VkBool32 timestampComputeAndGraphics;
+ float timestampPeriod;
+ uint32_t maxClipDistances;
+ uint32_t maxCullDistances;
+ uint32_t maxCombinedClipAndCullDistances;
+ uint32_t discreteQueuePriorities;
+ float pointSizeRange[2];
+ float lineWidthRange[2];
+ float pointSizeGranularity;
+ float lineWidthGranularity;
+ VkBool32 strictLines;
+ VkBool32 standardSampleLocations;
+ VkDeviceSize optimalBufferCopyOffsetAlignment;
+ VkDeviceSize optimalBufferCopyRowPitchAlignment;
+ VkDeviceSize nonCoherentAtomSize;
+} VkPhysicalDeviceLimits;
+
+typedef struct VkPhysicalDeviceMemoryProperties {
+ uint32_t memoryTypeCount;
+ VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES];
+ uint32_t memoryHeapCount;
+ VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS];
+} VkPhysicalDeviceMemoryProperties;
+
+typedef struct VkPhysicalDeviceSparseProperties {
+ VkBool32 residencyStandard2DBlockShape;
+ VkBool32 residencyStandard2DMultisampleBlockShape;
+ VkBool32 residencyStandard3DBlockShape;
+ VkBool32 residencyAlignedMipSize;
+ VkBool32 residencyNonResidentStrict;
+} VkPhysicalDeviceSparseProperties;
+
+typedef struct VkPhysicalDeviceProperties {
+ uint32_t apiVersion;
+ uint32_t driverVersion;
+ uint32_t vendorID;
+ uint32_t deviceID;
+ VkPhysicalDeviceType deviceType;
+ char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
+ uint8_t pipelineCacheUUID[VK_UUID_SIZE];
+ VkPhysicalDeviceLimits limits;
+ VkPhysicalDeviceSparseProperties sparseProperties;
+} VkPhysicalDeviceProperties;
+
+typedef struct VkQueueFamilyProperties {
+ VkQueueFlags queueFlags;
+ uint32_t queueCount;
+ uint32_t timestampValidBits;
+ VkExtent3D minImageTransferGranularity;
+} VkQueueFamilyProperties;
+
+typedef struct VkDeviceQueueCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceQueueCreateFlags flags;
+ uint32_t queueFamilyIndex;
+ uint32_t queueCount;
+ const float* pQueuePriorities;
+} VkDeviceQueueCreateInfo;
+
+typedef struct VkDeviceCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceCreateFlags flags;
+ uint32_t queueCreateInfoCount;
+ const VkDeviceQueueCreateInfo* pQueueCreateInfos;
+ uint32_t enabledLayerCount;
+ const char* const* ppEnabledLayerNames;
+ uint32_t enabledExtensionCount;
+ const char* const* ppEnabledExtensionNames;
+ const VkPhysicalDeviceFeatures* pEnabledFeatures;
+} VkDeviceCreateInfo;
+
+typedef struct VkExtensionProperties {
+ char extensionName[VK_MAX_EXTENSION_NAME_SIZE];
+ uint32_t specVersion;
+} VkExtensionProperties;
+
+typedef struct VkLayerProperties {
+ char layerName[VK_MAX_EXTENSION_NAME_SIZE];
+ uint32_t specVersion;
+ uint32_t implementationVersion;
+ char description[VK_MAX_DESCRIPTION_SIZE];
+} VkLayerProperties;
+
+typedef struct VkSubmitInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t waitSemaphoreCount;
+ const VkSemaphore* pWaitSemaphores;
+ const VkPipelineStageFlags* pWaitDstStageMask;
+ uint32_t commandBufferCount;
+ const VkCommandBuffer* pCommandBuffers;
+ uint32_t signalSemaphoreCount;
+ const VkSemaphore* pSignalSemaphores;
+} VkSubmitInfo;
+
+typedef struct VkMappedMemoryRange {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceMemory memory;
+ VkDeviceSize offset;
+ VkDeviceSize size;
+} VkMappedMemoryRange;
+
+typedef struct VkMemoryAllocateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceSize allocationSize;
+ uint32_t memoryTypeIndex;
+} VkMemoryAllocateInfo;
+
+typedef struct VkMemoryRequirements {
+ VkDeviceSize size;
+ VkDeviceSize alignment;
+ uint32_t memoryTypeBits;
+} VkMemoryRequirements;
+
+typedef struct VkSparseMemoryBind {
+ VkDeviceSize resourceOffset;
+ VkDeviceSize size;
+ VkDeviceMemory memory;
+ VkDeviceSize memoryOffset;
+ VkSparseMemoryBindFlags flags;
+} VkSparseMemoryBind;
+
+typedef struct VkSparseBufferMemoryBindInfo {
+ VkBuffer buffer;
+ uint32_t bindCount;
+ const VkSparseMemoryBind* pBinds;
+} VkSparseBufferMemoryBindInfo;
+
+typedef struct VkSparseImageOpaqueMemoryBindInfo {
+ VkImage image;
+ uint32_t bindCount;
+ const VkSparseMemoryBind* pBinds;
+} VkSparseImageOpaqueMemoryBindInfo;
+
+typedef struct VkImageSubresource {
+ VkImageAspectFlags aspectMask;
+ uint32_t mipLevel;
+ uint32_t arrayLayer;
+} VkImageSubresource;
+
+typedef struct VkSparseImageMemoryBind {
+ VkImageSubresource subresource;
+ VkOffset3D offset;
+ VkExtent3D extent;
+ VkDeviceMemory memory;
+ VkDeviceSize memoryOffset;
+ VkSparseMemoryBindFlags flags;
+} VkSparseImageMemoryBind;
+
+typedef struct VkSparseImageMemoryBindInfo {
+ VkImage image;
+ uint32_t bindCount;
+ const VkSparseImageMemoryBind* pBinds;
+} VkSparseImageMemoryBindInfo;
+
+typedef struct VkBindSparseInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t waitSemaphoreCount;
+ const VkSemaphore* pWaitSemaphores;
+ uint32_t bufferBindCount;
+ const VkSparseBufferMemoryBindInfo* pBufferBinds;
+ uint32_t imageOpaqueBindCount;
+ const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds;
+ uint32_t imageBindCount;
+ const VkSparseImageMemoryBindInfo* pImageBinds;
+ uint32_t signalSemaphoreCount;
+ const VkSemaphore* pSignalSemaphores;
+} VkBindSparseInfo;
+
+typedef struct VkSparseImageFormatProperties {
+ VkImageAspectFlags aspectMask;
+ VkExtent3D imageGranularity;
+ VkSparseImageFormatFlags flags;
+} VkSparseImageFormatProperties;
+
+typedef struct VkSparseImageMemoryRequirements {
+ VkSparseImageFormatProperties formatProperties;
+ uint32_t imageMipTailFirstLod;
+ VkDeviceSize imageMipTailSize;
+ VkDeviceSize imageMipTailOffset;
+ VkDeviceSize imageMipTailStride;
+} VkSparseImageMemoryRequirements;
+
+typedef struct VkFenceCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkFenceCreateFlags flags;
+} VkFenceCreateInfo;
+
+typedef struct VkSemaphoreCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphoreCreateFlags flags;
+} VkSemaphoreCreateInfo;
+
+typedef struct VkEventCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkEventCreateFlags flags;
+} VkEventCreateInfo;
+
+typedef struct VkQueryPoolCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkQueryPoolCreateFlags flags;
+ VkQueryType queryType;
+ uint32_t queryCount;
+ VkQueryPipelineStatisticFlags pipelineStatistics;
+} VkQueryPoolCreateInfo;
+
+typedef struct VkBufferCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkBufferCreateFlags flags;
+ VkDeviceSize size;
+ VkBufferUsageFlags usage;
+ VkSharingMode sharingMode;
+ uint32_t queueFamilyIndexCount;
+ const uint32_t* pQueueFamilyIndices;
+} VkBufferCreateInfo;
+
+typedef struct VkBufferViewCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkBufferViewCreateFlags flags;
+ VkBuffer buffer;
+ VkFormat format;
+ VkDeviceSize offset;
+ VkDeviceSize range;
+} VkBufferViewCreateInfo;
+
+typedef struct VkImageCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageCreateFlags flags;
+ VkImageType imageType;
+ VkFormat format;
+ VkExtent3D extent;
+ uint32_t mipLevels;
+ uint32_t arrayLayers;
+ VkSampleCountFlagBits samples;
+ VkImageTiling tiling;
+ VkImageUsageFlags usage;
+ VkSharingMode sharingMode;
+ uint32_t queueFamilyIndexCount;
+ const uint32_t* pQueueFamilyIndices;
+ VkImageLayout initialLayout;
+} VkImageCreateInfo;
+
+typedef struct VkSubresourceLayout {
+ VkDeviceSize offset;
+ VkDeviceSize size;
+ VkDeviceSize rowPitch;
+ VkDeviceSize arrayPitch;
+ VkDeviceSize depthPitch;
+} VkSubresourceLayout;
+
+typedef struct VkComponentMapping {
+ VkComponentSwizzle r;
+ VkComponentSwizzle g;
+ VkComponentSwizzle b;
+ VkComponentSwizzle a;
+} VkComponentMapping;
+
+typedef struct VkImageViewCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageViewCreateFlags flags;
+ VkImage image;
+ VkImageViewType viewType;
+ VkFormat format;
+ VkComponentMapping components;
+ VkImageSubresourceRange subresourceRange;
+} VkImageViewCreateInfo;
+
+typedef struct VkShaderModuleCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkShaderModuleCreateFlags flags;
+ size_t codeSize;
+ const uint32_t* pCode;
+} VkShaderModuleCreateInfo;
+
+typedef struct VkPipelineCacheCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCacheCreateFlags flags;
+ size_t initialDataSize;
+ const void* pInitialData;
+} VkPipelineCacheCreateInfo;
+
+typedef struct VkSpecializationMapEntry {
+ uint32_t constantID;
+ uint32_t offset;
+ size_t size;
+} VkSpecializationMapEntry;
+
+typedef struct VkSpecializationInfo {
+ uint32_t mapEntryCount;
+ const VkSpecializationMapEntry* pMapEntries;
+ size_t dataSize;
+ const void* pData;
+} VkSpecializationInfo;
+
+typedef struct VkPipelineShaderStageCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineShaderStageCreateFlags flags;
+ VkShaderStageFlagBits stage;
+ VkShaderModule module;
+ const char* pName;
+ const VkSpecializationInfo* pSpecializationInfo;
+} VkPipelineShaderStageCreateInfo;
+
+typedef struct VkComputePipelineCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCreateFlags flags;
+ VkPipelineShaderStageCreateInfo stage;
+ VkPipelineLayout layout;
+ VkPipeline basePipelineHandle;
+ int32_t basePipelineIndex;
+} VkComputePipelineCreateInfo;
+
+typedef struct VkVertexInputBindingDescription {
+ uint32_t binding;
+ uint32_t stride;
+ VkVertexInputRate inputRate;
+} VkVertexInputBindingDescription;
+
+typedef struct VkVertexInputAttributeDescription {
+ uint32_t location;
+ uint32_t binding;
+ VkFormat format;
+ uint32_t offset;
+} VkVertexInputAttributeDescription;
+
+typedef struct VkPipelineVertexInputStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineVertexInputStateCreateFlags flags;
+ uint32_t vertexBindingDescriptionCount;
+ const VkVertexInputBindingDescription* pVertexBindingDescriptions;
+ uint32_t vertexAttributeDescriptionCount;
+ const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
+} VkPipelineVertexInputStateCreateInfo;
+
+typedef struct VkPipelineInputAssemblyStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineInputAssemblyStateCreateFlags flags;
+ VkPrimitiveTopology topology;
+ VkBool32 primitiveRestartEnable;
+} VkPipelineInputAssemblyStateCreateInfo;
+
+typedef struct VkPipelineTessellationStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineTessellationStateCreateFlags flags;
+ uint32_t patchControlPoints;
+} VkPipelineTessellationStateCreateInfo;
+
+typedef struct VkViewport {
+ float x;
+ float y;
+ float width;
+ float height;
+ float minDepth;
+ float maxDepth;
+} VkViewport;
+
+typedef struct VkPipelineViewportStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineViewportStateCreateFlags flags;
+ uint32_t viewportCount;
+ const VkViewport* pViewports;
+ uint32_t scissorCount;
+ const VkRect2D* pScissors;
+} VkPipelineViewportStateCreateInfo;
+
+typedef struct VkPipelineRasterizationStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineRasterizationStateCreateFlags flags;
+ VkBool32 depthClampEnable;
+ VkBool32 rasterizerDiscardEnable;
+ VkPolygonMode polygonMode;
+ VkCullModeFlags cullMode;
+ VkFrontFace frontFace;
+ VkBool32 depthBiasEnable;
+ float depthBiasConstantFactor;
+ float depthBiasClamp;
+ float depthBiasSlopeFactor;
+ float lineWidth;
+} VkPipelineRasterizationStateCreateInfo;
+
+typedef struct VkPipelineMultisampleStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineMultisampleStateCreateFlags flags;
+ VkSampleCountFlagBits rasterizationSamples;
+ VkBool32 sampleShadingEnable;
+ float minSampleShading;
+ const VkSampleMask* pSampleMask;
+ VkBool32 alphaToCoverageEnable;
+ VkBool32 alphaToOneEnable;
+} VkPipelineMultisampleStateCreateInfo;
+
+typedef struct VkStencilOpState {
+ VkStencilOp failOp;
+ VkStencilOp passOp;
+ VkStencilOp depthFailOp;
+ VkCompareOp compareOp;
+ uint32_t compareMask;
+ uint32_t writeMask;
+ uint32_t reference;
+} VkStencilOpState;
+
+typedef struct VkPipelineDepthStencilStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineDepthStencilStateCreateFlags flags;
+ VkBool32 depthTestEnable;
+ VkBool32 depthWriteEnable;
+ VkCompareOp depthCompareOp;
+ VkBool32 depthBoundsTestEnable;
+ VkBool32 stencilTestEnable;
+ VkStencilOpState front;
+ VkStencilOpState back;
+ float minDepthBounds;
+ float maxDepthBounds;
+} VkPipelineDepthStencilStateCreateInfo;
+
+typedef struct VkPipelineColorBlendAttachmentState {
+ VkBool32 blendEnable;
+ VkBlendFactor srcColorBlendFactor;
+ VkBlendFactor dstColorBlendFactor;
+ VkBlendOp colorBlendOp;
+ VkBlendFactor srcAlphaBlendFactor;
+ VkBlendFactor dstAlphaBlendFactor;
+ VkBlendOp alphaBlendOp;
+ VkColorComponentFlags colorWriteMask;
+} VkPipelineColorBlendAttachmentState;
+
+typedef struct VkPipelineColorBlendStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineColorBlendStateCreateFlags flags;
+ VkBool32 logicOpEnable;
+ VkLogicOp logicOp;
+ uint32_t attachmentCount;
+ const VkPipelineColorBlendAttachmentState* pAttachments;
+ float blendConstants[4];
+} VkPipelineColorBlendStateCreateInfo;
+
+typedef struct VkPipelineDynamicStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineDynamicStateCreateFlags flags;
+ uint32_t dynamicStateCount;
+ const VkDynamicState* pDynamicStates;
+} VkPipelineDynamicStateCreateInfo;
+
+typedef struct VkGraphicsPipelineCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCreateFlags flags;
+ uint32_t stageCount;
+ const VkPipelineShaderStageCreateInfo* pStages;
+ const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
+ const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
+ const VkPipelineTessellationStateCreateInfo* pTessellationState;
+ const VkPipelineViewportStateCreateInfo* pViewportState;
+ const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
+ const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
+ const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
+ const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
+ const VkPipelineDynamicStateCreateInfo* pDynamicState;
+ VkPipelineLayout layout;
+ VkRenderPass renderPass;
+ uint32_t subpass;
+ VkPipeline basePipelineHandle;
+ int32_t basePipelineIndex;
+} VkGraphicsPipelineCreateInfo;
+
+typedef struct VkPushConstantRange {
+ VkShaderStageFlags stageFlags;
+ uint32_t offset;
+ uint32_t size;
+} VkPushConstantRange;
+
+typedef struct VkPipelineLayoutCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineLayoutCreateFlags flags;
+ uint32_t setLayoutCount;
+ const VkDescriptorSetLayout* pSetLayouts;
+ uint32_t pushConstantRangeCount;
+ const VkPushConstantRange* pPushConstantRanges;
+} VkPipelineLayoutCreateInfo;
+
+typedef struct VkSamplerCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkSamplerCreateFlags flags;
+ VkFilter magFilter;
+ VkFilter minFilter;
+ VkSamplerMipmapMode mipmapMode;
+ VkSamplerAddressMode addressModeU;
+ VkSamplerAddressMode addressModeV;
+ VkSamplerAddressMode addressModeW;
+ float mipLodBias;
+ VkBool32 anisotropyEnable;
+ float maxAnisotropy;
+ VkBool32 compareEnable;
+ VkCompareOp compareOp;
+ float minLod;
+ float maxLod;
+ VkBorderColor borderColor;
+ VkBool32 unnormalizedCoordinates;
+} VkSamplerCreateInfo;
+
+typedef struct VkCopyDescriptorSet {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorSet srcSet;
+ uint32_t srcBinding;
+ uint32_t srcArrayElement;
+ VkDescriptorSet dstSet;
+ uint32_t dstBinding;
+ uint32_t dstArrayElement;
+ uint32_t descriptorCount;
+} VkCopyDescriptorSet;
+
+typedef struct VkDescriptorBufferInfo {
+ VkBuffer buffer;
+ VkDeviceSize offset;
+ VkDeviceSize range;
+} VkDescriptorBufferInfo;
+
+typedef struct VkDescriptorImageInfo {
+ VkSampler sampler;
+ VkImageView imageView;
+ VkImageLayout imageLayout;
+} VkDescriptorImageInfo;
+
+typedef struct VkDescriptorPoolSize {
+ VkDescriptorType type;
+ uint32_t descriptorCount;
+} VkDescriptorPoolSize;
+
+typedef struct VkDescriptorPoolCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorPoolCreateFlags flags;
+ uint32_t maxSets;
+ uint32_t poolSizeCount;
+ const VkDescriptorPoolSize* pPoolSizes;
+} VkDescriptorPoolCreateInfo;
+
+typedef struct VkDescriptorSetAllocateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorPool descriptorPool;
+ uint32_t descriptorSetCount;
+ const VkDescriptorSetLayout* pSetLayouts;
+} VkDescriptorSetAllocateInfo;
+
+typedef struct VkDescriptorSetLayoutBinding {
+ uint32_t binding;
+ VkDescriptorType descriptorType;
+ uint32_t descriptorCount;
+ VkShaderStageFlags stageFlags;
+ const VkSampler* pImmutableSamplers;
+} VkDescriptorSetLayoutBinding;
+
+typedef struct VkDescriptorSetLayoutCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorSetLayoutCreateFlags flags;
+ uint32_t bindingCount;
+ const VkDescriptorSetLayoutBinding* pBindings;
+} VkDescriptorSetLayoutCreateInfo;
+
+typedef struct VkWriteDescriptorSet {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorSet dstSet;
+ uint32_t dstBinding;
+ uint32_t dstArrayElement;
+ uint32_t descriptorCount;
+ VkDescriptorType descriptorType;
+ const VkDescriptorImageInfo* pImageInfo;
+ const VkDescriptorBufferInfo* pBufferInfo;
+ const VkBufferView* pTexelBufferView;
+} VkWriteDescriptorSet;
+
+typedef struct VkAttachmentDescription {
+ VkAttachmentDescriptionFlags flags;
+ VkFormat format;
+ VkSampleCountFlagBits samples;
+ VkAttachmentLoadOp loadOp;
+ VkAttachmentStoreOp storeOp;
+ VkAttachmentLoadOp stencilLoadOp;
+ VkAttachmentStoreOp stencilStoreOp;
+ VkImageLayout initialLayout;
+ VkImageLayout finalLayout;
+} VkAttachmentDescription;
+
+typedef struct VkAttachmentReference {
+ uint32_t attachment;
+ VkImageLayout layout;
+} VkAttachmentReference;
+
+typedef struct VkFramebufferCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkFramebufferCreateFlags flags;
+ VkRenderPass renderPass;
+ uint32_t attachmentCount;
+ const VkImageView* pAttachments;
+ uint32_t width;
+ uint32_t height;
+ uint32_t layers;
+} VkFramebufferCreateInfo;
+
+typedef struct VkSubpassDescription {
+ VkSubpassDescriptionFlags flags;
+ VkPipelineBindPoint pipelineBindPoint;
+ uint32_t inputAttachmentCount;
+ const VkAttachmentReference* pInputAttachments;
+ uint32_t colorAttachmentCount;
+ const VkAttachmentReference* pColorAttachments;
+ const VkAttachmentReference* pResolveAttachments;
+ const VkAttachmentReference* pDepthStencilAttachment;
+ uint32_t preserveAttachmentCount;
+ const uint32_t* pPreserveAttachments;
+} VkSubpassDescription;
+
+typedef struct VkSubpassDependency {
+ uint32_t srcSubpass;
+ uint32_t dstSubpass;
+ VkPipelineStageFlags srcStageMask;
+ VkPipelineStageFlags dstStageMask;
+ VkAccessFlags srcAccessMask;
+ VkAccessFlags dstAccessMask;
+ VkDependencyFlags dependencyFlags;
+} VkSubpassDependency;
+
+typedef struct VkRenderPassCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkRenderPassCreateFlags flags;
+ uint32_t attachmentCount;
+ const VkAttachmentDescription* pAttachments;
+ uint32_t subpassCount;
+ const VkSubpassDescription* pSubpasses;
+ uint32_t dependencyCount;
+ const VkSubpassDependency* pDependencies;
+} VkRenderPassCreateInfo;
+
+typedef struct VkCommandPoolCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkCommandPoolCreateFlags flags;
+ uint32_t queueFamilyIndex;
+} VkCommandPoolCreateInfo;
+
+typedef struct VkCommandBufferAllocateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkCommandPool commandPool;
+ VkCommandBufferLevel level;
+ uint32_t commandBufferCount;
+} VkCommandBufferAllocateInfo;
+
+typedef struct VkCommandBufferInheritanceInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkRenderPass renderPass;
+ uint32_t subpass;
+ VkFramebuffer framebuffer;
+ VkBool32 occlusionQueryEnable;
+ VkQueryControlFlags queryFlags;
+ VkQueryPipelineStatisticFlags pipelineStatistics;
+} VkCommandBufferInheritanceInfo;
+
+typedef struct VkCommandBufferBeginInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkCommandBufferUsageFlags flags;
+ const VkCommandBufferInheritanceInfo* pInheritanceInfo;
+} VkCommandBufferBeginInfo;
+
+typedef struct VkBufferCopy {
+ VkDeviceSize srcOffset;
+ VkDeviceSize dstOffset;
+ VkDeviceSize size;
+} VkBufferCopy;
+
+typedef struct VkImageSubresourceLayers {
+ VkImageAspectFlags aspectMask;
+ uint32_t mipLevel;
+ uint32_t baseArrayLayer;
+ uint32_t layerCount;
+} VkImageSubresourceLayers;
+
+typedef struct VkBufferImageCopy {
+ VkDeviceSize bufferOffset;
+ uint32_t bufferRowLength;
+ uint32_t bufferImageHeight;
+ VkImageSubresourceLayers imageSubresource;
+ VkOffset3D imageOffset;
+ VkExtent3D imageExtent;
+} VkBufferImageCopy;
+
+typedef union VkClearColorValue {
+ float float32[4];
+ int32_t int32[4];
+ uint32_t uint32[4];
+} VkClearColorValue;
+
+typedef struct VkClearDepthStencilValue {
+ float depth;
+ uint32_t stencil;
+} VkClearDepthStencilValue;
+
+typedef union VkClearValue {
+ VkClearColorValue color;
+ VkClearDepthStencilValue depthStencil;
+} VkClearValue;
+
+typedef struct VkClearAttachment {
+ VkImageAspectFlags aspectMask;
+ uint32_t colorAttachment;
+ VkClearValue clearValue;
+} VkClearAttachment;
+
+typedef struct VkClearRect {
+ VkRect2D rect;
+ uint32_t baseArrayLayer;
+ uint32_t layerCount;
+} VkClearRect;
+
+typedef struct VkImageBlit {
+ VkImageSubresourceLayers srcSubresource;
+ VkOffset3D srcOffsets[2];
+ VkImageSubresourceLayers dstSubresource;
+ VkOffset3D dstOffsets[2];
+} VkImageBlit;
+
+typedef struct VkImageCopy {
+ VkImageSubresourceLayers srcSubresource;
+ VkOffset3D srcOffset;
+ VkImageSubresourceLayers dstSubresource;
+ VkOffset3D dstOffset;
+ VkExtent3D extent;
+} VkImageCopy;
+
+typedef struct VkImageResolve {
+ VkImageSubresourceLayers srcSubresource;
+ VkOffset3D srcOffset;
+ VkImageSubresourceLayers dstSubresource;
+ VkOffset3D dstOffset;
+ VkExtent3D extent;
+} VkImageResolve;
+
+typedef struct VkRenderPassBeginInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkRenderPass renderPass;
+ VkFramebuffer framebuffer;
+ VkRect2D renderArea;
+ uint32_t clearValueCount;
+ const VkClearValue* pClearValues;
+} VkRenderPassBeginInfo;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance);
+typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties);
+typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName);
+typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetDeviceProcAddr)(VkDevice device, const char* pName);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice);
+typedef void (VKAPI_PTR *PFN_vkDestroyDevice)(VkDevice device, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t* pPropertyCount, VkLayerProperties* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue);
+typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence);
+typedef VkResult (VKAPI_PTR *PFN_vkQueueWaitIdle)(VkQueue queue);
+typedef VkResult (VKAPI_PTR *PFN_vkDeviceWaitIdle)(VkDevice device);
+typedef VkResult (VKAPI_PTR *PFN_vkAllocateMemory)(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory);
+typedef void (VKAPI_PTR *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData);
+typedef void (VKAPI_PTR *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory memory);
+typedef VkResult (VKAPI_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges);
+typedef VkResult (VKAPI_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes);
+typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset);
+typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset);
+typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkQueueBindSparse)(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence);
+typedef void (VKAPI_PTR *PFN_vkDestroyFence)(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences);
+typedef VkResult (VKAPI_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence);
+typedef VkResult (VKAPI_PTR *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore);
+typedef void (VKAPI_PTR *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent);
+typedef void (VKAPI_PTR *PFN_vkDestroyEvent)(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkGetEventStatus)(VkDevice device, VkEvent event);
+typedef VkResult (VKAPI_PTR *PFN_vkSetEvent)(VkDevice device, VkEvent event);
+typedef VkResult (VKAPI_PTR *PFN_vkResetEvent)(VkDevice device, VkEvent event);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool);
+typedef void (VKAPI_PTR *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer);
+typedef void (VKAPI_PTR *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView);
+typedef void (VKAPI_PTR *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage);
+typedef void (VKAPI_PTR *PFN_vkDestroyImage)(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView);
+typedef void (VKAPI_PTR *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule);
+typedef void (VKAPI_PTR *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache);
+typedef void (VKAPI_PTR *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData);
+typedef VkResult (VKAPI_PTR *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
+typedef void (VKAPI_PTR *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout);
+typedef void (VKAPI_PTR *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler);
+typedef void (VKAPI_PTR *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout);
+typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool);
+typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags);
+typedef VkResult (VKAPI_PTR *PFN_vkAllocateDescriptorSets)(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets);
+typedef VkResult (VKAPI_PTR *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets);
+typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer);
+typedef void (VKAPI_PTR *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+typedef void (VKAPI_PTR *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateCommandPool)(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool);
+typedef void (VKAPI_PTR *PFN_vkDestroyCommandPool)(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkResetCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags);
+typedef VkResult (VKAPI_PTR *PFN_vkAllocateCommandBuffers)(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers);
+typedef void (VKAPI_PTR *PFN_vkFreeCommandBuffers)(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers);
+typedef VkResult (VKAPI_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer commandBuffer);
+typedef VkResult (VKAPI_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags);
+typedef void (VKAPI_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline);
+typedef void (VKAPI_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports);
+typedef void (VKAPI_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors);
+typedef void (VKAPI_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer commandBuffer, float lineWidth);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor);
+typedef void (VKAPI_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer commandBuffer, const float blendConstants[4]);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds);
+typedef void (VKAPI_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask);
+typedef void (VKAPI_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask);
+typedef void (VKAPI_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference);
+typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets);
+typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType);
+typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets);
+typedef void (VKAPI_PTR *PFN_vkCmdDraw)(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
+typedef void (VKAPI_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions);
+typedef void (VKAPI_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions);
+typedef void (VKAPI_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData);
+typedef void (VKAPI_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data);
+typedef void (VKAPI_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
+typedef void (VKAPI_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
+typedef void (VKAPI_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects);
+typedef void (VKAPI_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve* pRegions);
+typedef void (VKAPI_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask);
+typedef void (VKAPI_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask);
+typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers);
+typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags);
+typedef void (VKAPI_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query);
+typedef void (VKAPI_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
+typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags);
+typedef void (VKAPI_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents);
+typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer commandBuffer, VkSubpassContents contents);
+typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer commandBuffer);
+typedef void (VKAPI_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
+ const VkInstanceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkInstance* pInstance);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(
+ VkInstance instance,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(
+ VkInstance instance,
+ uint32_t* pPhysicalDeviceCount,
+ VkPhysicalDevice* pPhysicalDevices);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures* pFeatures);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkFormatProperties* pFormatProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags flags,
+ VkImageFormatProperties* pImageFormatProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties* pProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties* pQueueFamilyProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties* pMemoryProperties);
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(
+ VkInstance instance,
+ const char* pName);
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(
+ VkDevice device,
+ const char* pName);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(
+ VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDevice* pDevice);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(
+ VkDevice device,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
+ const char* pLayerName,
+ uint32_t* pPropertyCount,
+ VkExtensionProperties* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(
+ VkPhysicalDevice physicalDevice,
+ const char* pLayerName,
+ uint32_t* pPropertyCount,
+ VkExtensionProperties* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
+ uint32_t* pPropertyCount,
+ VkLayerProperties* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkLayerProperties* pProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(
+ VkDevice device,
+ uint32_t queueFamilyIndex,
+ uint32_t queueIndex,
+ VkQueue* pQueue);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(
+ VkQueue queue,
+ uint32_t submitCount,
+ const VkSubmitInfo* pSubmits,
+ VkFence fence);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle(
+ VkQueue queue);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle(
+ VkDevice device);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(
+ VkDevice device,
+ const VkMemoryAllocateInfo* pAllocateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDeviceMemory* pMemory);
+
+VKAPI_ATTR void VKAPI_CALL vkFreeMemory(
+ VkDevice device,
+ VkDeviceMemory memory,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory(
+ VkDevice device,
+ VkDeviceMemory memory,
+ VkDeviceSize offset,
+ VkDeviceSize size,
+ VkMemoryMapFlags flags,
+ void** ppData);
+
+VKAPI_ATTR void VKAPI_CALL vkUnmapMemory(
+ VkDevice device,
+ VkDeviceMemory memory);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges(
+ VkDevice device,
+ uint32_t memoryRangeCount,
+ const VkMappedMemoryRange* pMemoryRanges);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges(
+ VkDevice device,
+ uint32_t memoryRangeCount,
+ const VkMappedMemoryRange* pMemoryRanges);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment(
+ VkDevice device,
+ VkDeviceMemory memory,
+ VkDeviceSize* pCommittedMemoryInBytes);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory(
+ VkDevice device,
+ VkBuffer buffer,
+ VkDeviceMemory memory,
+ VkDeviceSize memoryOffset);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory(
+ VkDevice device,
+ VkImage image,
+ VkDeviceMemory memory,
+ VkDeviceSize memoryOffset);
+
+VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements(
+ VkDevice device,
+ VkBuffer buffer,
+ VkMemoryRequirements* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements(
+ VkDevice device,
+ VkImage image,
+ VkMemoryRequirements* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements(
+ VkDevice device,
+ VkImage image,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements* pSparseMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkSampleCountFlagBits samples,
+ VkImageUsageFlags usage,
+ VkImageTiling tiling,
+ uint32_t* pPropertyCount,
+ VkSparseImageFormatProperties* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse(
+ VkQueue queue,
+ uint32_t bindInfoCount,
+ const VkBindSparseInfo* pBindInfo,
+ VkFence fence);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence(
+ VkDevice device,
+ const VkFenceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFence* pFence);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyFence(
+ VkDevice device,
+ VkFence fence,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetFences(
+ VkDevice device,
+ uint32_t fenceCount,
+ const VkFence* pFences);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus(
+ VkDevice device,
+ VkFence fence);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences(
+ VkDevice device,
+ uint32_t fenceCount,
+ const VkFence* pFences,
+ VkBool32 waitAll,
+ uint64_t timeout);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore(
+ VkDevice device,
+ const VkSemaphoreCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSemaphore* pSemaphore);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore(
+ VkDevice device,
+ VkSemaphore semaphore,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent(
+ VkDevice device,
+ const VkEventCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkEvent* pEvent);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyEvent(
+ VkDevice device,
+ VkEvent event,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus(
+ VkDevice device,
+ VkEvent event);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent(
+ VkDevice device,
+ VkEvent event);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent(
+ VkDevice device,
+ VkEvent event);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool(
+ VkDevice device,
+ const VkQueryPoolCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkQueryPool* pQueryPool);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool(
+ VkDevice device,
+ VkQueryPool queryPool,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults(
+ VkDevice device,
+ VkQueryPool queryPool,
+ uint32_t firstQuery,
+ uint32_t queryCount,
+ size_t dataSize,
+ void* pData,
+ VkDeviceSize stride,
+ VkQueryResultFlags flags);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer(
+ VkDevice device,
+ const VkBufferCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkBuffer* pBuffer);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer(
+ VkDevice device,
+ VkBuffer buffer,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView(
+ VkDevice device,
+ const VkBufferViewCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkBufferView* pView);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView(
+ VkDevice device,
+ VkBufferView bufferView,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage(
+ VkDevice device,
+ const VkImageCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkImage* pImage);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyImage(
+ VkDevice device,
+ VkImage image,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout(
+ VkDevice device,
+ VkImage image,
+ const VkImageSubresource* pSubresource,
+ VkSubresourceLayout* pLayout);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView(
+ VkDevice device,
+ const VkImageViewCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkImageView* pView);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyImageView(
+ VkDevice device,
+ VkImageView imageView,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule(
+ VkDevice device,
+ const VkShaderModuleCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkShaderModule* pShaderModule);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule(
+ VkDevice device,
+ VkShaderModule shaderModule,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache(
+ VkDevice device,
+ const VkPipelineCacheCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipelineCache* pPipelineCache);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache(
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData(
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ size_t* pDataSize,
+ void* pData);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches(
+ VkDevice device,
+ VkPipelineCache dstCache,
+ uint32_t srcCacheCount,
+ const VkPipelineCache* pSrcCaches);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines(
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkGraphicsPipelineCreateInfo* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipeline* pPipelines);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines(
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkComputePipelineCreateInfo* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipeline* pPipelines);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline(
+ VkDevice device,
+ VkPipeline pipeline,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout(
+ VkDevice device,
+ const VkPipelineLayoutCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipelineLayout* pPipelineLayout);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(
+ VkDevice device,
+ VkPipelineLayout pipelineLayout,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(
+ VkDevice device,
+ const VkSamplerCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSampler* pSampler);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySampler(
+ VkDevice device,
+ VkSampler sampler,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout(
+ VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorSetLayout* pSetLayout);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout(
+ VkDevice device,
+ VkDescriptorSetLayout descriptorSetLayout,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool(
+ VkDevice device,
+ const VkDescriptorPoolCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorPool* pDescriptorPool);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool(
+ VkDevice device,
+ VkDescriptorPool descriptorPool,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool(
+ VkDevice device,
+ VkDescriptorPool descriptorPool,
+ VkDescriptorPoolResetFlags flags);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets(
+ VkDevice device,
+ const VkDescriptorSetAllocateInfo* pAllocateInfo,
+ VkDescriptorSet* pDescriptorSets);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets(
+ VkDevice device,
+ VkDescriptorPool descriptorPool,
+ uint32_t descriptorSetCount,
+ const VkDescriptorSet* pDescriptorSets);
+
+VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets(
+ VkDevice device,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet* pDescriptorWrites,
+ uint32_t descriptorCopyCount,
+ const VkCopyDescriptorSet* pDescriptorCopies);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer(
+ VkDevice device,
+ const VkFramebufferCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFramebuffer* pFramebuffer);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer(
+ VkDevice device,
+ VkFramebuffer framebuffer,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(
+ VkDevice device,
+ const VkRenderPassCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkRenderPass* pRenderPass);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass(
+ VkDevice device,
+ VkRenderPass renderPass,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity(
+ VkDevice device,
+ VkRenderPass renderPass,
+ VkExtent2D* pGranularity);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool(
+ VkDevice device,
+ const VkCommandPoolCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkCommandPool* pCommandPool);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool(
+ VkDevice device,
+ VkCommandPool commandPool,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool(
+ VkDevice device,
+ VkCommandPool commandPool,
+ VkCommandPoolResetFlags flags);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers(
+ VkDevice device,
+ const VkCommandBufferAllocateInfo* pAllocateInfo,
+ VkCommandBuffer* pCommandBuffers);
+
+VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers(
+ VkDevice device,
+ VkCommandPool commandPool,
+ uint32_t commandBufferCount,
+ const VkCommandBuffer* pCommandBuffers);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer(
+ VkCommandBuffer commandBuffer,
+ const VkCommandBufferBeginInfo* pBeginInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer(
+ VkCommandBuffer commandBuffer);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer(
+ VkCommandBuffer commandBuffer,
+ VkCommandBufferResetFlags flags);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline(
+ VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipeline pipeline);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkViewport* pViewports);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstScissor,
+ uint32_t scissorCount,
+ const VkRect2D* pScissors);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth(
+ VkCommandBuffer commandBuffer,
+ float lineWidth);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias(
+ VkCommandBuffer commandBuffer,
+ float depthBiasConstantFactor,
+ float depthBiasClamp,
+ float depthBiasSlopeFactor);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants(
+ VkCommandBuffer commandBuffer,
+ const float blendConstants[4]);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds(
+ VkCommandBuffer commandBuffer,
+ float minDepthBounds,
+ float maxDepthBounds);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask(
+ VkCommandBuffer commandBuffer,
+ VkStencilFaceFlags faceMask,
+ uint32_t compareMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask(
+ VkCommandBuffer commandBuffer,
+ VkStencilFaceFlags faceMask,
+ uint32_t writeMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference(
+ VkCommandBuffer commandBuffer,
+ VkStencilFaceFlags faceMask,
+ uint32_t reference);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets(
+ VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipelineLayout layout,
+ uint32_t firstSet,
+ uint32_t descriptorSetCount,
+ const VkDescriptorSet* pDescriptorSets,
+ uint32_t dynamicOffsetCount,
+ const uint32_t* pDynamicOffsets);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkIndexType indexType);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstBinding,
+ uint32_t bindingCount,
+ const VkBuffer* pBuffers,
+ const VkDeviceSize* pOffsets);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDraw(
+ VkCommandBuffer commandBuffer,
+ uint32_t vertexCount,
+ uint32_t instanceCount,
+ uint32_t firstVertex,
+ uint32_t firstInstance);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed(
+ VkCommandBuffer commandBuffer,
+ uint32_t indexCount,
+ uint32_t instanceCount,
+ uint32_t firstIndex,
+ int32_t vertexOffset,
+ uint32_t firstInstance);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ uint32_t drawCount,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ uint32_t drawCount,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDispatch(
+ VkCommandBuffer commandBuffer,
+ uint32_t groupCountX,
+ uint32_t groupCountY,
+ uint32_t groupCountZ);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer(
+ VkCommandBuffer commandBuffer,
+ VkBuffer srcBuffer,
+ VkBuffer dstBuffer,
+ uint32_t regionCount,
+ const VkBufferCopy* pRegions);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage(
+ VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkImageCopy* pRegions);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage(
+ VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkImageBlit* pRegions,
+ VkFilter filter);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage(
+ VkCommandBuffer commandBuffer,
+ VkBuffer srcBuffer,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkBufferImageCopy* pRegions);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer(
+ VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkBuffer dstBuffer,
+ uint32_t regionCount,
+ const VkBufferImageCopy* pRegions);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer(
+ VkCommandBuffer commandBuffer,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ VkDeviceSize dataSize,
+ const void* pData);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer(
+ VkCommandBuffer commandBuffer,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ VkDeviceSize size,
+ uint32_t data);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage(
+ VkCommandBuffer commandBuffer,
+ VkImage image,
+ VkImageLayout imageLayout,
+ const VkClearColorValue* pColor,
+ uint32_t rangeCount,
+ const VkImageSubresourceRange* pRanges);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage(
+ VkCommandBuffer commandBuffer,
+ VkImage image,
+ VkImageLayout imageLayout,
+ const VkClearDepthStencilValue* pDepthStencil,
+ uint32_t rangeCount,
+ const VkImageSubresourceRange* pRanges);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments(
+ VkCommandBuffer commandBuffer,
+ uint32_t attachmentCount,
+ const VkClearAttachment* pAttachments,
+ uint32_t rectCount,
+ const VkClearRect* pRects);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage(
+ VkCommandBuffer commandBuffer,
+ VkImage srcImage,
+ VkImageLayout srcImageLayout,
+ VkImage dstImage,
+ VkImageLayout dstImageLayout,
+ uint32_t regionCount,
+ const VkImageResolve* pRegions);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent(
+ VkCommandBuffer commandBuffer,
+ VkEvent event,
+ VkPipelineStageFlags stageMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent(
+ VkCommandBuffer commandBuffer,
+ VkEvent event,
+ VkPipelineStageFlags stageMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents(
+ VkCommandBuffer commandBuffer,
+ uint32_t eventCount,
+ const VkEvent* pEvents,
+ VkPipelineStageFlags srcStageMask,
+ VkPipelineStageFlags dstStageMask,
+ uint32_t memoryBarrierCount,
+ const VkMemoryBarrier* pMemoryBarriers,
+ uint32_t bufferMemoryBarrierCount,
+ const VkBufferMemoryBarrier* pBufferMemoryBarriers,
+ uint32_t imageMemoryBarrierCount,
+ const VkImageMemoryBarrier* pImageMemoryBarriers);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlags srcStageMask,
+ VkPipelineStageFlags dstStageMask,
+ VkDependencyFlags dependencyFlags,
+ uint32_t memoryBarrierCount,
+ const VkMemoryBarrier* pMemoryBarriers,
+ uint32_t bufferMemoryBarrierCount,
+ const VkBufferMemoryBarrier* pBufferMemoryBarriers,
+ uint32_t imageMemoryBarrierCount,
+ const VkImageMemoryBarrier* pImageMemoryBarriers);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t query,
+ VkQueryControlFlags flags);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t query);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t firstQuery,
+ uint32_t queryCount);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlagBits pipelineStage,
+ VkQueryPool queryPool,
+ uint32_t query);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t firstQuery,
+ uint32_t queryCount,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ VkDeviceSize stride,
+ VkQueryResultFlags flags);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants(
+ VkCommandBuffer commandBuffer,
+ VkPipelineLayout layout,
+ VkShaderStageFlags stageFlags,
+ uint32_t offset,
+ uint32_t size,
+ const void* pValues);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(
+ VkCommandBuffer commandBuffer,
+ const VkRenderPassBeginInfo* pRenderPassBegin,
+ VkSubpassContents contents);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass(
+ VkCommandBuffer commandBuffer,
+ VkSubpassContents contents);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass(
+ VkCommandBuffer commandBuffer);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands(
+ VkCommandBuffer commandBuffer,
+ uint32_t commandBufferCount,
+ const VkCommandBuffer* pCommandBuffers);
+#endif
+
+
+#define VK_VERSION_1_1 1
+// Vulkan 1.1 version number
+#define VK_API_VERSION_1_1 VK_MAKE_API_VERSION(0, 1, 1, 0)// Patch version should always be set to 0
+
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversion)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplate)
+#define VK_MAX_DEVICE_GROUP_SIZE 32U
+#define VK_LUID_SIZE 8U
+#define VK_QUEUE_FAMILY_EXTERNAL (~1U)
+
+typedef enum VkPointClippingBehavior {
+ VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES = 0,
+ VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY = 1,
+ VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES,
+ VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY,
+ VK_POINT_CLIPPING_BEHAVIOR_MAX_ENUM = 0x7FFFFFFF
+} VkPointClippingBehavior;
+
+typedef enum VkTessellationDomainOrigin {
+ VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT = 0,
+ VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1,
+ VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT,
+ VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT,
+ VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM = 0x7FFFFFFF
+} VkTessellationDomainOrigin;
+
+typedef enum VkSamplerYcbcrModelConversion {
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0,
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY = 1,
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 = 2,
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 = 3,
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 = 4,
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY,
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709,
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601,
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020,
+ VK_SAMPLER_YCBCR_MODEL_CONVERSION_MAX_ENUM = 0x7FFFFFFF
+} VkSamplerYcbcrModelConversion;
+
+typedef enum VkSamplerYcbcrRange {
+ VK_SAMPLER_YCBCR_RANGE_ITU_FULL = 0,
+ VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1,
+ VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
+ VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW,
+ VK_SAMPLER_YCBCR_RANGE_MAX_ENUM = 0x7FFFFFFF
+} VkSamplerYcbcrRange;
+
+typedef enum VkChromaLocation {
+ VK_CHROMA_LOCATION_COSITED_EVEN = 0,
+ VK_CHROMA_LOCATION_MIDPOINT = 1,
+ VK_CHROMA_LOCATION_COSITED_EVEN_KHR = VK_CHROMA_LOCATION_COSITED_EVEN,
+ VK_CHROMA_LOCATION_MIDPOINT_KHR = VK_CHROMA_LOCATION_MIDPOINT,
+ VK_CHROMA_LOCATION_MAX_ENUM = 0x7FFFFFFF
+} VkChromaLocation;
+
+typedef enum VkDescriptorUpdateTemplateType {
+ VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0,
+ VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1,
+ VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
+ VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorUpdateTemplateType;
+
+typedef enum VkSubgroupFeatureFlagBits {
+ VK_SUBGROUP_FEATURE_BASIC_BIT = 0x00000001,
+ VK_SUBGROUP_FEATURE_VOTE_BIT = 0x00000002,
+ VK_SUBGROUP_FEATURE_ARITHMETIC_BIT = 0x00000004,
+ VK_SUBGROUP_FEATURE_BALLOT_BIT = 0x00000008,
+ VK_SUBGROUP_FEATURE_SHUFFLE_BIT = 0x00000010,
+ VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 0x00000020,
+ VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 0x00000040,
+ VK_SUBGROUP_FEATURE_QUAD_BIT = 0x00000080,
+ VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV = 0x00000100,
+ VK_SUBGROUP_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSubgroupFeatureFlagBits;
+typedef VkFlags VkSubgroupFeatureFlags;
+
+typedef enum VkPeerMemoryFeatureFlagBits {
+ VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT = 0x00000001,
+ VK_PEER_MEMORY_FEATURE_COPY_DST_BIT = 0x00000002,
+ VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT = 0x00000004,
+ VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT = 0x00000008,
+ VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT_KHR = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT,
+ VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHR = VK_PEER_MEMORY_FEATURE_COPY_DST_BIT,
+ VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT_KHR = VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT,
+ VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT_KHR = VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT,
+ VK_PEER_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkPeerMemoryFeatureFlagBits;
+typedef VkFlags VkPeerMemoryFeatureFlags;
+
+typedef enum VkMemoryAllocateFlagBits {
+ VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 0x00000001,
+ VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT = 0x00000002,
+ VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000004,
+ VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT,
+ VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT,
+ VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
+ VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkMemoryAllocateFlagBits;
+typedef VkFlags VkMemoryAllocateFlags;
+typedef VkFlags VkCommandPoolTrimFlags;
+typedef VkFlags VkDescriptorUpdateTemplateCreateFlags;
+
+typedef enum VkExternalMemoryHandleTypeFlagBits {
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT = 0x00000008,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT = 0x00000010,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT = 0x00000020,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT = 0x00000040,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT = 0x00000200,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID = 0x00000400,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT = 0x00000080,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA = 0x00000800,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV = 0x00001000,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkExternalMemoryHandleTypeFlagBits;
+typedef VkFlags VkExternalMemoryHandleTypeFlags;
+
+typedef enum VkExternalMemoryFeatureFlagBits {
+ VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT = 0x00000001,
+ VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT = 0x00000002,
+ VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT = 0x00000004,
+ VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT,
+ VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT,
+ VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT,
+ VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkExternalMemoryFeatureFlagBits;
+typedef VkFlags VkExternalMemoryFeatureFlags;
+
+typedef enum VkExternalFenceHandleTypeFlagBits {
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000008,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkExternalFenceHandleTypeFlagBits;
+typedef VkFlags VkExternalFenceHandleTypeFlags;
+
+typedef enum VkExternalFenceFeatureFlagBits {
+ VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT = 0x00000001,
+ VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT = 0x00000002,
+ VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT,
+ VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT,
+ VK_EXTERNAL_FENCE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkExternalFenceFeatureFlagBits;
+typedef VkFlags VkExternalFenceFeatureFlags;
+
+typedef enum VkFenceImportFlagBits {
+ VK_FENCE_IMPORT_TEMPORARY_BIT = 0x00000001,
+ VK_FENCE_IMPORT_TEMPORARY_BIT_KHR = VK_FENCE_IMPORT_TEMPORARY_BIT,
+ VK_FENCE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkFenceImportFlagBits;
+typedef VkFlags VkFenceImportFlags;
+
+typedef enum VkSemaphoreImportFlagBits {
+ VK_SEMAPHORE_IMPORT_TEMPORARY_BIT = 0x00000001,
+ VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
+ VK_SEMAPHORE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSemaphoreImportFlagBits;
+typedef VkFlags VkSemaphoreImportFlags;
+
+typedef enum VkExternalSemaphoreHandleTypeFlagBits {
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT = 0x00000008,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000010,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA = 0x00000080,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE_BIT = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkExternalSemaphoreHandleTypeFlagBits;
+typedef VkFlags VkExternalSemaphoreHandleTypeFlags;
+
+typedef enum VkExternalSemaphoreFeatureFlagBits {
+ VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT = 0x00000001,
+ VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT = 0x00000002,
+ VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT,
+ VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT,
+ VK_EXTERNAL_SEMAPHORE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkExternalSemaphoreFeatureFlagBits;
+typedef VkFlags VkExternalSemaphoreFeatureFlags;
+typedef struct VkPhysicalDeviceSubgroupProperties {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t subgroupSize;
+ VkShaderStageFlags supportedStages;
+ VkSubgroupFeatureFlags supportedOperations;
+ VkBool32 quadOperationsInAllStages;
+} VkPhysicalDeviceSubgroupProperties;
+
+typedef struct VkBindBufferMemoryInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkBuffer buffer;
+ VkDeviceMemory memory;
+ VkDeviceSize memoryOffset;
+} VkBindBufferMemoryInfo;
+
+typedef struct VkBindImageMemoryInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage image;
+ VkDeviceMemory memory;
+ VkDeviceSize memoryOffset;
+} VkBindImageMemoryInfo;
+
+typedef struct VkPhysicalDevice16BitStorageFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 storageBuffer16BitAccess;
+ VkBool32 uniformAndStorageBuffer16BitAccess;
+ VkBool32 storagePushConstant16;
+ VkBool32 storageInputOutput16;
+} VkPhysicalDevice16BitStorageFeatures;
+
+typedef struct VkMemoryDedicatedRequirements {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 prefersDedicatedAllocation;
+ VkBool32 requiresDedicatedAllocation;
+} VkMemoryDedicatedRequirements;
+
+typedef struct VkMemoryDedicatedAllocateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage image;
+ VkBuffer buffer;
+} VkMemoryDedicatedAllocateInfo;
+
+typedef struct VkMemoryAllocateFlagsInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkMemoryAllocateFlags flags;
+ uint32_t deviceMask;
+} VkMemoryAllocateFlagsInfo;
+
+typedef struct VkDeviceGroupRenderPassBeginInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t deviceMask;
+ uint32_t deviceRenderAreaCount;
+ const VkRect2D* pDeviceRenderAreas;
+} VkDeviceGroupRenderPassBeginInfo;
+
+typedef struct VkDeviceGroupCommandBufferBeginInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t deviceMask;
+} VkDeviceGroupCommandBufferBeginInfo;
+
+typedef struct VkDeviceGroupSubmitInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t waitSemaphoreCount;
+ const uint32_t* pWaitSemaphoreDeviceIndices;
+ uint32_t commandBufferCount;
+ const uint32_t* pCommandBufferDeviceMasks;
+ uint32_t signalSemaphoreCount;
+ const uint32_t* pSignalSemaphoreDeviceIndices;
+} VkDeviceGroupSubmitInfo;
+
+typedef struct VkDeviceGroupBindSparseInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t resourceDeviceIndex;
+ uint32_t memoryDeviceIndex;
+} VkDeviceGroupBindSparseInfo;
+
+typedef struct VkBindBufferMemoryDeviceGroupInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t deviceIndexCount;
+ const uint32_t* pDeviceIndices;
+} VkBindBufferMemoryDeviceGroupInfo;
+
+typedef struct VkBindImageMemoryDeviceGroupInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t deviceIndexCount;
+ const uint32_t* pDeviceIndices;
+ uint32_t splitInstanceBindRegionCount;
+ const VkRect2D* pSplitInstanceBindRegions;
+} VkBindImageMemoryDeviceGroupInfo;
+
+typedef struct VkPhysicalDeviceGroupProperties {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t physicalDeviceCount;
+ VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE];
+ VkBool32 subsetAllocation;
+} VkPhysicalDeviceGroupProperties;
+
+typedef struct VkDeviceGroupDeviceCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t physicalDeviceCount;
+ const VkPhysicalDevice* pPhysicalDevices;
+} VkDeviceGroupDeviceCreateInfo;
+
+typedef struct VkBufferMemoryRequirementsInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkBuffer buffer;
+} VkBufferMemoryRequirementsInfo2;
+
+typedef struct VkImageMemoryRequirementsInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage image;
+} VkImageMemoryRequirementsInfo2;
+
+typedef struct VkImageSparseMemoryRequirementsInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage image;
+} VkImageSparseMemoryRequirementsInfo2;
+
+typedef struct VkMemoryRequirements2 {
+ VkStructureType sType;
+ void* pNext;
+ VkMemoryRequirements memoryRequirements;
+} VkMemoryRequirements2;
+
+typedef struct VkSparseImageMemoryRequirements2 {
+ VkStructureType sType;
+ void* pNext;
+ VkSparseImageMemoryRequirements memoryRequirements;
+} VkSparseImageMemoryRequirements2;
+
+typedef struct VkPhysicalDeviceFeatures2 {
+ VkStructureType sType;
+ void* pNext;
+ VkPhysicalDeviceFeatures features;
+} VkPhysicalDeviceFeatures2;
+
+typedef struct VkPhysicalDeviceProperties2 {
+ VkStructureType sType;
+ void* pNext;
+ VkPhysicalDeviceProperties properties;
+} VkPhysicalDeviceProperties2;
+
+typedef struct VkFormatProperties2 {
+ VkStructureType sType;
+ void* pNext;
+ VkFormatProperties formatProperties;
+} VkFormatProperties2;
+
+typedef struct VkImageFormatProperties2 {
+ VkStructureType sType;
+ void* pNext;
+ VkImageFormatProperties imageFormatProperties;
+} VkImageFormatProperties2;
+
+typedef struct VkPhysicalDeviceImageFormatInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkFormat format;
+ VkImageType type;
+ VkImageTiling tiling;
+ VkImageUsageFlags usage;
+ VkImageCreateFlags flags;
+} VkPhysicalDeviceImageFormatInfo2;
+
+typedef struct VkQueueFamilyProperties2 {
+ VkStructureType sType;
+ void* pNext;
+ VkQueueFamilyProperties queueFamilyProperties;
+} VkQueueFamilyProperties2;
+
+typedef struct VkPhysicalDeviceMemoryProperties2 {
+ VkStructureType sType;
+ void* pNext;
+ VkPhysicalDeviceMemoryProperties memoryProperties;
+} VkPhysicalDeviceMemoryProperties2;
+
+typedef struct VkSparseImageFormatProperties2 {
+ VkStructureType sType;
+ void* pNext;
+ VkSparseImageFormatProperties properties;
+} VkSparseImageFormatProperties2;
+
+typedef struct VkPhysicalDeviceSparseImageFormatInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkFormat format;
+ VkImageType type;
+ VkSampleCountFlagBits samples;
+ VkImageUsageFlags usage;
+ VkImageTiling tiling;
+} VkPhysicalDeviceSparseImageFormatInfo2;
+
+typedef struct VkPhysicalDevicePointClippingProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkPointClippingBehavior pointClippingBehavior;
+} VkPhysicalDevicePointClippingProperties;
+
+typedef struct VkInputAttachmentAspectReference {
+ uint32_t subpass;
+ uint32_t inputAttachmentIndex;
+ VkImageAspectFlags aspectMask;
+} VkInputAttachmentAspectReference;
+
+typedef struct VkRenderPassInputAttachmentAspectCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t aspectReferenceCount;
+ const VkInputAttachmentAspectReference* pAspectReferences;
+} VkRenderPassInputAttachmentAspectCreateInfo;
+
+typedef struct VkImageViewUsageCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageUsageFlags usage;
+} VkImageViewUsageCreateInfo;
+
+typedef struct VkPipelineTessellationDomainOriginStateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkTessellationDomainOrigin domainOrigin;
+} VkPipelineTessellationDomainOriginStateCreateInfo;
+
+typedef struct VkRenderPassMultiviewCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t subpassCount;
+ const uint32_t* pViewMasks;
+ uint32_t dependencyCount;
+ const int32_t* pViewOffsets;
+ uint32_t correlationMaskCount;
+ const uint32_t* pCorrelationMasks;
+} VkRenderPassMultiviewCreateInfo;
+
+typedef struct VkPhysicalDeviceMultiviewFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 multiview;
+ VkBool32 multiviewGeometryShader;
+ VkBool32 multiviewTessellationShader;
+} VkPhysicalDeviceMultiviewFeatures;
+
+typedef struct VkPhysicalDeviceMultiviewProperties {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxMultiviewViewCount;
+ uint32_t maxMultiviewInstanceIndex;
+} VkPhysicalDeviceMultiviewProperties;
+
+typedef struct VkPhysicalDeviceVariablePointersFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 variablePointersStorageBuffer;
+ VkBool32 variablePointers;
+} VkPhysicalDeviceVariablePointersFeatures;
+
+typedef VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointerFeatures;
+
+typedef struct VkPhysicalDeviceProtectedMemoryFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 protectedMemory;
+} VkPhysicalDeviceProtectedMemoryFeatures;
+
+typedef struct VkPhysicalDeviceProtectedMemoryProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 protectedNoFault;
+} VkPhysicalDeviceProtectedMemoryProperties;
+
+typedef struct VkDeviceQueueInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceQueueCreateFlags flags;
+ uint32_t queueFamilyIndex;
+ uint32_t queueIndex;
+} VkDeviceQueueInfo2;
+
+typedef struct VkProtectedSubmitInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 protectedSubmit;
+} VkProtectedSubmitInfo;
+
+typedef struct VkSamplerYcbcrConversionCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkFormat format;
+ VkSamplerYcbcrModelConversion ycbcrModel;
+ VkSamplerYcbcrRange ycbcrRange;
+ VkComponentMapping components;
+ VkChromaLocation xChromaOffset;
+ VkChromaLocation yChromaOffset;
+ VkFilter chromaFilter;
+ VkBool32 forceExplicitReconstruction;
+} VkSamplerYcbcrConversionCreateInfo;
+
+typedef struct VkSamplerYcbcrConversionInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkSamplerYcbcrConversion conversion;
+} VkSamplerYcbcrConversionInfo;
+
+typedef struct VkBindImagePlaneMemoryInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageAspectFlagBits planeAspect;
+} VkBindImagePlaneMemoryInfo;
+
+typedef struct VkImagePlaneMemoryRequirementsInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageAspectFlagBits planeAspect;
+} VkImagePlaneMemoryRequirementsInfo;
+
+typedef struct VkPhysicalDeviceSamplerYcbcrConversionFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 samplerYcbcrConversion;
+} VkPhysicalDeviceSamplerYcbcrConversionFeatures;
+
+typedef struct VkSamplerYcbcrConversionImageFormatProperties {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t combinedImageSamplerDescriptorCount;
+} VkSamplerYcbcrConversionImageFormatProperties;
+
+typedef struct VkDescriptorUpdateTemplateEntry {
+ uint32_t dstBinding;
+ uint32_t dstArrayElement;
+ uint32_t descriptorCount;
+ VkDescriptorType descriptorType;
+ size_t offset;
+ size_t stride;
+} VkDescriptorUpdateTemplateEntry;
+
+typedef struct VkDescriptorUpdateTemplateCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorUpdateTemplateCreateFlags flags;
+ uint32_t descriptorUpdateEntryCount;
+ const VkDescriptorUpdateTemplateEntry* pDescriptorUpdateEntries;
+ VkDescriptorUpdateTemplateType templateType;
+ VkDescriptorSetLayout descriptorSetLayout;
+ VkPipelineBindPoint pipelineBindPoint;
+ VkPipelineLayout pipelineLayout;
+ uint32_t set;
+} VkDescriptorUpdateTemplateCreateInfo;
+
+typedef struct VkExternalMemoryProperties {
+ VkExternalMemoryFeatureFlags externalMemoryFeatures;
+ VkExternalMemoryHandleTypeFlags exportFromImportedHandleTypes;
+ VkExternalMemoryHandleTypeFlags compatibleHandleTypes;
+} VkExternalMemoryProperties;
+
+typedef struct VkPhysicalDeviceExternalImageFormatInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagBits handleType;
+} VkPhysicalDeviceExternalImageFormatInfo;
+
+typedef struct VkExternalImageFormatProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkExternalMemoryProperties externalMemoryProperties;
+} VkExternalImageFormatProperties;
+
+typedef struct VkPhysicalDeviceExternalBufferInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkBufferCreateFlags flags;
+ VkBufferUsageFlags usage;
+ VkExternalMemoryHandleTypeFlagBits handleType;
+} VkPhysicalDeviceExternalBufferInfo;
+
+typedef struct VkExternalBufferProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkExternalMemoryProperties externalMemoryProperties;
+} VkExternalBufferProperties;
+
+typedef struct VkPhysicalDeviceIDProperties {
+ VkStructureType sType;
+ void* pNext;
+ uint8_t deviceUUID[VK_UUID_SIZE];
+ uint8_t driverUUID[VK_UUID_SIZE];
+ uint8_t deviceLUID[VK_LUID_SIZE];
+ uint32_t deviceNodeMask;
+ VkBool32 deviceLUIDValid;
+} VkPhysicalDeviceIDProperties;
+
+typedef struct VkExternalMemoryImageCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlags handleTypes;
+} VkExternalMemoryImageCreateInfo;
+
+typedef struct VkExternalMemoryBufferCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlags handleTypes;
+} VkExternalMemoryBufferCreateInfo;
+
+typedef struct VkExportMemoryAllocateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlags handleTypes;
+} VkExportMemoryAllocateInfo;
+
+typedef struct VkPhysicalDeviceExternalFenceInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalFenceHandleTypeFlagBits handleType;
+} VkPhysicalDeviceExternalFenceInfo;
+
+typedef struct VkExternalFenceProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkExternalFenceHandleTypeFlags exportFromImportedHandleTypes;
+ VkExternalFenceHandleTypeFlags compatibleHandleTypes;
+ VkExternalFenceFeatureFlags externalFenceFeatures;
+} VkExternalFenceProperties;
+
+typedef struct VkExportFenceCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalFenceHandleTypeFlags handleTypes;
+} VkExportFenceCreateInfo;
+
+typedef struct VkExportSemaphoreCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalSemaphoreHandleTypeFlags handleTypes;
+} VkExportSemaphoreCreateInfo;
+
+typedef struct VkPhysicalDeviceExternalSemaphoreInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalSemaphoreHandleTypeFlagBits handleType;
+} VkPhysicalDeviceExternalSemaphoreInfo;
+
+typedef struct VkExternalSemaphoreProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkExternalSemaphoreHandleTypeFlags exportFromImportedHandleTypes;
+ VkExternalSemaphoreHandleTypeFlags compatibleHandleTypes;
+ VkExternalSemaphoreFeatureFlags externalSemaphoreFeatures;
+} VkExternalSemaphoreProperties;
+
+typedef struct VkPhysicalDeviceMaintenance3Properties {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxPerSetDescriptors;
+ VkDeviceSize maxMemoryAllocationSize;
+} VkPhysicalDeviceMaintenance3Properties;
+
+typedef struct VkDescriptorSetLayoutSupport {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 supported;
+} VkDescriptorSetLayoutSupport;
+
+typedef struct VkPhysicalDeviceShaderDrawParametersFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderDrawParameters;
+} VkPhysicalDeviceShaderDrawParametersFeatures;
+
+typedef VkPhysicalDeviceShaderDrawParametersFeatures VkPhysicalDeviceShaderDrawParameterFeatures;
+
+typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t* pApiVersion);
+typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos);
+typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeatures)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMask)(VkCommandBuffer commandBuffer, uint32_t deviceMask);
+typedef void (VKAPI_PTR *PFN_vkCmdDispatchBase)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
+typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroups)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties);
+typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2)(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2)(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties);
+typedef void (VKAPI_PTR *PFN_vkTrimCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue2)(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversion)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion);
+typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversion)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplate)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate);
+typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplate)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplate)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFenceProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties);
+typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupport)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion(
+ uint32_t* pApiVersion);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindBufferMemoryInfo* pBindInfos);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindImageMemoryInfo* pBindInfos);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeatures(
+ VkDevice device,
+ uint32_t heapIndex,
+ uint32_t localDeviceIndex,
+ uint32_t remoteDeviceIndex,
+ VkPeerMemoryFeatureFlags* pPeerMemoryFeatures);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMask(
+ VkCommandBuffer commandBuffer,
+ uint32_t deviceMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBase(
+ VkCommandBuffer commandBuffer,
+ uint32_t baseGroupX,
+ uint32_t baseGroupY,
+ uint32_t baseGroupZ,
+ uint32_t groupCountX,
+ uint32_t groupCountY,
+ uint32_t groupCountZ);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups(
+ VkInstance instance,
+ uint32_t* pPhysicalDeviceGroupCount,
+ VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2(
+ VkDevice device,
+ const VkImageMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2(
+ VkDevice device,
+ const VkBufferMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2(
+ VkDevice device,
+ const VkImageSparseMemoryRequirementsInfo2* pInfo,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2* pSparseMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures2* pFeatures);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties2* pProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkFormatProperties2* pFormatProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
+ VkImageFormatProperties2* pImageFormatProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties2* pQueueFamilyProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties2* pMemoryProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo,
+ uint32_t* pPropertyCount,
+ VkSparseImageFormatProperties2* pProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkTrimCommandPool(
+ VkDevice device,
+ VkCommandPool commandPool,
+ VkCommandPoolTrimFlags flags);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue2(
+ VkDevice device,
+ const VkDeviceQueueInfo2* pQueueInfo,
+ VkQueue* pQueue);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion(
+ VkDevice device,
+ const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSamplerYcbcrConversion* pYcbcrConversion);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion(
+ VkDevice device,
+ VkSamplerYcbcrConversion ycbcrConversion,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplate(
+ VkDevice device,
+ const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplate(
+ VkDevice device,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplate(
+ VkDevice device,
+ VkDescriptorSet descriptorSet,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const void* pData);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
+ VkExternalBufferProperties* pExternalBufferProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFenceProperties(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
+ VkExternalFenceProperties* pExternalFenceProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphoreProperties(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
+ VkExternalSemaphoreProperties* pExternalSemaphoreProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport(
+ VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+ VkDescriptorSetLayoutSupport* pSupport);
+#endif
+
+
+#define VK_VERSION_1_2 1
+// Vulkan 1.2 version number
+#define VK_API_VERSION_1_2 VK_MAKE_API_VERSION(0, 1, 2, 0)// Patch version should always be set to 0
+
+#define VK_MAX_DRIVER_NAME_SIZE 256U
+#define VK_MAX_DRIVER_INFO_SIZE 256U
+
+typedef enum VkDriverId {
+ VK_DRIVER_ID_AMD_PROPRIETARY = 1,
+ VK_DRIVER_ID_AMD_OPEN_SOURCE = 2,
+ VK_DRIVER_ID_MESA_RADV = 3,
+ VK_DRIVER_ID_NVIDIA_PROPRIETARY = 4,
+ VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS = 5,
+ VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA = 6,
+ VK_DRIVER_ID_IMAGINATION_PROPRIETARY = 7,
+ VK_DRIVER_ID_QUALCOMM_PROPRIETARY = 8,
+ VK_DRIVER_ID_ARM_PROPRIETARY = 9,
+ VK_DRIVER_ID_GOOGLE_SWIFTSHADER = 10,
+ VK_DRIVER_ID_GGP_PROPRIETARY = 11,
+ VK_DRIVER_ID_BROADCOM_PROPRIETARY = 12,
+ VK_DRIVER_ID_MESA_LLVMPIPE = 13,
+ VK_DRIVER_ID_MOLTENVK = 14,
+ VK_DRIVER_ID_COREAVI_PROPRIETARY = 15,
+ VK_DRIVER_ID_JUICE_PROPRIETARY = 16,
+ VK_DRIVER_ID_VERISILICON_PROPRIETARY = 17,
+ VK_DRIVER_ID_MESA_TURNIP = 18,
+ VK_DRIVER_ID_MESA_V3DV = 19,
+ VK_DRIVER_ID_MESA_PANVK = 20,
+ VK_DRIVER_ID_SAMSUNG_PROPRIETARY = 21,
+ VK_DRIVER_ID_MESA_VENUS = 22,
+ VK_DRIVER_ID_MESA_DOZEN = 23,
+ VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY,
+ VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE,
+ VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV,
+ VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = VK_DRIVER_ID_NVIDIA_PROPRIETARY,
+ VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS,
+ VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA,
+ VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = VK_DRIVER_ID_IMAGINATION_PROPRIETARY,
+ VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
+ VK_DRIVER_ID_ARM_PROPRIETARY_KHR = VK_DRIVER_ID_ARM_PROPRIETARY,
+ VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = VK_DRIVER_ID_GOOGLE_SWIFTSHADER,
+ VK_DRIVER_ID_GGP_PROPRIETARY_KHR = VK_DRIVER_ID_GGP_PROPRIETARY,
+ VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY,
+ VK_DRIVER_ID_MAX_ENUM = 0x7FFFFFFF
+} VkDriverId;
+
+typedef enum VkShaderFloatControlsIndependence {
+ VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY = 0,
+ VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL = 1,
+ VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE = 2,
+ VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY,
+ VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL,
+ VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE,
+ VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM = 0x7FFFFFFF
+} VkShaderFloatControlsIndependence;
+
+typedef enum VkSamplerReductionMode {
+ VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE = 0,
+ VK_SAMPLER_REDUCTION_MODE_MIN = 1,
+ VK_SAMPLER_REDUCTION_MODE_MAX = 2,
+ VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE,
+ VK_SAMPLER_REDUCTION_MODE_MIN_EXT = VK_SAMPLER_REDUCTION_MODE_MIN,
+ VK_SAMPLER_REDUCTION_MODE_MAX_EXT = VK_SAMPLER_REDUCTION_MODE_MAX,
+ VK_SAMPLER_REDUCTION_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkSamplerReductionMode;
+
+typedef enum VkSemaphoreType {
+ VK_SEMAPHORE_TYPE_BINARY = 0,
+ VK_SEMAPHORE_TYPE_TIMELINE = 1,
+ VK_SEMAPHORE_TYPE_BINARY_KHR = VK_SEMAPHORE_TYPE_BINARY,
+ VK_SEMAPHORE_TYPE_TIMELINE_KHR = VK_SEMAPHORE_TYPE_TIMELINE,
+ VK_SEMAPHORE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkSemaphoreType;
+
+typedef enum VkResolveModeFlagBits {
+ VK_RESOLVE_MODE_NONE = 0,
+ VK_RESOLVE_MODE_SAMPLE_ZERO_BIT = 0x00000001,
+ VK_RESOLVE_MODE_AVERAGE_BIT = 0x00000002,
+ VK_RESOLVE_MODE_MIN_BIT = 0x00000004,
+ VK_RESOLVE_MODE_MAX_BIT = 0x00000008,
+ VK_RESOLVE_MODE_NONE_KHR = VK_RESOLVE_MODE_NONE,
+ VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
+ VK_RESOLVE_MODE_AVERAGE_BIT_KHR = VK_RESOLVE_MODE_AVERAGE_BIT,
+ VK_RESOLVE_MODE_MIN_BIT_KHR = VK_RESOLVE_MODE_MIN_BIT,
+ VK_RESOLVE_MODE_MAX_BIT_KHR = VK_RESOLVE_MODE_MAX_BIT,
+ VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkResolveModeFlagBits;
+typedef VkFlags VkResolveModeFlags;
+
+typedef enum VkDescriptorBindingFlagBits {
+ VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 0x00000001,
+ VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002,
+ VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004,
+ VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008,
+ VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
+ VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
+ VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,
+ VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,
+ VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorBindingFlagBits;
+typedef VkFlags VkDescriptorBindingFlags;
+
+typedef enum VkSemaphoreWaitFlagBits {
+ VK_SEMAPHORE_WAIT_ANY_BIT = 0x00000001,
+ VK_SEMAPHORE_WAIT_ANY_BIT_KHR = VK_SEMAPHORE_WAIT_ANY_BIT,
+ VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSemaphoreWaitFlagBits;
+typedef VkFlags VkSemaphoreWaitFlags;
+typedef struct VkPhysicalDeviceVulkan11Features {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 storageBuffer16BitAccess;
+ VkBool32 uniformAndStorageBuffer16BitAccess;
+ VkBool32 storagePushConstant16;
+ VkBool32 storageInputOutput16;
+ VkBool32 multiview;
+ VkBool32 multiviewGeometryShader;
+ VkBool32 multiviewTessellationShader;
+ VkBool32 variablePointersStorageBuffer;
+ VkBool32 variablePointers;
+ VkBool32 protectedMemory;
+ VkBool32 samplerYcbcrConversion;
+ VkBool32 shaderDrawParameters;
+} VkPhysicalDeviceVulkan11Features;
+
+typedef struct VkPhysicalDeviceVulkan11Properties {
+ VkStructureType sType;
+ void* pNext;
+ uint8_t deviceUUID[VK_UUID_SIZE];
+ uint8_t driverUUID[VK_UUID_SIZE];
+ uint8_t deviceLUID[VK_LUID_SIZE];
+ uint32_t deviceNodeMask;
+ VkBool32 deviceLUIDValid;
+ uint32_t subgroupSize;
+ VkShaderStageFlags subgroupSupportedStages;
+ VkSubgroupFeatureFlags subgroupSupportedOperations;
+ VkBool32 subgroupQuadOperationsInAllStages;
+ VkPointClippingBehavior pointClippingBehavior;
+ uint32_t maxMultiviewViewCount;
+ uint32_t maxMultiviewInstanceIndex;
+ VkBool32 protectedNoFault;
+ uint32_t maxPerSetDescriptors;
+ VkDeviceSize maxMemoryAllocationSize;
+} VkPhysicalDeviceVulkan11Properties;
+
+typedef struct VkPhysicalDeviceVulkan12Features {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 samplerMirrorClampToEdge;
+ VkBool32 drawIndirectCount;
+ VkBool32 storageBuffer8BitAccess;
+ VkBool32 uniformAndStorageBuffer8BitAccess;
+ VkBool32 storagePushConstant8;
+ VkBool32 shaderBufferInt64Atomics;
+ VkBool32 shaderSharedInt64Atomics;
+ VkBool32 shaderFloat16;
+ VkBool32 shaderInt8;
+ VkBool32 descriptorIndexing;
+ VkBool32 shaderInputAttachmentArrayDynamicIndexing;
+ VkBool32 shaderUniformTexelBufferArrayDynamicIndexing;
+ VkBool32 shaderStorageTexelBufferArrayDynamicIndexing;
+ VkBool32 shaderUniformBufferArrayNonUniformIndexing;
+ VkBool32 shaderSampledImageArrayNonUniformIndexing;
+ VkBool32 shaderStorageBufferArrayNonUniformIndexing;
+ VkBool32 shaderStorageImageArrayNonUniformIndexing;
+ VkBool32 shaderInputAttachmentArrayNonUniformIndexing;
+ VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing;
+ VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing;
+ VkBool32 descriptorBindingUniformBufferUpdateAfterBind;
+ VkBool32 descriptorBindingSampledImageUpdateAfterBind;
+ VkBool32 descriptorBindingStorageImageUpdateAfterBind;
+ VkBool32 descriptorBindingStorageBufferUpdateAfterBind;
+ VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind;
+ VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind;
+ VkBool32 descriptorBindingUpdateUnusedWhilePending;
+ VkBool32 descriptorBindingPartiallyBound;
+ VkBool32 descriptorBindingVariableDescriptorCount;
+ VkBool32 runtimeDescriptorArray;
+ VkBool32 samplerFilterMinmax;
+ VkBool32 scalarBlockLayout;
+ VkBool32 imagelessFramebuffer;
+ VkBool32 uniformBufferStandardLayout;
+ VkBool32 shaderSubgroupExtendedTypes;
+ VkBool32 separateDepthStencilLayouts;
+ VkBool32 hostQueryReset;
+ VkBool32 timelineSemaphore;
+ VkBool32 bufferDeviceAddress;
+ VkBool32 bufferDeviceAddressCaptureReplay;
+ VkBool32 bufferDeviceAddressMultiDevice;
+ VkBool32 vulkanMemoryModel;
+ VkBool32 vulkanMemoryModelDeviceScope;
+ VkBool32 vulkanMemoryModelAvailabilityVisibilityChains;
+ VkBool32 shaderOutputViewportIndex;
+ VkBool32 shaderOutputLayer;
+ VkBool32 subgroupBroadcastDynamicId;
+} VkPhysicalDeviceVulkan12Features;
+
+typedef struct VkConformanceVersion {
+ uint8_t major;
+ uint8_t minor;
+ uint8_t subminor;
+ uint8_t patch;
+} VkConformanceVersion;
+
+typedef struct VkPhysicalDeviceVulkan12Properties {
+ VkStructureType sType;
+ void* pNext;
+ VkDriverId driverID;
+ char driverName[VK_MAX_DRIVER_NAME_SIZE];
+ char driverInfo[VK_MAX_DRIVER_INFO_SIZE];
+ VkConformanceVersion conformanceVersion;
+ VkShaderFloatControlsIndependence denormBehaviorIndependence;
+ VkShaderFloatControlsIndependence roundingModeIndependence;
+ VkBool32 shaderSignedZeroInfNanPreserveFloat16;
+ VkBool32 shaderSignedZeroInfNanPreserveFloat32;
+ VkBool32 shaderSignedZeroInfNanPreserveFloat64;
+ VkBool32 shaderDenormPreserveFloat16;
+ VkBool32 shaderDenormPreserveFloat32;
+ VkBool32 shaderDenormPreserveFloat64;
+ VkBool32 shaderDenormFlushToZeroFloat16;
+ VkBool32 shaderDenormFlushToZeroFloat32;
+ VkBool32 shaderDenormFlushToZeroFloat64;
+ VkBool32 shaderRoundingModeRTEFloat16;
+ VkBool32 shaderRoundingModeRTEFloat32;
+ VkBool32 shaderRoundingModeRTEFloat64;
+ VkBool32 shaderRoundingModeRTZFloat16;
+ VkBool32 shaderRoundingModeRTZFloat32;
+ VkBool32 shaderRoundingModeRTZFloat64;
+ uint32_t maxUpdateAfterBindDescriptorsInAllPools;
+ VkBool32 shaderUniformBufferArrayNonUniformIndexingNative;
+ VkBool32 shaderSampledImageArrayNonUniformIndexingNative;
+ VkBool32 shaderStorageBufferArrayNonUniformIndexingNative;
+ VkBool32 shaderStorageImageArrayNonUniformIndexingNative;
+ VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative;
+ VkBool32 robustBufferAccessUpdateAfterBind;
+ VkBool32 quadDivergentImplicitLod;
+ uint32_t maxPerStageDescriptorUpdateAfterBindSamplers;
+ uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers;
+ uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers;
+ uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages;
+ uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages;
+ uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments;
+ uint32_t maxPerStageUpdateAfterBindResources;
+ uint32_t maxDescriptorSetUpdateAfterBindSamplers;
+ uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers;
+ uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
+ uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers;
+ uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
+ uint32_t maxDescriptorSetUpdateAfterBindSampledImages;
+ uint32_t maxDescriptorSetUpdateAfterBindStorageImages;
+ uint32_t maxDescriptorSetUpdateAfterBindInputAttachments;
+ VkResolveModeFlags supportedDepthResolveModes;
+ VkResolveModeFlags supportedStencilResolveModes;
+ VkBool32 independentResolveNone;
+ VkBool32 independentResolve;
+ VkBool32 filterMinmaxSingleComponentFormats;
+ VkBool32 filterMinmaxImageComponentMapping;
+ uint64_t maxTimelineSemaphoreValueDifference;
+ VkSampleCountFlags framebufferIntegerColorSampleCounts;
+} VkPhysicalDeviceVulkan12Properties;
+
+typedef struct VkImageFormatListCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t viewFormatCount;
+ const VkFormat* pViewFormats;
+} VkImageFormatListCreateInfo;
+
+typedef struct VkAttachmentDescription2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkAttachmentDescriptionFlags flags;
+ VkFormat format;
+ VkSampleCountFlagBits samples;
+ VkAttachmentLoadOp loadOp;
+ VkAttachmentStoreOp storeOp;
+ VkAttachmentLoadOp stencilLoadOp;
+ VkAttachmentStoreOp stencilStoreOp;
+ VkImageLayout initialLayout;
+ VkImageLayout finalLayout;
+} VkAttachmentDescription2;
+
+typedef struct VkAttachmentReference2 {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t attachment;
+ VkImageLayout layout;
+ VkImageAspectFlags aspectMask;
+} VkAttachmentReference2;
+
+typedef struct VkSubpassDescription2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkSubpassDescriptionFlags flags;
+ VkPipelineBindPoint pipelineBindPoint;
+ uint32_t viewMask;
+ uint32_t inputAttachmentCount;
+ const VkAttachmentReference2* pInputAttachments;
+ uint32_t colorAttachmentCount;
+ const VkAttachmentReference2* pColorAttachments;
+ const VkAttachmentReference2* pResolveAttachments;
+ const VkAttachmentReference2* pDepthStencilAttachment;
+ uint32_t preserveAttachmentCount;
+ const uint32_t* pPreserveAttachments;
+} VkSubpassDescription2;
+
+typedef struct VkSubpassDependency2 {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t srcSubpass;
+ uint32_t dstSubpass;
+ VkPipelineStageFlags srcStageMask;
+ VkPipelineStageFlags dstStageMask;
+ VkAccessFlags srcAccessMask;
+ VkAccessFlags dstAccessMask;
+ VkDependencyFlags dependencyFlags;
+ int32_t viewOffset;
+} VkSubpassDependency2;
+
+typedef struct VkRenderPassCreateInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkRenderPassCreateFlags flags;
+ uint32_t attachmentCount;
+ const VkAttachmentDescription2* pAttachments;
+ uint32_t subpassCount;
+ const VkSubpassDescription2* pSubpasses;
+ uint32_t dependencyCount;
+ const VkSubpassDependency2* pDependencies;
+ uint32_t correlatedViewMaskCount;
+ const uint32_t* pCorrelatedViewMasks;
+} VkRenderPassCreateInfo2;
+
+typedef struct VkSubpassBeginInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkSubpassContents contents;
+} VkSubpassBeginInfo;
+
+typedef struct VkSubpassEndInfo {
+ VkStructureType sType;
+ const void* pNext;
+} VkSubpassEndInfo;
+
+typedef struct VkPhysicalDevice8BitStorageFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 storageBuffer8BitAccess;
+ VkBool32 uniformAndStorageBuffer8BitAccess;
+ VkBool32 storagePushConstant8;
+} VkPhysicalDevice8BitStorageFeatures;
+
+typedef struct VkPhysicalDeviceDriverProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkDriverId driverID;
+ char driverName[VK_MAX_DRIVER_NAME_SIZE];
+ char driverInfo[VK_MAX_DRIVER_INFO_SIZE];
+ VkConformanceVersion conformanceVersion;
+} VkPhysicalDeviceDriverProperties;
+
+typedef struct VkPhysicalDeviceShaderAtomicInt64Features {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderBufferInt64Atomics;
+ VkBool32 shaderSharedInt64Atomics;
+} VkPhysicalDeviceShaderAtomicInt64Features;
+
+typedef struct VkPhysicalDeviceShaderFloat16Int8Features {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderFloat16;
+ VkBool32 shaderInt8;
+} VkPhysicalDeviceShaderFloat16Int8Features;
+
+typedef struct VkPhysicalDeviceFloatControlsProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkShaderFloatControlsIndependence denormBehaviorIndependence;
+ VkShaderFloatControlsIndependence roundingModeIndependence;
+ VkBool32 shaderSignedZeroInfNanPreserveFloat16;
+ VkBool32 shaderSignedZeroInfNanPreserveFloat32;
+ VkBool32 shaderSignedZeroInfNanPreserveFloat64;
+ VkBool32 shaderDenormPreserveFloat16;
+ VkBool32 shaderDenormPreserveFloat32;
+ VkBool32 shaderDenormPreserveFloat64;
+ VkBool32 shaderDenormFlushToZeroFloat16;
+ VkBool32 shaderDenormFlushToZeroFloat32;
+ VkBool32 shaderDenormFlushToZeroFloat64;
+ VkBool32 shaderRoundingModeRTEFloat16;
+ VkBool32 shaderRoundingModeRTEFloat32;
+ VkBool32 shaderRoundingModeRTEFloat64;
+ VkBool32 shaderRoundingModeRTZFloat16;
+ VkBool32 shaderRoundingModeRTZFloat32;
+ VkBool32 shaderRoundingModeRTZFloat64;
+} VkPhysicalDeviceFloatControlsProperties;
+
+typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t bindingCount;
+ const VkDescriptorBindingFlags* pBindingFlags;
+} VkDescriptorSetLayoutBindingFlagsCreateInfo;
+
+typedef struct VkPhysicalDeviceDescriptorIndexingFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderInputAttachmentArrayDynamicIndexing;
+ VkBool32 shaderUniformTexelBufferArrayDynamicIndexing;
+ VkBool32 shaderStorageTexelBufferArrayDynamicIndexing;
+ VkBool32 shaderUniformBufferArrayNonUniformIndexing;
+ VkBool32 shaderSampledImageArrayNonUniformIndexing;
+ VkBool32 shaderStorageBufferArrayNonUniformIndexing;
+ VkBool32 shaderStorageImageArrayNonUniformIndexing;
+ VkBool32 shaderInputAttachmentArrayNonUniformIndexing;
+ VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing;
+ VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing;
+ VkBool32 descriptorBindingUniformBufferUpdateAfterBind;
+ VkBool32 descriptorBindingSampledImageUpdateAfterBind;
+ VkBool32 descriptorBindingStorageImageUpdateAfterBind;
+ VkBool32 descriptorBindingStorageBufferUpdateAfterBind;
+ VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind;
+ VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind;
+ VkBool32 descriptorBindingUpdateUnusedWhilePending;
+ VkBool32 descriptorBindingPartiallyBound;
+ VkBool32 descriptorBindingVariableDescriptorCount;
+ VkBool32 runtimeDescriptorArray;
+} VkPhysicalDeviceDescriptorIndexingFeatures;
+
+typedef struct VkPhysicalDeviceDescriptorIndexingProperties {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxUpdateAfterBindDescriptorsInAllPools;
+ VkBool32 shaderUniformBufferArrayNonUniformIndexingNative;
+ VkBool32 shaderSampledImageArrayNonUniformIndexingNative;
+ VkBool32 shaderStorageBufferArrayNonUniformIndexingNative;
+ VkBool32 shaderStorageImageArrayNonUniformIndexingNative;
+ VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative;
+ VkBool32 robustBufferAccessUpdateAfterBind;
+ VkBool32 quadDivergentImplicitLod;
+ uint32_t maxPerStageDescriptorUpdateAfterBindSamplers;
+ uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers;
+ uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers;
+ uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages;
+ uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages;
+ uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments;
+ uint32_t maxPerStageUpdateAfterBindResources;
+ uint32_t maxDescriptorSetUpdateAfterBindSamplers;
+ uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers;
+ uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic;
+ uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers;
+ uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic;
+ uint32_t maxDescriptorSetUpdateAfterBindSampledImages;
+ uint32_t maxDescriptorSetUpdateAfterBindStorageImages;
+ uint32_t maxDescriptorSetUpdateAfterBindInputAttachments;
+} VkPhysicalDeviceDescriptorIndexingProperties;
+
+typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t descriptorSetCount;
+ const uint32_t* pDescriptorCounts;
+} VkDescriptorSetVariableDescriptorCountAllocateInfo;
+
+typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupport {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxVariableDescriptorCount;
+} VkDescriptorSetVariableDescriptorCountLayoutSupport;
+
+typedef struct VkSubpassDescriptionDepthStencilResolve {
+ VkStructureType sType;
+ const void* pNext;
+ VkResolveModeFlagBits depthResolveMode;
+ VkResolveModeFlagBits stencilResolveMode;
+ const VkAttachmentReference2* pDepthStencilResolveAttachment;
+} VkSubpassDescriptionDepthStencilResolve;
+
+typedef struct VkPhysicalDeviceDepthStencilResolveProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkResolveModeFlags supportedDepthResolveModes;
+ VkResolveModeFlags supportedStencilResolveModes;
+ VkBool32 independentResolveNone;
+ VkBool32 independentResolve;
+} VkPhysicalDeviceDepthStencilResolveProperties;
+
+typedef struct VkPhysicalDeviceScalarBlockLayoutFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 scalarBlockLayout;
+} VkPhysicalDeviceScalarBlockLayoutFeatures;
+
+typedef struct VkImageStencilUsageCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageUsageFlags stencilUsage;
+} VkImageStencilUsageCreateInfo;
+
+typedef struct VkSamplerReductionModeCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkSamplerReductionMode reductionMode;
+} VkSamplerReductionModeCreateInfo;
+
+typedef struct VkPhysicalDeviceSamplerFilterMinmaxProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 filterMinmaxSingleComponentFormats;
+ VkBool32 filterMinmaxImageComponentMapping;
+} VkPhysicalDeviceSamplerFilterMinmaxProperties;
+
+typedef struct VkPhysicalDeviceVulkanMemoryModelFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 vulkanMemoryModel;
+ VkBool32 vulkanMemoryModelDeviceScope;
+ VkBool32 vulkanMemoryModelAvailabilityVisibilityChains;
+} VkPhysicalDeviceVulkanMemoryModelFeatures;
+
+typedef struct VkPhysicalDeviceImagelessFramebufferFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 imagelessFramebuffer;
+} VkPhysicalDeviceImagelessFramebufferFeatures;
+
+typedef struct VkFramebufferAttachmentImageInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageCreateFlags flags;
+ VkImageUsageFlags usage;
+ uint32_t width;
+ uint32_t height;
+ uint32_t layerCount;
+ uint32_t viewFormatCount;
+ const VkFormat* pViewFormats;
+} VkFramebufferAttachmentImageInfo;
+
+typedef struct VkFramebufferAttachmentsCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t attachmentImageInfoCount;
+ const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos;
+} VkFramebufferAttachmentsCreateInfo;
+
+typedef struct VkRenderPassAttachmentBeginInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t attachmentCount;
+ const VkImageView* pAttachments;
+} VkRenderPassAttachmentBeginInfo;
+
+typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 uniformBufferStandardLayout;
+} VkPhysicalDeviceUniformBufferStandardLayoutFeatures;
+
+typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderSubgroupExtendedTypes;
+} VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures;
+
+typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 separateDepthStencilLayouts;
+} VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures;
+
+typedef struct VkAttachmentReferenceStencilLayout {
+ VkStructureType sType;
+ void* pNext;
+ VkImageLayout stencilLayout;
+} VkAttachmentReferenceStencilLayout;
+
+typedef struct VkAttachmentDescriptionStencilLayout {
+ VkStructureType sType;
+ void* pNext;
+ VkImageLayout stencilInitialLayout;
+ VkImageLayout stencilFinalLayout;
+} VkAttachmentDescriptionStencilLayout;
+
+typedef struct VkPhysicalDeviceHostQueryResetFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 hostQueryReset;
+} VkPhysicalDeviceHostQueryResetFeatures;
+
+typedef struct VkPhysicalDeviceTimelineSemaphoreFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 timelineSemaphore;
+} VkPhysicalDeviceTimelineSemaphoreFeatures;
+
+typedef struct VkPhysicalDeviceTimelineSemaphoreProperties {
+ VkStructureType sType;
+ void* pNext;
+ uint64_t maxTimelineSemaphoreValueDifference;
+} VkPhysicalDeviceTimelineSemaphoreProperties;
+
+typedef struct VkSemaphoreTypeCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphoreType semaphoreType;
+ uint64_t initialValue;
+} VkSemaphoreTypeCreateInfo;
+
+typedef struct VkTimelineSemaphoreSubmitInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t waitSemaphoreValueCount;
+ const uint64_t* pWaitSemaphoreValues;
+ uint32_t signalSemaphoreValueCount;
+ const uint64_t* pSignalSemaphoreValues;
+} VkTimelineSemaphoreSubmitInfo;
+
+typedef struct VkSemaphoreWaitInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphoreWaitFlags flags;
+ uint32_t semaphoreCount;
+ const VkSemaphore* pSemaphores;
+ const uint64_t* pValues;
+} VkSemaphoreWaitInfo;
+
+typedef struct VkSemaphoreSignalInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphore semaphore;
+ uint64_t value;
+} VkSemaphoreSignalInfo;
+
+typedef struct VkPhysicalDeviceBufferDeviceAddressFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 bufferDeviceAddress;
+ VkBool32 bufferDeviceAddressCaptureReplay;
+ VkBool32 bufferDeviceAddressMultiDevice;
+} VkPhysicalDeviceBufferDeviceAddressFeatures;
+
+typedef struct VkBufferDeviceAddressInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkBuffer buffer;
+} VkBufferDeviceAddressInfo;
+
+typedef struct VkBufferOpaqueCaptureAddressCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint64_t opaqueCaptureAddress;
+} VkBufferOpaqueCaptureAddressCreateInfo;
+
+typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint64_t opaqueCaptureAddress;
+} VkMemoryOpaqueCaptureAddressAllocateInfo;
+
+typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceMemory memory;
+} VkDeviceMemoryOpaqueCaptureAddressInfo;
+
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo);
+typedef void (VKAPI_PTR *PFN_vkResetQueryPool)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
+typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValue)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue);
+typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphores)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout);
+typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphore)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo);
+typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddress)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCount(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCount(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2(
+ VkDevice device,
+ const VkRenderPassCreateInfo2* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkRenderPass* pRenderPass);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2(
+ VkCommandBuffer commandBuffer,
+ const VkRenderPassBeginInfo* pRenderPassBegin,
+ const VkSubpassBeginInfo* pSubpassBeginInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2(
+ VkCommandBuffer commandBuffer,
+ const VkSubpassBeginInfo* pSubpassBeginInfo,
+ const VkSubpassEndInfo* pSubpassEndInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2(
+ VkCommandBuffer commandBuffer,
+ const VkSubpassEndInfo* pSubpassEndInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkResetQueryPool(
+ VkDevice device,
+ VkQueryPool queryPool,
+ uint32_t firstQuery,
+ uint32_t queryCount);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValue(
+ VkDevice device,
+ VkSemaphore semaphore,
+ uint64_t* pValue);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphores(
+ VkDevice device,
+ const VkSemaphoreWaitInfo* pWaitInfo,
+ uint64_t timeout);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphore(
+ VkDevice device,
+ const VkSemaphoreSignalInfo* pSignalInfo);
+
+VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddress(
+ VkDevice device,
+ const VkBufferDeviceAddressInfo* pInfo);
+
+VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddress(
+ VkDevice device,
+ const VkBufferDeviceAddressInfo* pInfo);
+
+VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress(
+ VkDevice device,
+ const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
+#endif
+
+
+#define VK_VERSION_1_3 1
+// Vulkan 1.3 version number
+#define VK_API_VERSION_1_3 VK_MAKE_API_VERSION(0, 1, 3, 0)// Patch version should always be set to 0
+
+typedef uint64_t VkFlags64;
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlot)
+
+typedef enum VkPipelineCreationFeedbackFlagBits {
+ VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT = 0x00000001,
+ VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT = 0x00000002,
+ VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT = 0x00000004,
+ VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
+ VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT,
+ VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT,
+ VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineCreationFeedbackFlagBits;
+typedef VkFlags VkPipelineCreationFeedbackFlags;
+
+typedef enum VkToolPurposeFlagBits {
+ VK_TOOL_PURPOSE_VALIDATION_BIT = 0x00000001,
+ VK_TOOL_PURPOSE_PROFILING_BIT = 0x00000002,
+ VK_TOOL_PURPOSE_TRACING_BIT = 0x00000004,
+ VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT = 0x00000008,
+ VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT = 0x00000010,
+ VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020,
+ VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040,
+ VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = VK_TOOL_PURPOSE_VALIDATION_BIT,
+ VK_TOOL_PURPOSE_PROFILING_BIT_EXT = VK_TOOL_PURPOSE_PROFILING_BIT,
+ VK_TOOL_PURPOSE_TRACING_BIT_EXT = VK_TOOL_PURPOSE_TRACING_BIT,
+ VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT,
+ VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT,
+ VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkToolPurposeFlagBits;
+typedef VkFlags VkToolPurposeFlags;
+typedef VkFlags VkPrivateDataSlotCreateFlags;
+typedef VkFlags64 VkPipelineStageFlags2;
+
+// Flag bits for VkPipelineStageFlagBits2
+typedef VkFlags64 VkPipelineStageFlagBits2;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE = 0ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT = 0x00000001ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT = 0x00000002ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT = 0x00000004ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT = 0x00000008ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT = 0x00000040ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT = 0x00000080ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT = 0x00000100ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT = 0x00000200ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT = 0x00000800ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT = 0x00001000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT = 0x00001000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT = 0x00002000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT = 0x00004000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT = 0x00008000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT = 0x00010000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT = 0x100000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT = 0x200000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT = 0x400000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT = 0x800000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT = 0x1000000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT = 0x2000000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT = 0x4000000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL;
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR = 0x04000000ULL;
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR = 0x08000000ULL;
+#endif
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_EXT = 0x00080000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_EXT = 0x00100000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR = 0x10000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MICROMAP_BUILD_BIT_EXT = 0x40000000ULL;
+static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_OPTICAL_FLOW_BIT_NV = 0x20000000ULL;
+
+typedef VkFlags64 VkAccessFlags2;
+
+// Flag bits for VkAccessFlagBits2
+typedef VkFlags64 VkAccessFlagBits2;
+static const VkAccessFlagBits2 VK_ACCESS_2_NONE = 0ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_NONE_KHR = 0ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT = 0x00000001ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT = 0x00000002ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT = 0x00000008ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT = 0x00000010ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT = 0x00000020ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT = 0x00000040ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT = 0x00000080ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT = 0x00000800ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT = 0x00001000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT = 0x00002000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT = 0x00004000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT = 0x00008000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT = 0x00010000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT = 0x100000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT = 0x200000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT = 0x400000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL;
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR = 0x800000000ULL;
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR = 0x1000000000ULL;
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR = 0x2000000000ULL;
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR = 0x4000000000ULL;
+#endif
+static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_BINDING_TABLE_READ_BIT_KHR = 0x10000000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_MICROMAP_READ_BIT_EXT = 0x100000000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_MICROMAP_WRITE_BIT_EXT = 0x200000000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_OPTICAL_FLOW_READ_BIT_NV = 0x40000000000ULL;
+static const VkAccessFlagBits2 VK_ACCESS_2_OPTICAL_FLOW_WRITE_BIT_NV = 0x80000000000ULL;
+
+
+typedef enum VkSubmitFlagBits {
+ VK_SUBMIT_PROTECTED_BIT = 0x00000001,
+ VK_SUBMIT_PROTECTED_BIT_KHR = VK_SUBMIT_PROTECTED_BIT,
+ VK_SUBMIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkSubmitFlagBits;
+typedef VkFlags VkSubmitFlags;
+
+typedef enum VkRenderingFlagBits {
+ VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 0x00000001,
+ VK_RENDERING_SUSPENDING_BIT = 0x00000002,
+ VK_RENDERING_RESUMING_BIT = 0x00000004,
+ VK_RENDERING_ENABLE_LEGACY_DITHERING_BIT_EXT = 0x00000008,
+ VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT,
+ VK_RENDERING_SUSPENDING_BIT_KHR = VK_RENDERING_SUSPENDING_BIT,
+ VK_RENDERING_RESUMING_BIT_KHR = VK_RENDERING_RESUMING_BIT,
+ VK_RENDERING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
+} VkRenderingFlagBits;
+typedef VkFlags VkRenderingFlags;
+typedef VkFlags64 VkFormatFeatureFlags2;
+
+// Flag bits for VkFormatFeatureFlagBits2
+typedef VkFlags64 VkFormatFeatureFlagBits2;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT = 0x00000001ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR = 0x00000001ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT = 0x00000002ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR = 0x00000002ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR = 0x00000004ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT = 0x00000010ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000010ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR = 0x00000020ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT = 0x00000040ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR = 0x00000040ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT = 0x00000080ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR = 0x00000080ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR = 0x00000100ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 0x00000200ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT = 0x00000400ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR = 0x00000400ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT = 0x00000800ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR = 0x00000800ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR = 0x00001000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT = 0x00002000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT = 0x00004000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR = 0x00004000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT = 0x00008000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR = 0x00008000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR = 0x00010000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 0x00020000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 0x00040000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 0x00080000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 0x00100000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 0x00200000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT = 0x00400000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR = 0x00400000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT = 0x00800000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR = 0x00800000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT = 0x80000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR = 0x80000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT = 0x100000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR = 0x100000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT = 0x200000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR = 0x200000000ULL;
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000ULL;
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000ULL;
+#endif
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000ULL;
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000ULL;
+#endif
+#ifdef VK_ENABLE_BETA_EXTENSIONS
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000ULL;
+#endif
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV = 0x4000000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_WEIGHT_IMAGE_BIT_QCOM = 0x400000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_WEIGHT_SAMPLED_IMAGE_BIT_QCOM = 0x800000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM = 0x1000000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BOX_FILTER_SAMPLED_BIT_QCOM = 0x2000000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_OPTICAL_FLOW_IMAGE_BIT_NV = 0x10000000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_OPTICAL_FLOW_VECTOR_BIT_NV = 0x20000000000ULL;
+static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_OPTICAL_FLOW_COST_BIT_NV = 0x40000000000ULL;
+
+typedef struct VkPhysicalDeviceVulkan13Features {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 robustImageAccess;
+ VkBool32 inlineUniformBlock;
+ VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind;
+ VkBool32 pipelineCreationCacheControl;
+ VkBool32 privateData;
+ VkBool32 shaderDemoteToHelperInvocation;
+ VkBool32 shaderTerminateInvocation;
+ VkBool32 subgroupSizeControl;
+ VkBool32 computeFullSubgroups;
+ VkBool32 synchronization2;
+ VkBool32 textureCompressionASTC_HDR;
+ VkBool32 shaderZeroInitializeWorkgroupMemory;
+ VkBool32 dynamicRendering;
+ VkBool32 shaderIntegerDotProduct;
+ VkBool32 maintenance4;
+} VkPhysicalDeviceVulkan13Features;
+
+typedef struct VkPhysicalDeviceVulkan13Properties {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t minSubgroupSize;
+ uint32_t maxSubgroupSize;
+ uint32_t maxComputeWorkgroupSubgroups;
+ VkShaderStageFlags requiredSubgroupSizeStages;
+ uint32_t maxInlineUniformBlockSize;
+ uint32_t maxPerStageDescriptorInlineUniformBlocks;
+ uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks;
+ uint32_t maxDescriptorSetInlineUniformBlocks;
+ uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks;
+ uint32_t maxInlineUniformTotalSize;
+ VkBool32 integerDotProduct8BitUnsignedAccelerated;
+ VkBool32 integerDotProduct8BitSignedAccelerated;
+ VkBool32 integerDotProduct8BitMixedSignednessAccelerated;
+ VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated;
+ VkBool32 integerDotProduct4x8BitPackedSignedAccelerated;
+ VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated;
+ VkBool32 integerDotProduct16BitUnsignedAccelerated;
+ VkBool32 integerDotProduct16BitSignedAccelerated;
+ VkBool32 integerDotProduct16BitMixedSignednessAccelerated;
+ VkBool32 integerDotProduct32BitUnsignedAccelerated;
+ VkBool32 integerDotProduct32BitSignedAccelerated;
+ VkBool32 integerDotProduct32BitMixedSignednessAccelerated;
+ VkBool32 integerDotProduct64BitUnsignedAccelerated;
+ VkBool32 integerDotProduct64BitSignedAccelerated;
+ VkBool32 integerDotProduct64BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated;
+ VkDeviceSize storageTexelBufferOffsetAlignmentBytes;
+ VkBool32 storageTexelBufferOffsetSingleTexelAlignment;
+ VkDeviceSize uniformTexelBufferOffsetAlignmentBytes;
+ VkBool32 uniformTexelBufferOffsetSingleTexelAlignment;
+ VkDeviceSize maxBufferSize;
+} VkPhysicalDeviceVulkan13Properties;
+
+typedef struct VkPipelineCreationFeedback {
+ VkPipelineCreationFeedbackFlags flags;
+ uint64_t duration;
+} VkPipelineCreationFeedback;
+
+typedef struct VkPipelineCreationFeedbackCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCreationFeedback* pPipelineCreationFeedback;
+ uint32_t pipelineStageCreationFeedbackCount;
+ VkPipelineCreationFeedback* pPipelineStageCreationFeedbacks;
+} VkPipelineCreationFeedbackCreateInfo;
+
+typedef struct VkPhysicalDeviceShaderTerminateInvocationFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderTerminateInvocation;
+} VkPhysicalDeviceShaderTerminateInvocationFeatures;
+
+typedef struct VkPhysicalDeviceToolProperties {
+ VkStructureType sType;
+ void* pNext;
+ char name[VK_MAX_EXTENSION_NAME_SIZE];
+ char version[VK_MAX_EXTENSION_NAME_SIZE];
+ VkToolPurposeFlags purposes;
+ char description[VK_MAX_DESCRIPTION_SIZE];
+ char layer[VK_MAX_EXTENSION_NAME_SIZE];
+} VkPhysicalDeviceToolProperties;
+
+typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderDemoteToHelperInvocation;
+} VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures;
+
+typedef struct VkPhysicalDevicePrivateDataFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 privateData;
+} VkPhysicalDevicePrivateDataFeatures;
+
+typedef struct VkDevicePrivateDataCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t privateDataSlotRequestCount;
+} VkDevicePrivateDataCreateInfo;
+
+typedef struct VkPrivateDataSlotCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkPrivateDataSlotCreateFlags flags;
+} VkPrivateDataSlotCreateInfo;
+
+typedef struct VkPhysicalDevicePipelineCreationCacheControlFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 pipelineCreationCacheControl;
+} VkPhysicalDevicePipelineCreationCacheControlFeatures;
+
+typedef struct VkMemoryBarrier2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineStageFlags2 srcStageMask;
+ VkAccessFlags2 srcAccessMask;
+ VkPipelineStageFlags2 dstStageMask;
+ VkAccessFlags2 dstAccessMask;
+} VkMemoryBarrier2;
+
+typedef struct VkBufferMemoryBarrier2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineStageFlags2 srcStageMask;
+ VkAccessFlags2 srcAccessMask;
+ VkPipelineStageFlags2 dstStageMask;
+ VkAccessFlags2 dstAccessMask;
+ uint32_t srcQueueFamilyIndex;
+ uint32_t dstQueueFamilyIndex;
+ VkBuffer buffer;
+ VkDeviceSize offset;
+ VkDeviceSize size;
+} VkBufferMemoryBarrier2;
+
+typedef struct VkImageMemoryBarrier2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineStageFlags2 srcStageMask;
+ VkAccessFlags2 srcAccessMask;
+ VkPipelineStageFlags2 dstStageMask;
+ VkAccessFlags2 dstAccessMask;
+ VkImageLayout oldLayout;
+ VkImageLayout newLayout;
+ uint32_t srcQueueFamilyIndex;
+ uint32_t dstQueueFamilyIndex;
+ VkImage image;
+ VkImageSubresourceRange subresourceRange;
+} VkImageMemoryBarrier2;
+
+typedef struct VkDependencyInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkDependencyFlags dependencyFlags;
+ uint32_t memoryBarrierCount;
+ const VkMemoryBarrier2* pMemoryBarriers;
+ uint32_t bufferMemoryBarrierCount;
+ const VkBufferMemoryBarrier2* pBufferMemoryBarriers;
+ uint32_t imageMemoryBarrierCount;
+ const VkImageMemoryBarrier2* pImageMemoryBarriers;
+} VkDependencyInfo;
+
+typedef struct VkSemaphoreSubmitInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphore semaphore;
+ uint64_t value;
+ VkPipelineStageFlags2 stageMask;
+ uint32_t deviceIndex;
+} VkSemaphoreSubmitInfo;
+
+typedef struct VkCommandBufferSubmitInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkCommandBuffer commandBuffer;
+ uint32_t deviceMask;
+} VkCommandBufferSubmitInfo;
+
+typedef struct VkSubmitInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkSubmitFlags flags;
+ uint32_t waitSemaphoreInfoCount;
+ const VkSemaphoreSubmitInfo* pWaitSemaphoreInfos;
+ uint32_t commandBufferInfoCount;
+ const VkCommandBufferSubmitInfo* pCommandBufferInfos;
+ uint32_t signalSemaphoreInfoCount;
+ const VkSemaphoreSubmitInfo* pSignalSemaphoreInfos;
+} VkSubmitInfo2;
+
+typedef struct VkPhysicalDeviceSynchronization2Features {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 synchronization2;
+} VkPhysicalDeviceSynchronization2Features;
+
+typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderZeroInitializeWorkgroupMemory;
+} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures;
+
+typedef struct VkPhysicalDeviceImageRobustnessFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 robustImageAccess;
+} VkPhysicalDeviceImageRobustnessFeatures;
+
+typedef struct VkBufferCopy2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceSize srcOffset;
+ VkDeviceSize dstOffset;
+ VkDeviceSize size;
+} VkBufferCopy2;
+
+typedef struct VkCopyBufferInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkBuffer srcBuffer;
+ VkBuffer dstBuffer;
+ uint32_t regionCount;
+ const VkBufferCopy2* pRegions;
+} VkCopyBufferInfo2;
+
+typedef struct VkImageCopy2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageSubresourceLayers srcSubresource;
+ VkOffset3D srcOffset;
+ VkImageSubresourceLayers dstSubresource;
+ VkOffset3D dstOffset;
+ VkExtent3D extent;
+} VkImageCopy2;
+
+typedef struct VkCopyImageInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage srcImage;
+ VkImageLayout srcImageLayout;
+ VkImage dstImage;
+ VkImageLayout dstImageLayout;
+ uint32_t regionCount;
+ const VkImageCopy2* pRegions;
+} VkCopyImageInfo2;
+
+typedef struct VkBufferImageCopy2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceSize bufferOffset;
+ uint32_t bufferRowLength;
+ uint32_t bufferImageHeight;
+ VkImageSubresourceLayers imageSubresource;
+ VkOffset3D imageOffset;
+ VkExtent3D imageExtent;
+} VkBufferImageCopy2;
+
+typedef struct VkCopyBufferToImageInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkBuffer srcBuffer;
+ VkImage dstImage;
+ VkImageLayout dstImageLayout;
+ uint32_t regionCount;
+ const VkBufferImageCopy2* pRegions;
+} VkCopyBufferToImageInfo2;
+
+typedef struct VkCopyImageToBufferInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage srcImage;
+ VkImageLayout srcImageLayout;
+ VkBuffer dstBuffer;
+ uint32_t regionCount;
+ const VkBufferImageCopy2* pRegions;
+} VkCopyImageToBufferInfo2;
+
+typedef struct VkImageBlit2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageSubresourceLayers srcSubresource;
+ VkOffset3D srcOffsets[2];
+ VkImageSubresourceLayers dstSubresource;
+ VkOffset3D dstOffsets[2];
+} VkImageBlit2;
+
+typedef struct VkBlitImageInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage srcImage;
+ VkImageLayout srcImageLayout;
+ VkImage dstImage;
+ VkImageLayout dstImageLayout;
+ uint32_t regionCount;
+ const VkImageBlit2* pRegions;
+ VkFilter filter;
+} VkBlitImageInfo2;
+
+typedef struct VkImageResolve2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageSubresourceLayers srcSubresource;
+ VkOffset3D srcOffset;
+ VkImageSubresourceLayers dstSubresource;
+ VkOffset3D dstOffset;
+ VkExtent3D extent;
+} VkImageResolve2;
+
+typedef struct VkResolveImageInfo2 {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage srcImage;
+ VkImageLayout srcImageLayout;
+ VkImage dstImage;
+ VkImageLayout dstImageLayout;
+ uint32_t regionCount;
+ const VkImageResolve2* pRegions;
+} VkResolveImageInfo2;
+
+typedef struct VkPhysicalDeviceSubgroupSizeControlFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 subgroupSizeControl;
+ VkBool32 computeFullSubgroups;
+} VkPhysicalDeviceSubgroupSizeControlFeatures;
+
+typedef struct VkPhysicalDeviceSubgroupSizeControlProperties {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t minSubgroupSize;
+ uint32_t maxSubgroupSize;
+ uint32_t maxComputeWorkgroupSubgroups;
+ VkShaderStageFlags requiredSubgroupSizeStages;
+} VkPhysicalDeviceSubgroupSizeControlProperties;
+
+typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfo {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t requiredSubgroupSize;
+} VkPipelineShaderStageRequiredSubgroupSizeCreateInfo;
+
+typedef struct VkPhysicalDeviceInlineUniformBlockFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 inlineUniformBlock;
+ VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind;
+} VkPhysicalDeviceInlineUniformBlockFeatures;
+
+typedef struct VkPhysicalDeviceInlineUniformBlockProperties {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxInlineUniformBlockSize;
+ uint32_t maxPerStageDescriptorInlineUniformBlocks;
+ uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks;
+ uint32_t maxDescriptorSetInlineUniformBlocks;
+ uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks;
+} VkPhysicalDeviceInlineUniformBlockProperties;
+
+typedef struct VkWriteDescriptorSetInlineUniformBlock {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t dataSize;
+ const void* pData;
+} VkWriteDescriptorSetInlineUniformBlock;
+
+typedef struct VkDescriptorPoolInlineUniformBlockCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t maxInlineUniformBlockBindings;
+} VkDescriptorPoolInlineUniformBlockCreateInfo;
+
+typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 textureCompressionASTC_HDR;
+} VkPhysicalDeviceTextureCompressionASTCHDRFeatures;
+
+typedef struct VkRenderingAttachmentInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageView imageView;
+ VkImageLayout imageLayout;
+ VkResolveModeFlagBits resolveMode;
+ VkImageView resolveImageView;
+ VkImageLayout resolveImageLayout;
+ VkAttachmentLoadOp loadOp;
+ VkAttachmentStoreOp storeOp;
+ VkClearValue clearValue;
+} VkRenderingAttachmentInfo;
+
+typedef struct VkRenderingInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkRenderingFlags flags;
+ VkRect2D renderArea;
+ uint32_t layerCount;
+ uint32_t viewMask;
+ uint32_t colorAttachmentCount;
+ const VkRenderingAttachmentInfo* pColorAttachments;
+ const VkRenderingAttachmentInfo* pDepthAttachment;
+ const VkRenderingAttachmentInfo* pStencilAttachment;
+} VkRenderingInfo;
+
+typedef struct VkPipelineRenderingCreateInfo {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t viewMask;
+ uint32_t colorAttachmentCount;
+ const VkFormat* pColorAttachmentFormats;
+ VkFormat depthAttachmentFormat;
+ VkFormat stencilAttachmentFormat;
+} VkPipelineRenderingCreateInfo;
+
+typedef struct VkPhysicalDeviceDynamicRenderingFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 dynamicRendering;
+} VkPhysicalDeviceDynamicRenderingFeatures;
+
+typedef struct VkCommandBufferInheritanceRenderingInfo {
+ VkStructureType sType;
+ const void* pNext;
+ VkRenderingFlags flags;
+ uint32_t viewMask;
+ uint32_t colorAttachmentCount;
+ const VkFormat* pColorAttachmentFormats;
+ VkFormat depthAttachmentFormat;
+ VkFormat stencilAttachmentFormat;
+ VkSampleCountFlagBits rasterizationSamples;
+} VkCommandBufferInheritanceRenderingInfo;
+
+typedef struct VkPhysicalDeviceShaderIntegerDotProductFeatures {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderIntegerDotProduct;
+} VkPhysicalDeviceShaderIntegerDotProductFeatures;
+
+typedef struct VkPhysicalDeviceShaderIntegerDotProductProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 integerDotProduct8BitUnsignedAccelerated;
+ VkBool32 integerDotProduct8BitSignedAccelerated;
+ VkBool32 integerDotProduct8BitMixedSignednessAccelerated;
+ VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated;
+ VkBool32 integerDotProduct4x8BitPackedSignedAccelerated;
+ VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated;
+ VkBool32 integerDotProduct16BitUnsignedAccelerated;
+ VkBool32 integerDotProduct16BitSignedAccelerated;
+ VkBool32 integerDotProduct16BitMixedSignednessAccelerated;
+ VkBool32 integerDotProduct32BitUnsignedAccelerated;
+ VkBool32 integerDotProduct32BitSignedAccelerated;
+ VkBool32 integerDotProduct32BitMixedSignednessAccelerated;
+ VkBool32 integerDotProduct64BitUnsignedAccelerated;
+ VkBool32 integerDotProduct64BitSignedAccelerated;
+ VkBool32 integerDotProduct64BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated;
+} VkPhysicalDeviceShaderIntegerDotProductProperties;
+
+typedef struct VkPhysicalDeviceTexelBufferAlignmentProperties {
+ VkStructureType sType;
+ void* pNext;
+ VkDeviceSize storageTexelBufferOffsetAlignmentBytes;
+ VkBool32 storageTexelBufferOffsetSingleTexelAlignment;
+ VkDeviceSize uniformTexelBufferOffsetAlignmentBytes;
+ VkBool32 uniformTexelBufferOffsetSingleTexelAlignment;
+} VkPhysicalDeviceTexelBufferAlignmentProperties;
+
+typedef struct VkFormatProperties3 {
+ VkStructureType sType;
+ void* pNext;
+ VkFormatFeatureFlags2 linearTilingFeatures;
+ VkFormatFeatureFlags2 optimalTilingFeatures;
+ VkFormatFeatureFlags2 bufferFeatures;
+} VkFormatProperties3;
+
+typedef struct VkPhysicalDeviceMaintenance4Features {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 maintenance4;
+} VkPhysicalDeviceMaintenance4Features;
+
+typedef struct VkPhysicalDeviceMaintenance4Properties {
+ VkStructureType sType;
+ void* pNext;
+ VkDeviceSize maxBufferSize;
+} VkPhysicalDeviceMaintenance4Properties;
+
+typedef struct VkDeviceBufferMemoryRequirements {
+ VkStructureType sType;
+ const void* pNext;
+ const VkBufferCreateInfo* pCreateInfo;
+} VkDeviceBufferMemoryRequirements;
+
+typedef struct VkDeviceImageMemoryRequirements {
+ VkStructureType sType;
+ const void* pNext;
+ const VkImageCreateInfo* pCreateInfo;
+ VkImageAspectFlagBits planeAspect;
+} VkDeviceImageMemoryRequirements;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolProperties)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlot)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot);
+typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlot)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data);
+typedef void (VKAPI_PTR *PFN_vkGetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData);
+typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask);
+typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos);
+typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query);
+typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginRendering)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdEndRendering)(VkCommandBuffer commandBuffer);
+typedef void (VKAPI_PTR *PFN_vkCmdSetCullMode)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode);
+typedef void (VKAPI_PTR *PFN_vkCmdSetFrontFace)(VkCommandBuffer commandBuffer, VkFrontFace frontFace);
+typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveTopology)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology);
+typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWithCount)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport* pViewports);
+typedef void (VKAPI_PTR *PFN_vkCmdSetScissorWithCount)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors);
+typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers2)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthWriteEnable)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthCompareOp)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBoundsTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetStencilTestEnable)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOp)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp);
+typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizerDiscardEnable)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBiasEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnable)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirements)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolProperties(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pToolCount,
+ VkPhysicalDeviceToolProperties* pToolProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlot(
+ VkDevice device,
+ const VkPrivateDataSlotCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkPrivateDataSlot* pPrivateDataSlot);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlot(
+ VkDevice device,
+ VkPrivateDataSlot privateDataSlot,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateData(
+ VkDevice device,
+ VkObjectType objectType,
+ uint64_t objectHandle,
+ VkPrivateDataSlot privateDataSlot,
+ uint64_t data);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPrivateData(
+ VkDevice device,
+ VkObjectType objectType,
+ uint64_t objectHandle,
+ VkPrivateDataSlot privateDataSlot,
+ uint64_t* pData);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2(
+ VkCommandBuffer commandBuffer,
+ VkEvent event,
+ const VkDependencyInfo* pDependencyInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2(
+ VkCommandBuffer commandBuffer,
+ VkEvent event,
+ VkPipelineStageFlags2 stageMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2(
+ VkCommandBuffer commandBuffer,
+ uint32_t eventCount,
+ const VkEvent* pEvents,
+ const VkDependencyInfo* pDependencyInfos);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2(
+ VkCommandBuffer commandBuffer,
+ const VkDependencyInfo* pDependencyInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlags2 stage,
+ VkQueryPool queryPool,
+ uint32_t query);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2(
+ VkQueue queue,
+ uint32_t submitCount,
+ const VkSubmitInfo2* pSubmits,
+ VkFence fence);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2(
+ VkCommandBuffer commandBuffer,
+ const VkCopyBufferInfo2* pCopyBufferInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2(
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageInfo2* pCopyImageInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2(
+ VkCommandBuffer commandBuffer,
+ const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2(
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2(
+ VkCommandBuffer commandBuffer,
+ const VkBlitImageInfo2* pBlitImageInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2(
+ VkCommandBuffer commandBuffer,
+ const VkResolveImageInfo2* pResolveImageInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginRendering(
+ VkCommandBuffer commandBuffer,
+ const VkRenderingInfo* pRenderingInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndRendering(
+ VkCommandBuffer commandBuffer);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCullMode(
+ VkCommandBuffer commandBuffer,
+ VkCullModeFlags cullMode);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFace(
+ VkCommandBuffer commandBuffer,
+ VkFrontFace frontFace);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopology(
+ VkCommandBuffer commandBuffer,
+ VkPrimitiveTopology primitiveTopology);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCount(
+ VkCommandBuffer commandBuffer,
+ uint32_t viewportCount,
+ const VkViewport* pViewports);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCount(
+ VkCommandBuffer commandBuffer,
+ uint32_t scissorCount,
+ const VkRect2D* pScissors);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstBinding,
+ uint32_t bindingCount,
+ const VkBuffer* pBuffers,
+ const VkDeviceSize* pOffsets,
+ const VkDeviceSize* pSizes,
+ const VkDeviceSize* pStrides);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnable(
+ VkCommandBuffer commandBuffer,
+ VkBool32 depthTestEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnable(
+ VkCommandBuffer commandBuffer,
+ VkBool32 depthWriteEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOp(
+ VkCommandBuffer commandBuffer,
+ VkCompareOp depthCompareOp);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnable(
+ VkCommandBuffer commandBuffer,
+ VkBool32 depthBoundsTestEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnable(
+ VkCommandBuffer commandBuffer,
+ VkBool32 stencilTestEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOp(
+ VkCommandBuffer commandBuffer,
+ VkStencilFaceFlags faceMask,
+ VkStencilOp failOp,
+ VkStencilOp passOp,
+ VkStencilOp depthFailOp,
+ VkCompareOp compareOp);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnable(
+ VkCommandBuffer commandBuffer,
+ VkBool32 rasterizerDiscardEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnable(
+ VkCommandBuffer commandBuffer,
+ VkBool32 depthBiasEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnable(
+ VkCommandBuffer commandBuffer,
+ VkBool32 primitiveRestartEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirements(
+ VkDevice device,
+ const VkDeviceBufferMemoryRequirements* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirements(
+ VkDevice device,
+ const VkDeviceImageMemoryRequirements* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirements(
+ VkDevice device,
+ const VkDeviceImageMemoryRequirements* pInfo,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2* pSparseMemoryRequirements);
+#endif
+
+
+#define VK_KHR_surface 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
+#define VK_KHR_SURFACE_SPEC_VERSION 25
+#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface"
+
+typedef enum VkPresentModeKHR {
+ VK_PRESENT_MODE_IMMEDIATE_KHR = 0,
+ VK_PRESENT_MODE_MAILBOX_KHR = 1,
+ VK_PRESENT_MODE_FIFO_KHR = 2,
+ VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3,
+ VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000,
+ VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001,
+ VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkPresentModeKHR;
+
+typedef enum VkColorSpaceKHR {
+ VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0,
+ VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001,
+ VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT = 1000104002,
+ VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT = 1000104003,
+ VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104004,
+ VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104005,
+ VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006,
+ VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007,
+ VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008,
+ VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009,
+ VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010,
+ VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011,
+ VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012,
+ VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013,
+ VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014,
+ VK_COLOR_SPACE_DISPLAY_NATIVE_AMD = 1000213000,
+ VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
+ VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT,
+ VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkColorSpaceKHR;
+
+typedef enum VkSurfaceTransformFlagBitsKHR {
+ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001,
+ VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002,
+ VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004,
+ VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008,
+ VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010,
+ VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020,
+ VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040,
+ VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080,
+ VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100,
+ VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkSurfaceTransformFlagBitsKHR;
+
+typedef enum VkCompositeAlphaFlagBitsKHR {
+ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001,
+ VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002,
+ VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004,
+ VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008,
+ VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkCompositeAlphaFlagBitsKHR;
+typedef VkFlags VkCompositeAlphaFlagsKHR;
+typedef VkFlags VkSurfaceTransformFlagsKHR;
+typedef struct VkSurfaceCapabilitiesKHR {
+ uint32_t minImageCount;
+ uint32_t maxImageCount;
+ VkExtent2D currentExtent;
+ VkExtent2D minImageExtent;
+ VkExtent2D maxImageExtent;
+ uint32_t maxImageArrayLayers;
+ VkSurfaceTransformFlagsKHR supportedTransforms;
+ VkSurfaceTransformFlagBitsKHR currentTransform;
+ VkCompositeAlphaFlagsKHR supportedCompositeAlpha;
+ VkImageUsageFlags supportedUsageFlags;
+} VkSurfaceCapabilitiesKHR;
+
+typedef struct VkSurfaceFormatKHR {
+ VkFormat format;
+ VkColorSpaceKHR colorSpace;
+} VkSurfaceFormatKHR;
+
+typedef void (VKAPI_PTR *PFN_vkDestroySurfaceKHR)(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(
+ VkInstance instance,
+ VkSurfaceKHR surface,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ VkSurfaceKHR surface,
+ VkBool32* pSupported);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pSurfaceFormatCount,
+ VkSurfaceFormatKHR* pSurfaceFormats);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pPresentModeCount,
+ VkPresentModeKHR* pPresentModes);
+#endif
+
+
+#define VK_KHR_swapchain 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR)
+#define VK_KHR_SWAPCHAIN_SPEC_VERSION 70
+#define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain"
+
+typedef enum VkSwapchainCreateFlagBitsKHR {
+ VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000001,
+ VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 0x00000002,
+ VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR = 0x00000004,
+ VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkSwapchainCreateFlagBitsKHR;
+typedef VkFlags VkSwapchainCreateFlagsKHR;
+
+typedef enum VkDeviceGroupPresentModeFlagBitsKHR {
+ VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR = 0x00000001,
+ VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR = 0x00000002,
+ VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR = 0x00000004,
+ VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR = 0x00000008,
+ VK_DEVICE_GROUP_PRESENT_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkDeviceGroupPresentModeFlagBitsKHR;
+typedef VkFlags VkDeviceGroupPresentModeFlagsKHR;
+typedef struct VkSwapchainCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSwapchainCreateFlagsKHR flags;
+ VkSurfaceKHR surface;
+ uint32_t minImageCount;
+ VkFormat imageFormat;
+ VkColorSpaceKHR imageColorSpace;
+ VkExtent2D imageExtent;
+ uint32_t imageArrayLayers;
+ VkImageUsageFlags imageUsage;
+ VkSharingMode imageSharingMode;
+ uint32_t queueFamilyIndexCount;
+ const uint32_t* pQueueFamilyIndices;
+ VkSurfaceTransformFlagBitsKHR preTransform;
+ VkCompositeAlphaFlagBitsKHR compositeAlpha;
+ VkPresentModeKHR presentMode;
+ VkBool32 clipped;
+ VkSwapchainKHR oldSwapchain;
+} VkSwapchainCreateInfoKHR;
+
+typedef struct VkPresentInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t waitSemaphoreCount;
+ const VkSemaphore* pWaitSemaphores;
+ uint32_t swapchainCount;
+ const VkSwapchainKHR* pSwapchains;
+ const uint32_t* pImageIndices;
+ VkResult* pResults;
+} VkPresentInfoKHR;
+
+typedef struct VkImageSwapchainCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSwapchainKHR swapchain;
+} VkImageSwapchainCreateInfoKHR;
+
+typedef struct VkBindImageMemorySwapchainInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSwapchainKHR swapchain;
+ uint32_t imageIndex;
+} VkBindImageMemorySwapchainInfoKHR;
+
+typedef struct VkAcquireNextImageInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSwapchainKHR swapchain;
+ uint64_t timeout;
+ VkSemaphore semaphore;
+ VkFence fence;
+ uint32_t deviceMask;
+} VkAcquireNextImageInfoKHR;
+
+typedef struct VkDeviceGroupPresentCapabilitiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE];
+ VkDeviceGroupPresentModeFlagsKHR modes;
+} VkDeviceGroupPresentCapabilitiesKHR;
+
+typedef struct VkDeviceGroupPresentInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t swapchainCount;
+ const uint32_t* pDeviceMasks;
+ VkDeviceGroupPresentModeFlagBitsKHR mode;
+} VkDeviceGroupPresentInfoKHR;
+
+typedef struct VkDeviceGroupSwapchainCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceGroupPresentModeFlagsKHR modes;
+} VkDeviceGroupSwapchainCreateInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain);
+typedef void (VKAPI_PTR *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages);
+typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex);
+typedef VkResult (VKAPI_PTR *PFN_vkQueuePresentKHR)(VkQueue queue, const VkPresentInfoKHR* pPresentInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupPresentCapabilitiesKHR)(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModesKHR)(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR* pModes);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDevicePresentRectanglesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects);
+typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImage2KHR)(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR(
+ VkDevice device,
+ const VkSwapchainCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSwapchainKHR* pSwapchain);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint32_t* pSwapchainImageCount,
+ VkImage* pSwapchainImages);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint64_t timeout,
+ VkSemaphore semaphore,
+ VkFence fence,
+ uint32_t* pImageIndex);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(
+ VkQueue queue,
+ const VkPresentInfoKHR* pPresentInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupPresentCapabilitiesKHR(
+ VkDevice device,
+ VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHR(
+ VkDevice device,
+ VkSurfaceKHR surface,
+ VkDeviceGroupPresentModeFlagsKHR* pModes);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pRectCount,
+ VkRect2D* pRects);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHR(
+ VkDevice device,
+ const VkAcquireNextImageInfoKHR* pAcquireInfo,
+ uint32_t* pImageIndex);
+#endif
+
+
+#define VK_KHR_display 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayModeKHR)
+#define VK_KHR_DISPLAY_SPEC_VERSION 23
+#define VK_KHR_DISPLAY_EXTENSION_NAME "VK_KHR_display"
+typedef VkFlags VkDisplayModeCreateFlagsKHR;
+
+typedef enum VkDisplayPlaneAlphaFlagBitsKHR {
+ VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR = 0x00000001,
+ VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR = 0x00000002,
+ VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR = 0x00000004,
+ VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR = 0x00000008,
+ VK_DISPLAY_PLANE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkDisplayPlaneAlphaFlagBitsKHR;
+typedef VkFlags VkDisplayPlaneAlphaFlagsKHR;
+typedef VkFlags VkDisplaySurfaceCreateFlagsKHR;
+typedef struct VkDisplayModeParametersKHR {
+ VkExtent2D visibleRegion;
+ uint32_t refreshRate;
+} VkDisplayModeParametersKHR;
+
+typedef struct VkDisplayModeCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDisplayModeCreateFlagsKHR flags;
+ VkDisplayModeParametersKHR parameters;
+} VkDisplayModeCreateInfoKHR;
+
+typedef struct VkDisplayModePropertiesKHR {
+ VkDisplayModeKHR displayMode;
+ VkDisplayModeParametersKHR parameters;
+} VkDisplayModePropertiesKHR;
+
+typedef struct VkDisplayPlaneCapabilitiesKHR {
+ VkDisplayPlaneAlphaFlagsKHR supportedAlpha;
+ VkOffset2D minSrcPosition;
+ VkOffset2D maxSrcPosition;
+ VkExtent2D minSrcExtent;
+ VkExtent2D maxSrcExtent;
+ VkOffset2D minDstPosition;
+ VkOffset2D maxDstPosition;
+ VkExtent2D minDstExtent;
+ VkExtent2D maxDstExtent;
+} VkDisplayPlaneCapabilitiesKHR;
+
+typedef struct VkDisplayPlanePropertiesKHR {
+ VkDisplayKHR currentDisplay;
+ uint32_t currentStackIndex;
+} VkDisplayPlanePropertiesKHR;
+
+typedef struct VkDisplayPropertiesKHR {
+ VkDisplayKHR display;
+ const char* displayName;
+ VkExtent2D physicalDimensions;
+ VkExtent2D physicalResolution;
+ VkSurfaceTransformFlagsKHR supportedTransforms;
+ VkBool32 planeReorderPossible;
+ VkBool32 persistentContent;
+} VkDisplayPropertiesKHR;
+
+typedef struct VkDisplaySurfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDisplaySurfaceCreateFlagsKHR flags;
+ VkDisplayModeKHR displayMode;
+ uint32_t planeIndex;
+ uint32_t planeStackIndex;
+ VkSurfaceTransformFlagBitsKHR transform;
+ float globalAlpha;
+ VkDisplayPlaneAlphaFlagBitsKHR alphaMode;
+ VkExtent2D imageExtent;
+} VkDisplaySurfaceCreateInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlanePropertiesKHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneSupportedDisplaysKHR)(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModePropertiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayModeKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayPlaneSurfaceKHR)(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkDisplayPropertiesKHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkDisplayPlanePropertiesKHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t planeIndex,
+ uint32_t* pDisplayCount,
+ VkDisplayKHR* pDisplays);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display,
+ uint32_t* pPropertyCount,
+ VkDisplayModePropertiesKHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display,
+ const VkDisplayModeCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDisplayModeKHR* pMode);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayModeKHR mode,
+ uint32_t planeIndex,
+ VkDisplayPlaneCapabilitiesKHR* pCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR(
+ VkInstance instance,
+ const VkDisplaySurfaceCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+#endif
+
+
+#define VK_KHR_display_swapchain 1
+#define VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION 10
+#define VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME "VK_KHR_display_swapchain"
+typedef struct VkDisplayPresentInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkRect2D srcRect;
+ VkRect2D dstRect;
+ VkBool32 persistent;
+} VkDisplayPresentInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateSharedSwapchainsKHR)(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR(
+ VkDevice device,
+ uint32_t swapchainCount,
+ const VkSwapchainCreateInfoKHR* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkSwapchainKHR* pSwapchains);
+#endif
+
+
+#define VK_KHR_sampler_mirror_clamp_to_edge 1
+#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 3
+#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge"
+
+
+#define VK_KHR_dynamic_rendering 1
+#define VK_KHR_DYNAMIC_RENDERING_SPEC_VERSION 1
+#define VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME "VK_KHR_dynamic_rendering"
+typedef VkRenderingFlags VkRenderingFlagsKHR;
+
+typedef VkRenderingFlagBits VkRenderingFlagBitsKHR;
+
+typedef VkRenderingInfo VkRenderingInfoKHR;
+
+typedef VkRenderingAttachmentInfo VkRenderingAttachmentInfoKHR;
+
+typedef VkPipelineRenderingCreateInfo VkPipelineRenderingCreateInfoKHR;
+
+typedef VkPhysicalDeviceDynamicRenderingFeatures VkPhysicalDeviceDynamicRenderingFeaturesKHR;
+
+typedef VkCommandBufferInheritanceRenderingInfo VkCommandBufferInheritanceRenderingInfoKHR;
+
+typedef struct VkRenderingFragmentShadingRateAttachmentInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageView imageView;
+ VkImageLayout imageLayout;
+ VkExtent2D shadingRateAttachmentTexelSize;
+} VkRenderingFragmentShadingRateAttachmentInfoKHR;
+
+typedef struct VkRenderingFragmentDensityMapAttachmentInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageView imageView;
+ VkImageLayout imageLayout;
+} VkRenderingFragmentDensityMapAttachmentInfoEXT;
+
+typedef struct VkAttachmentSampleCountInfoAMD {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t colorAttachmentCount;
+ const VkSampleCountFlagBits* pColorAttachmentSamples;
+ VkSampleCountFlagBits depthStencilAttachmentSamples;
+} VkAttachmentSampleCountInfoAMD;
+
+typedef VkAttachmentSampleCountInfoAMD VkAttachmentSampleCountInfoNV;
+
+typedef struct VkMultiviewPerViewAttributesInfoNVX {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 perViewAttributes;
+ VkBool32 perViewAttributesPositionXOnly;
+} VkMultiviewPerViewAttributesInfoNVX;
+
+typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderingKHR)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdEndRenderingKHR)(VkCommandBuffer commandBuffer);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderingKHR(
+ VkCommandBuffer commandBuffer,
+ const VkRenderingInfo* pRenderingInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderingKHR(
+ VkCommandBuffer commandBuffer);
+#endif
+
+
+#define VK_KHR_multiview 1
+#define VK_KHR_MULTIVIEW_SPEC_VERSION 1
+#define VK_KHR_MULTIVIEW_EXTENSION_NAME "VK_KHR_multiview"
+typedef VkRenderPassMultiviewCreateInfo VkRenderPassMultiviewCreateInfoKHR;
+
+typedef VkPhysicalDeviceMultiviewFeatures VkPhysicalDeviceMultiviewFeaturesKHR;
+
+typedef VkPhysicalDeviceMultiviewProperties VkPhysicalDeviceMultiviewPropertiesKHR;
+
+
+
+#define VK_KHR_get_physical_device_properties2 1
+#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION 2
+#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_physical_device_properties2"
+typedef VkPhysicalDeviceFeatures2 VkPhysicalDeviceFeatures2KHR;
+
+typedef VkPhysicalDeviceProperties2 VkPhysicalDeviceProperties2KHR;
+
+typedef VkFormatProperties2 VkFormatProperties2KHR;
+
+typedef VkImageFormatProperties2 VkImageFormatProperties2KHR;
+
+typedef VkPhysicalDeviceImageFormatInfo2 VkPhysicalDeviceImageFormatInfo2KHR;
+
+typedef VkQueueFamilyProperties2 VkQueueFamilyProperties2KHR;
+
+typedef VkPhysicalDeviceMemoryProperties2 VkPhysicalDeviceMemoryProperties2KHR;
+
+typedef VkSparseImageFormatProperties2 VkSparseImageFormatProperties2KHR;
+
+typedef VkPhysicalDeviceSparseImageFormatInfo2 VkPhysicalDeviceSparseImageFormatInfo2KHR;
+
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2KHR)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures2* pFeatures);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties2* pProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkFormatProperties2* pFormatProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo,
+ VkImageFormatProperties2* pImageFormatProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties2* pQueueFamilyProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties2* pMemoryProperties);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo,
+ uint32_t* pPropertyCount,
+ VkSparseImageFormatProperties2* pProperties);
+#endif
+
+
+#define VK_KHR_device_group 1
+#define VK_KHR_DEVICE_GROUP_SPEC_VERSION 4
+#define VK_KHR_DEVICE_GROUP_EXTENSION_NAME "VK_KHR_device_group"
+typedef VkPeerMemoryFeatureFlags VkPeerMemoryFeatureFlagsKHR;
+
+typedef VkPeerMemoryFeatureFlagBits VkPeerMemoryFeatureFlagBitsKHR;
+
+typedef VkMemoryAllocateFlags VkMemoryAllocateFlagsKHR;
+
+typedef VkMemoryAllocateFlagBits VkMemoryAllocateFlagBitsKHR;
+
+typedef VkMemoryAllocateFlagsInfo VkMemoryAllocateFlagsInfoKHR;
+
+typedef VkDeviceGroupRenderPassBeginInfo VkDeviceGroupRenderPassBeginInfoKHR;
+
+typedef VkDeviceGroupCommandBufferBeginInfo VkDeviceGroupCommandBufferBeginInfoKHR;
+
+typedef VkDeviceGroupSubmitInfo VkDeviceGroupSubmitInfoKHR;
+
+typedef VkDeviceGroupBindSparseInfo VkDeviceGroupBindSparseInfoKHR;
+
+typedef VkBindBufferMemoryDeviceGroupInfo VkBindBufferMemoryDeviceGroupInfoKHR;
+
+typedef VkBindImageMemoryDeviceGroupInfo VkBindImageMemoryDeviceGroupInfoKHR;
+
+typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMaskKHR)(VkCommandBuffer commandBuffer, uint32_t deviceMask);
+typedef void (VKAPI_PTR *PFN_vkCmdDispatchBaseKHR)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeaturesKHR(
+ VkDevice device,
+ uint32_t heapIndex,
+ uint32_t localDeviceIndex,
+ uint32_t remoteDeviceIndex,
+ VkPeerMemoryFeatureFlags* pPeerMemoryFeatures);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMaskKHR(
+ VkCommandBuffer commandBuffer,
+ uint32_t deviceMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHR(
+ VkCommandBuffer commandBuffer,
+ uint32_t baseGroupX,
+ uint32_t baseGroupY,
+ uint32_t baseGroupZ,
+ uint32_t groupCountX,
+ uint32_t groupCountY,
+ uint32_t groupCountZ);
+#endif
+
+
+#define VK_KHR_shader_draw_parameters 1
+#define VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION 1
+#define VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME "VK_KHR_shader_draw_parameters"
+
+
+#define VK_KHR_maintenance1 1
+#define VK_KHR_MAINTENANCE_1_SPEC_VERSION 2
+#define VK_KHR_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_maintenance1"
+#define VK_KHR_MAINTENANCE1_SPEC_VERSION VK_KHR_MAINTENANCE_1_SPEC_VERSION
+#define VK_KHR_MAINTENANCE1_EXTENSION_NAME VK_KHR_MAINTENANCE_1_EXTENSION_NAME
+typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR;
+
+typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkTrimCommandPoolKHR(
+ VkDevice device,
+ VkCommandPool commandPool,
+ VkCommandPoolTrimFlags flags);
+#endif
+
+
+#define VK_KHR_device_group_creation 1
+#define VK_KHR_DEVICE_GROUP_CREATION_SPEC_VERSION 1
+#define VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME "VK_KHR_device_group_creation"
+#define VK_MAX_DEVICE_GROUP_SIZE_KHR VK_MAX_DEVICE_GROUP_SIZE
+typedef VkPhysicalDeviceGroupProperties VkPhysicalDeviceGroupPropertiesKHR;
+
+typedef VkDeviceGroupDeviceCreateInfo VkDeviceGroupDeviceCreateInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroupsKHR)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroupsKHR(
+ VkInstance instance,
+ uint32_t* pPhysicalDeviceGroupCount,
+ VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties);
+#endif
+
+
+#define VK_KHR_external_memory_capabilities 1
+#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_memory_capabilities"
+#define VK_LUID_SIZE_KHR VK_LUID_SIZE
+typedef VkExternalMemoryHandleTypeFlags VkExternalMemoryHandleTypeFlagsKHR;
+
+typedef VkExternalMemoryHandleTypeFlagBits VkExternalMemoryHandleTypeFlagBitsKHR;
+
+typedef VkExternalMemoryFeatureFlags VkExternalMemoryFeatureFlagsKHR;
+
+typedef VkExternalMemoryFeatureFlagBits VkExternalMemoryFeatureFlagBitsKHR;
+
+typedef VkExternalMemoryProperties VkExternalMemoryPropertiesKHR;
+
+typedef VkPhysicalDeviceExternalImageFormatInfo VkPhysicalDeviceExternalImageFormatInfoKHR;
+
+typedef VkExternalImageFormatProperties VkExternalImageFormatPropertiesKHR;
+
+typedef VkPhysicalDeviceExternalBufferInfo VkPhysicalDeviceExternalBufferInfoKHR;
+
+typedef VkExternalBufferProperties VkExternalBufferPropertiesKHR;
+
+typedef VkPhysicalDeviceIDProperties VkPhysicalDeviceIDPropertiesKHR;
+
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferPropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
+ VkExternalBufferProperties* pExternalBufferProperties);
+#endif
+
+
+#define VK_KHR_external_memory 1
+#define VK_KHR_EXTERNAL_MEMORY_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME "VK_KHR_external_memory"
+#define VK_QUEUE_FAMILY_EXTERNAL_KHR VK_QUEUE_FAMILY_EXTERNAL
+typedef VkExternalMemoryImageCreateInfo VkExternalMemoryImageCreateInfoKHR;
+
+typedef VkExternalMemoryBufferCreateInfo VkExternalMemoryBufferCreateInfoKHR;
+
+typedef VkExportMemoryAllocateInfo VkExportMemoryAllocateInfoKHR;
+
+
+
+#define VK_KHR_external_memory_fd 1
+#define VK_KHR_EXTERNAL_MEMORY_FD_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME "VK_KHR_external_memory_fd"
+typedef struct VkImportMemoryFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagBits handleType;
+ int fd;
+} VkImportMemoryFdInfoKHR;
+
+typedef struct VkMemoryFdPropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t memoryTypeBits;
+} VkMemoryFdPropertiesKHR;
+
+typedef struct VkMemoryGetFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceMemory memory;
+ VkExternalMemoryHandleTypeFlagBits handleType;
+} VkMemoryGetFdInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdKHR)(VkDevice device, const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd);
+typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdPropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, int fd, VkMemoryFdPropertiesKHR* pMemoryFdProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdKHR(
+ VkDevice device,
+ const VkMemoryGetFdInfoKHR* pGetFdInfo,
+ int* pFd);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdPropertiesKHR(
+ VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ int fd,
+ VkMemoryFdPropertiesKHR* pMemoryFdProperties);
+#endif
+
+
+#define VK_KHR_external_semaphore_capabilities 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_semaphore_capabilities"
+typedef VkExternalSemaphoreHandleTypeFlags VkExternalSemaphoreHandleTypeFlagsKHR;
+
+typedef VkExternalSemaphoreHandleTypeFlagBits VkExternalSemaphoreHandleTypeFlagBitsKHR;
+
+typedef VkExternalSemaphoreFeatureFlags VkExternalSemaphoreFeatureFlagsKHR;
+
+typedef VkExternalSemaphoreFeatureFlagBits VkExternalSemaphoreFeatureFlagBitsKHR;
+
+typedef VkPhysicalDeviceExternalSemaphoreInfo VkPhysicalDeviceExternalSemaphoreInfoKHR;
+
+typedef VkExternalSemaphoreProperties VkExternalSemaphorePropertiesKHR;
+
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo,
+ VkExternalSemaphoreProperties* pExternalSemaphoreProperties);
+#endif
+
+
+#define VK_KHR_external_semaphore 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_KHR_external_semaphore"
+typedef VkSemaphoreImportFlags VkSemaphoreImportFlagsKHR;
+
+typedef VkSemaphoreImportFlagBits VkSemaphoreImportFlagBitsKHR;
+
+typedef VkExportSemaphoreCreateInfo VkExportSemaphoreCreateInfoKHR;
+
+
+
+#define VK_KHR_external_semaphore_fd 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME "VK_KHR_external_semaphore_fd"
+typedef struct VkImportSemaphoreFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphore semaphore;
+ VkSemaphoreImportFlags flags;
+ VkExternalSemaphoreHandleTypeFlagBits handleType;
+ int fd;
+} VkImportSemaphoreFdInfoKHR;
+
+typedef struct VkSemaphoreGetFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSemaphore semaphore;
+ VkExternalSemaphoreHandleTypeFlagBits handleType;
+} VkSemaphoreGetFdInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreFdKHR)(VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreFdKHR)(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreFdKHR(
+ VkDevice device,
+ const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreFdKHR(
+ VkDevice device,
+ const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
+ int* pFd);
+#endif
+
+
+#define VK_KHR_push_descriptor 1
+#define VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION 2
+#define VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME "VK_KHR_push_descriptor"
+typedef struct VkPhysicalDevicePushDescriptorPropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxPushDescriptors;
+} VkPhysicalDevicePushDescriptorPropertiesKHR;
+
+typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetKHR)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites);
+typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplateKHR)(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkPipelineLayout layout, uint32_t set, const void* pData);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetKHR(
+ VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipelineLayout layout,
+ uint32_t set,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet* pDescriptorWrites);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR(
+ VkCommandBuffer commandBuffer,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ VkPipelineLayout layout,
+ uint32_t set,
+ const void* pData);
+#endif
+
+
+#define VK_KHR_shader_float16_int8 1
+#define VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION 1
+#define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8"
+typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceShaderFloat16Int8FeaturesKHR;
+
+typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceFloat16Int8FeaturesKHR;
+
+
+
+#define VK_KHR_16bit_storage 1
+#define VK_KHR_16BIT_STORAGE_SPEC_VERSION 1
+#define VK_KHR_16BIT_STORAGE_EXTENSION_NAME "VK_KHR_16bit_storage"
+typedef VkPhysicalDevice16BitStorageFeatures VkPhysicalDevice16BitStorageFeaturesKHR;
+
+
+
+#define VK_KHR_incremental_present 1
+#define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 2
+#define VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME "VK_KHR_incremental_present"
+typedef struct VkRectLayerKHR {
+ VkOffset2D offset;
+ VkExtent2D extent;
+ uint32_t layer;
+} VkRectLayerKHR;
+
+typedef struct VkPresentRegionKHR {
+ uint32_t rectangleCount;
+ const VkRectLayerKHR* pRectangles;
+} VkPresentRegionKHR;
+
+typedef struct VkPresentRegionsKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t swapchainCount;
+ const VkPresentRegionKHR* pRegions;
+} VkPresentRegionsKHR;
+
+
+
+#define VK_KHR_descriptor_update_template 1
+typedef VkDescriptorUpdateTemplate VkDescriptorUpdateTemplateKHR;
+
+#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION 1
+#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME "VK_KHR_descriptor_update_template"
+typedef VkDescriptorUpdateTemplateType VkDescriptorUpdateTemplateTypeKHR;
+
+typedef VkDescriptorUpdateTemplateCreateFlags VkDescriptorUpdateTemplateCreateFlagsKHR;
+
+typedef VkDescriptorUpdateTemplateEntry VkDescriptorUpdateTemplateEntryKHR;
+
+typedef VkDescriptorUpdateTemplateCreateInfo VkDescriptorUpdateTemplateCreateInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplateKHR)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate);
+typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplateKHR)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplateKHR)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplateKHR(
+ VkDevice device,
+ const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplateKHR(
+ VkDevice device,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR(
+ VkDevice device,
+ VkDescriptorSet descriptorSet,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const void* pData);
+#endif
+
+
+#define VK_KHR_imageless_framebuffer 1
+#define VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION 1
+#define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME "VK_KHR_imageless_framebuffer"
+typedef VkPhysicalDeviceImagelessFramebufferFeatures VkPhysicalDeviceImagelessFramebufferFeaturesKHR;
+
+typedef VkFramebufferAttachmentsCreateInfo VkFramebufferAttachmentsCreateInfoKHR;
+
+typedef VkFramebufferAttachmentImageInfo VkFramebufferAttachmentImageInfoKHR;
+
+typedef VkRenderPassAttachmentBeginInfo VkRenderPassAttachmentBeginInfoKHR;
+
+
+
+#define VK_KHR_create_renderpass2 1
+#define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1
+#define VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME "VK_KHR_create_renderpass2"
+typedef VkRenderPassCreateInfo2 VkRenderPassCreateInfo2KHR;
+
+typedef VkAttachmentDescription2 VkAttachmentDescription2KHR;
+
+typedef VkAttachmentReference2 VkAttachmentReference2KHR;
+
+typedef VkSubpassDescription2 VkSubpassDescription2KHR;
+
+typedef VkSubpassDependency2 VkSubpassDependency2KHR;
+
+typedef VkSubpassBeginInfo VkSubpassBeginInfoKHR;
+
+typedef VkSubpassEndInfo VkSubpassEndInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR(
+ VkDevice device,
+ const VkRenderPassCreateInfo2* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkRenderPass* pRenderPass);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkRenderPassBeginInfo* pRenderPassBegin,
+ const VkSubpassBeginInfo* pSubpassBeginInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkSubpassBeginInfo* pSubpassBeginInfo,
+ const VkSubpassEndInfo* pSubpassEndInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkSubpassEndInfo* pSubpassEndInfo);
+#endif
+
+
+#define VK_KHR_shared_presentable_image 1
+#define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1
+#define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image"
+typedef struct VkSharedPresentSurfaceCapabilitiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkImageUsageFlags sharedPresentSupportedUsageFlags;
+} VkSharedPresentSurfaceCapabilitiesKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainStatusKHR)(VkDevice device, VkSwapchainKHR swapchain);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainStatusKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain);
+#endif
+
+
+#define VK_KHR_external_fence_capabilities 1
+#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_fence_capabilities"
+typedef VkExternalFenceHandleTypeFlags VkExternalFenceHandleTypeFlagsKHR;
+
+typedef VkExternalFenceHandleTypeFlagBits VkExternalFenceHandleTypeFlagBitsKHR;
+
+typedef VkExternalFenceFeatureFlags VkExternalFenceFeatureFlagsKHR;
+
+typedef VkExternalFenceFeatureFlagBits VkExternalFenceFeatureFlagBitsKHR;
+
+typedef VkPhysicalDeviceExternalFenceInfo VkPhysicalDeviceExternalFenceInfoKHR;
+
+typedef VkExternalFenceProperties VkExternalFencePropertiesKHR;
+
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFencePropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo,
+ VkExternalFenceProperties* pExternalFenceProperties);
+#endif
+
+
+#define VK_KHR_external_fence 1
+#define VK_KHR_EXTERNAL_FENCE_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME "VK_KHR_external_fence"
+typedef VkFenceImportFlags VkFenceImportFlagsKHR;
+
+typedef VkFenceImportFlagBits VkFenceImportFlagBitsKHR;
+
+typedef VkExportFenceCreateInfo VkExportFenceCreateInfoKHR;
+
+
+
+#define VK_KHR_external_fence_fd 1
+#define VK_KHR_EXTERNAL_FENCE_FD_SPEC_VERSION 1
+#define VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME "VK_KHR_external_fence_fd"
+typedef struct VkImportFenceFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkFence fence;
+ VkFenceImportFlags flags;
+ VkExternalFenceHandleTypeFlagBits handleType;
+ int fd;
+} VkImportFenceFdInfoKHR;
+
+typedef struct VkFenceGetFdInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkFence fence;
+ VkExternalFenceHandleTypeFlagBits handleType;
+} VkFenceGetFdInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkImportFenceFdKHR)(VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkGetFenceFdKHR)(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceFdKHR(
+ VkDevice device,
+ const VkImportFenceFdInfoKHR* pImportFenceFdInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceFdKHR(
+ VkDevice device,
+ const VkFenceGetFdInfoKHR* pGetFdInfo,
+ int* pFd);
+#endif
+
+
+#define VK_KHR_performance_query 1
+#define VK_KHR_PERFORMANCE_QUERY_SPEC_VERSION 1
+#define VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME "VK_KHR_performance_query"
+
+typedef enum VkPerformanceCounterUnitKHR {
+ VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR = 0,
+ VK_PERFORMANCE_COUNTER_UNIT_PERCENTAGE_KHR = 1,
+ VK_PERFORMANCE_COUNTER_UNIT_NANOSECONDS_KHR = 2,
+ VK_PERFORMANCE_COUNTER_UNIT_BYTES_KHR = 3,
+ VK_PERFORMANCE_COUNTER_UNIT_BYTES_PER_SECOND_KHR = 4,
+ VK_PERFORMANCE_COUNTER_UNIT_KELVIN_KHR = 5,
+ VK_PERFORMANCE_COUNTER_UNIT_WATTS_KHR = 6,
+ VK_PERFORMANCE_COUNTER_UNIT_VOLTS_KHR = 7,
+ VK_PERFORMANCE_COUNTER_UNIT_AMPS_KHR = 8,
+ VK_PERFORMANCE_COUNTER_UNIT_HERTZ_KHR = 9,
+ VK_PERFORMANCE_COUNTER_UNIT_CYCLES_KHR = 10,
+ VK_PERFORMANCE_COUNTER_UNIT_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkPerformanceCounterUnitKHR;
+
+typedef enum VkPerformanceCounterScopeKHR {
+ VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR = 0,
+ VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR = 1,
+ VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR = 2,
+ VK_QUERY_SCOPE_COMMAND_BUFFER_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR,
+ VK_QUERY_SCOPE_RENDER_PASS_KHR = VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR,
+ VK_QUERY_SCOPE_COMMAND_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR,
+ VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkPerformanceCounterScopeKHR;
+
+typedef enum VkPerformanceCounterStorageKHR {
+ VK_PERFORMANCE_COUNTER_STORAGE_INT32_KHR = 0,
+ VK_PERFORMANCE_COUNTER_STORAGE_INT64_KHR = 1,
+ VK_PERFORMANCE_COUNTER_STORAGE_UINT32_KHR = 2,
+ VK_PERFORMANCE_COUNTER_STORAGE_UINT64_KHR = 3,
+ VK_PERFORMANCE_COUNTER_STORAGE_FLOAT32_KHR = 4,
+ VK_PERFORMANCE_COUNTER_STORAGE_FLOAT64_KHR = 5,
+ VK_PERFORMANCE_COUNTER_STORAGE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkPerformanceCounterStorageKHR;
+
+typedef enum VkPerformanceCounterDescriptionFlagBitsKHR {
+ VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_BIT_KHR = 0x00000001,
+ VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_BIT_KHR = 0x00000002,
+ VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_KHR = VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_BIT_KHR,
+ VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_KHR = VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_BIT_KHR,
+ VK_PERFORMANCE_COUNTER_DESCRIPTION_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkPerformanceCounterDescriptionFlagBitsKHR;
+typedef VkFlags VkPerformanceCounterDescriptionFlagsKHR;
+
+typedef enum VkAcquireProfilingLockFlagBitsKHR {
+ VK_ACQUIRE_PROFILING_LOCK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkAcquireProfilingLockFlagBitsKHR;
+typedef VkFlags VkAcquireProfilingLockFlagsKHR;
+typedef struct VkPhysicalDevicePerformanceQueryFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 performanceCounterQueryPools;
+ VkBool32 performanceCounterMultipleQueryPools;
+} VkPhysicalDevicePerformanceQueryFeaturesKHR;
+
+typedef struct VkPhysicalDevicePerformanceQueryPropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 allowCommandBufferQueryCopies;
+} VkPhysicalDevicePerformanceQueryPropertiesKHR;
+
+typedef struct VkPerformanceCounterKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkPerformanceCounterUnitKHR unit;
+ VkPerformanceCounterScopeKHR scope;
+ VkPerformanceCounterStorageKHR storage;
+ uint8_t uuid[VK_UUID_SIZE];
+} VkPerformanceCounterKHR;
+
+typedef struct VkPerformanceCounterDescriptionKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkPerformanceCounterDescriptionFlagsKHR flags;
+ char name[VK_MAX_DESCRIPTION_SIZE];
+ char category[VK_MAX_DESCRIPTION_SIZE];
+ char description[VK_MAX_DESCRIPTION_SIZE];
+} VkPerformanceCounterDescriptionKHR;
+
+typedef struct VkQueryPoolPerformanceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t queueFamilyIndex;
+ uint32_t counterIndexCount;
+ const uint32_t* pCounterIndices;
+} VkQueryPoolPerformanceCreateInfoKHR;
+
+typedef union VkPerformanceCounterResultKHR {
+ int32_t int32;
+ int64_t int64;
+ uint32_t uint32;
+ uint64_t uint64;
+ float float32;
+ double float64;
+} VkPerformanceCounterResultKHR;
+
+typedef struct VkAcquireProfilingLockInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkAcquireProfilingLockFlagsKHR flags;
+ uint64_t timeout;
+} VkAcquireProfilingLockInfoKHR;
+
+typedef struct VkPerformanceQuerySubmitInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t counterPassIndex;
+} VkPerformanceQuerySubmitInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t* pCounterCount, VkPerformanceCounterKHR* pCounters, VkPerformanceCounterDescriptionKHR* pCounterDescriptions);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR)(VkPhysicalDevice physicalDevice, const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo, uint32_t* pNumPasses);
+typedef VkResult (VKAPI_PTR *PFN_vkAcquireProfilingLockKHR)(VkDevice device, const VkAcquireProfilingLockInfoKHR* pInfo);
+typedef void (VKAPI_PTR *PFN_vkReleaseProfilingLockKHR)(VkDevice device);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ uint32_t* pCounterCount,
+ VkPerformanceCounterKHR* pCounters,
+ VkPerformanceCounterDescriptionKHR* pCounterDescriptions);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(
+ VkPhysicalDevice physicalDevice,
+ const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo,
+ uint32_t* pNumPasses);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireProfilingLockKHR(
+ VkDevice device,
+ const VkAcquireProfilingLockInfoKHR* pInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkReleaseProfilingLockKHR(
+ VkDevice device);
+#endif
+
+
+#define VK_KHR_maintenance2 1
+#define VK_KHR_MAINTENANCE_2_SPEC_VERSION 1
+#define VK_KHR_MAINTENANCE_2_EXTENSION_NAME "VK_KHR_maintenance2"
+#define VK_KHR_MAINTENANCE2_SPEC_VERSION VK_KHR_MAINTENANCE_2_SPEC_VERSION
+#define VK_KHR_MAINTENANCE2_EXTENSION_NAME VK_KHR_MAINTENANCE_2_EXTENSION_NAME
+typedef VkPointClippingBehavior VkPointClippingBehaviorKHR;
+
+typedef VkTessellationDomainOrigin VkTessellationDomainOriginKHR;
+
+typedef VkPhysicalDevicePointClippingProperties VkPhysicalDevicePointClippingPropertiesKHR;
+
+typedef VkRenderPassInputAttachmentAspectCreateInfo VkRenderPassInputAttachmentAspectCreateInfoKHR;
+
+typedef VkInputAttachmentAspectReference VkInputAttachmentAspectReferenceKHR;
+
+typedef VkImageViewUsageCreateInfo VkImageViewUsageCreateInfoKHR;
+
+typedef VkPipelineTessellationDomainOriginStateCreateInfo VkPipelineTessellationDomainOriginStateCreateInfoKHR;
+
+
+
+#define VK_KHR_get_surface_capabilities2 1
+#define VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION 1
+#define VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME "VK_KHR_get_surface_capabilities2"
+typedef struct VkPhysicalDeviceSurfaceInfo2KHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSurfaceKHR surface;
+} VkPhysicalDeviceSurfaceInfo2KHR;
+
+typedef struct VkSurfaceCapabilities2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkSurfaceCapabilitiesKHR surfaceCapabilities;
+} VkSurfaceCapabilities2KHR;
+
+typedef struct VkSurfaceFormat2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkSurfaceFormatKHR surfaceFormat;
+} VkSurfaceFormat2KHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ uint32_t* pSurfaceFormatCount,
+ VkSurfaceFormat2KHR* pSurfaceFormats);
+#endif
+
+
+#define VK_KHR_variable_pointers 1
+#define VK_KHR_VARIABLE_POINTERS_SPEC_VERSION 1
+#define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME "VK_KHR_variable_pointers"
+typedef VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointerFeaturesKHR;
+
+typedef VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointersFeaturesKHR;
+
+
+
+#define VK_KHR_get_display_properties2 1
+#define VK_KHR_GET_DISPLAY_PROPERTIES_2_SPEC_VERSION 1
+#define VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_display_properties2"
+typedef struct VkDisplayProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkDisplayPropertiesKHR displayProperties;
+} VkDisplayProperties2KHR;
+
+typedef struct VkDisplayPlaneProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkDisplayPlanePropertiesKHR displayPlaneProperties;
+} VkDisplayPlaneProperties2KHR;
+
+typedef struct VkDisplayModeProperties2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkDisplayModePropertiesKHR displayModeProperties;
+} VkDisplayModeProperties2KHR;
+
+typedef struct VkDisplayPlaneInfo2KHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDisplayModeKHR mode;
+ uint32_t planeIndex;
+} VkDisplayPlaneInfo2KHR;
+
+typedef struct VkDisplayPlaneCapabilities2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkDisplayPlaneCapabilitiesKHR capabilities;
+} VkDisplayPlaneCapabilities2KHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayProperties2KHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlaneProperties2KHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModeProperties2KHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModeProperties2KHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR* pCapabilities);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkDisplayProperties2KHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlaneProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkDisplayPlaneProperties2KHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModeProperties2KHR(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display,
+ uint32_t* pPropertyCount,
+ VkDisplayModeProperties2KHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilities2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo,
+ VkDisplayPlaneCapabilities2KHR* pCapabilities);
+#endif
+
+
+#define VK_KHR_dedicated_allocation 1
+#define VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION 3
+#define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_KHR_dedicated_allocation"
+typedef VkMemoryDedicatedRequirements VkMemoryDedicatedRequirementsKHR;
+
+typedef VkMemoryDedicatedAllocateInfo VkMemoryDedicatedAllocateInfoKHR;
+
+
+
+#define VK_KHR_storage_buffer_storage_class 1
+#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION 1
+#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME "VK_KHR_storage_buffer_storage_class"
+
+
+#define VK_KHR_relaxed_block_layout 1
+#define VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION 1
+#define VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME "VK_KHR_relaxed_block_layout"
+
+
+#define VK_KHR_get_memory_requirements2 1
+#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION 1
+#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME "VK_KHR_get_memory_requirements2"
+typedef VkBufferMemoryRequirementsInfo2 VkBufferMemoryRequirementsInfo2KHR;
+
+typedef VkImageMemoryRequirementsInfo2 VkImageMemoryRequirementsInfo2KHR;
+
+typedef VkImageSparseMemoryRequirementsInfo2 VkImageSparseMemoryRequirementsInfo2KHR;
+
+typedef VkMemoryRequirements2 VkMemoryRequirements2KHR;
+
+typedef VkSparseImageMemoryRequirements2 VkSparseImageMemoryRequirements2KHR;
+
+typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2KHR)(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2KHR)(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2KHR)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2KHR(
+ VkDevice device,
+ const VkImageMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2KHR(
+ VkDevice device,
+ const VkBufferMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2KHR(
+ VkDevice device,
+ const VkImageSparseMemoryRequirementsInfo2* pInfo,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2* pSparseMemoryRequirements);
+#endif
+
+
+#define VK_KHR_image_format_list 1
+#define VK_KHR_IMAGE_FORMAT_LIST_SPEC_VERSION 1
+#define VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME "VK_KHR_image_format_list"
+typedef VkImageFormatListCreateInfo VkImageFormatListCreateInfoKHR;
+
+
+
+#define VK_KHR_sampler_ycbcr_conversion 1
+typedef VkSamplerYcbcrConversion VkSamplerYcbcrConversionKHR;
+
+#define VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION 14
+#define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME "VK_KHR_sampler_ycbcr_conversion"
+typedef VkSamplerYcbcrModelConversion VkSamplerYcbcrModelConversionKHR;
+
+typedef VkSamplerYcbcrRange VkSamplerYcbcrRangeKHR;
+
+typedef VkChromaLocation VkChromaLocationKHR;
+
+typedef VkSamplerYcbcrConversionCreateInfo VkSamplerYcbcrConversionCreateInfoKHR;
+
+typedef VkSamplerYcbcrConversionInfo VkSamplerYcbcrConversionInfoKHR;
+
+typedef VkBindImagePlaneMemoryInfo VkBindImagePlaneMemoryInfoKHR;
+
+typedef VkImagePlaneMemoryRequirementsInfo VkImagePlaneMemoryRequirementsInfoKHR;
+
+typedef VkPhysicalDeviceSamplerYcbcrConversionFeatures VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR;
+
+typedef VkSamplerYcbcrConversionImageFormatProperties VkSamplerYcbcrConversionImageFormatPropertiesKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversionKHR)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion);
+typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversionKHR)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversionKHR(
+ VkDevice device,
+ const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSamplerYcbcrConversion* pYcbcrConversion);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversionKHR(
+ VkDevice device,
+ VkSamplerYcbcrConversion ycbcrConversion,
+ const VkAllocationCallbacks* pAllocator);
+#endif
+
+
+#define VK_KHR_bind_memory2 1
+#define VK_KHR_BIND_MEMORY_2_SPEC_VERSION 1
+#define VK_KHR_BIND_MEMORY_2_EXTENSION_NAME "VK_KHR_bind_memory2"
+typedef VkBindBufferMemoryInfo VkBindBufferMemoryInfoKHR;
+
+typedef VkBindImageMemoryInfo VkBindImageMemoryInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2KHR)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos);
+typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2KHR)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2KHR(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindBufferMemoryInfo* pBindInfos);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2KHR(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindImageMemoryInfo* pBindInfos);
+#endif
+
+
+#define VK_KHR_maintenance3 1
+#define VK_KHR_MAINTENANCE_3_SPEC_VERSION 1
+#define VK_KHR_MAINTENANCE_3_EXTENSION_NAME "VK_KHR_maintenance3"
+#define VK_KHR_MAINTENANCE3_SPEC_VERSION VK_KHR_MAINTENANCE_3_SPEC_VERSION
+#define VK_KHR_MAINTENANCE3_EXTENSION_NAME VK_KHR_MAINTENANCE_3_EXTENSION_NAME
+typedef VkPhysicalDeviceMaintenance3Properties VkPhysicalDeviceMaintenance3PropertiesKHR;
+
+typedef VkDescriptorSetLayoutSupport VkDescriptorSetLayoutSupportKHR;
+
+typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupportKHR)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupportKHR(
+ VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+ VkDescriptorSetLayoutSupport* pSupport);
+#endif
+
+
+#define VK_KHR_draw_indirect_count 1
+#define VK_KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION 1
+#define VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_KHR_draw_indirect_count"
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountKHR(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountKHR(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+#endif
+
+
+#define VK_KHR_shader_subgroup_extended_types 1
+#define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION 1
+#define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME "VK_KHR_shader_subgroup_extended_types"
+typedef VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR;
+
+
+
+#define VK_KHR_8bit_storage 1
+#define VK_KHR_8BIT_STORAGE_SPEC_VERSION 1
+#define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage"
+typedef VkPhysicalDevice8BitStorageFeatures VkPhysicalDevice8BitStorageFeaturesKHR;
+
+
+
+#define VK_KHR_shader_atomic_int64 1
+#define VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION 1
+#define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME "VK_KHR_shader_atomic_int64"
+typedef VkPhysicalDeviceShaderAtomicInt64Features VkPhysicalDeviceShaderAtomicInt64FeaturesKHR;
+
+
+
+#define VK_KHR_shader_clock 1
+#define VK_KHR_SHADER_CLOCK_SPEC_VERSION 1
+#define VK_KHR_SHADER_CLOCK_EXTENSION_NAME "VK_KHR_shader_clock"
+typedef struct VkPhysicalDeviceShaderClockFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderSubgroupClock;
+ VkBool32 shaderDeviceClock;
+} VkPhysicalDeviceShaderClockFeaturesKHR;
+
+
+
+#define VK_KHR_global_priority 1
+#define VK_MAX_GLOBAL_PRIORITY_SIZE_KHR 16U
+#define VK_KHR_GLOBAL_PRIORITY_SPEC_VERSION 1
+#define VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME "VK_KHR_global_priority"
+
+typedef enum VkQueueGlobalPriorityKHR {
+ VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR = 128,
+ VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR = 256,
+ VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR = 512,
+ VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR = 1024,
+ VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR,
+ VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR,
+ VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR,
+ VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR,
+ VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkQueueGlobalPriorityKHR;
+typedef struct VkDeviceQueueGlobalPriorityCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkQueueGlobalPriorityKHR globalPriority;
+} VkDeviceQueueGlobalPriorityCreateInfoKHR;
+
+typedef struct VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 globalPriorityQuery;
+} VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR;
+
+typedef struct VkQueueFamilyGlobalPriorityPropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t priorityCount;
+ VkQueueGlobalPriorityKHR priorities[VK_MAX_GLOBAL_PRIORITY_SIZE_KHR];
+} VkQueueFamilyGlobalPriorityPropertiesKHR;
+
+
+
+#define VK_KHR_driver_properties 1
+#define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1
+#define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties"
+#define VK_MAX_DRIVER_NAME_SIZE_KHR VK_MAX_DRIVER_NAME_SIZE
+#define VK_MAX_DRIVER_INFO_SIZE_KHR VK_MAX_DRIVER_INFO_SIZE
+typedef VkDriverId VkDriverIdKHR;
+
+typedef VkConformanceVersion VkConformanceVersionKHR;
+
+typedef VkPhysicalDeviceDriverProperties VkPhysicalDeviceDriverPropertiesKHR;
+
+
+
+#define VK_KHR_shader_float_controls 1
+#define VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION 4
+#define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME "VK_KHR_shader_float_controls"
+typedef VkShaderFloatControlsIndependence VkShaderFloatControlsIndependenceKHR;
+
+typedef VkPhysicalDeviceFloatControlsProperties VkPhysicalDeviceFloatControlsPropertiesKHR;
+
+
+
+#define VK_KHR_depth_stencil_resolve 1
+#define VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION 1
+#define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME "VK_KHR_depth_stencil_resolve"
+typedef VkResolveModeFlagBits VkResolveModeFlagBitsKHR;
+
+typedef VkResolveModeFlags VkResolveModeFlagsKHR;
+
+typedef VkSubpassDescriptionDepthStencilResolve VkSubpassDescriptionDepthStencilResolveKHR;
+
+typedef VkPhysicalDeviceDepthStencilResolveProperties VkPhysicalDeviceDepthStencilResolvePropertiesKHR;
+
+
+
+#define VK_KHR_swapchain_mutable_format 1
+#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION 1
+#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME "VK_KHR_swapchain_mutable_format"
+
+
+#define VK_KHR_timeline_semaphore 1
+#define VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION 2
+#define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME "VK_KHR_timeline_semaphore"
+typedef VkSemaphoreType VkSemaphoreTypeKHR;
+
+typedef VkSemaphoreWaitFlagBits VkSemaphoreWaitFlagBitsKHR;
+
+typedef VkSemaphoreWaitFlags VkSemaphoreWaitFlagsKHR;
+
+typedef VkPhysicalDeviceTimelineSemaphoreFeatures VkPhysicalDeviceTimelineSemaphoreFeaturesKHR;
+
+typedef VkPhysicalDeviceTimelineSemaphoreProperties VkPhysicalDeviceTimelineSemaphorePropertiesKHR;
+
+typedef VkSemaphoreTypeCreateInfo VkSemaphoreTypeCreateInfoKHR;
+
+typedef VkTimelineSemaphoreSubmitInfo VkTimelineSemaphoreSubmitInfoKHR;
+
+typedef VkSemaphoreWaitInfo VkSemaphoreWaitInfoKHR;
+
+typedef VkSemaphoreSignalInfo VkSemaphoreSignalInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValueKHR)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue);
+typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphoresKHR)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout);
+typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphoreKHR)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValueKHR(
+ VkDevice device,
+ VkSemaphore semaphore,
+ uint64_t* pValue);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphoresKHR(
+ VkDevice device,
+ const VkSemaphoreWaitInfo* pWaitInfo,
+ uint64_t timeout);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphoreKHR(
+ VkDevice device,
+ const VkSemaphoreSignalInfo* pSignalInfo);
+#endif
+
+
+#define VK_KHR_vulkan_memory_model 1
+#define VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION 3
+#define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model"
+typedef VkPhysicalDeviceVulkanMemoryModelFeatures VkPhysicalDeviceVulkanMemoryModelFeaturesKHR;
+
+
+
+#define VK_KHR_shader_terminate_invocation 1
+#define VK_KHR_SHADER_TERMINATE_INVOCATION_SPEC_VERSION 1
+#define VK_KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME "VK_KHR_shader_terminate_invocation"
+typedef VkPhysicalDeviceShaderTerminateInvocationFeatures VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR;
+
+
+
+#define VK_KHR_fragment_shading_rate 1
+#define VK_KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION 2
+#define VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME "VK_KHR_fragment_shading_rate"
+
+typedef enum VkFragmentShadingRateCombinerOpKHR {
+ VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR = 0,
+ VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR = 1,
+ VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR = 2,
+ VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR = 3,
+ VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR = 4,
+ VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkFragmentShadingRateCombinerOpKHR;
+typedef struct VkFragmentShadingRateAttachmentInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ const VkAttachmentReference2* pFragmentShadingRateAttachment;
+ VkExtent2D shadingRateAttachmentTexelSize;
+} VkFragmentShadingRateAttachmentInfoKHR;
+
+typedef struct VkPipelineFragmentShadingRateStateCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkExtent2D fragmentSize;
+ VkFragmentShadingRateCombinerOpKHR combinerOps[2];
+} VkPipelineFragmentShadingRateStateCreateInfoKHR;
+
+typedef struct VkPhysicalDeviceFragmentShadingRateFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 pipelineFragmentShadingRate;
+ VkBool32 primitiveFragmentShadingRate;
+ VkBool32 attachmentFragmentShadingRate;
+} VkPhysicalDeviceFragmentShadingRateFeaturesKHR;
+
+typedef struct VkPhysicalDeviceFragmentShadingRatePropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkExtent2D minFragmentShadingRateAttachmentTexelSize;
+ VkExtent2D maxFragmentShadingRateAttachmentTexelSize;
+ uint32_t maxFragmentShadingRateAttachmentTexelSizeAspectRatio;
+ VkBool32 primitiveFragmentShadingRateWithMultipleViewports;
+ VkBool32 layeredShadingRateAttachments;
+ VkBool32 fragmentShadingRateNonTrivialCombinerOps;
+ VkExtent2D maxFragmentSize;
+ uint32_t maxFragmentSizeAspectRatio;
+ uint32_t maxFragmentShadingRateCoverageSamples;
+ VkSampleCountFlagBits maxFragmentShadingRateRasterizationSamples;
+ VkBool32 fragmentShadingRateWithShaderDepthStencilWrites;
+ VkBool32 fragmentShadingRateWithSampleMask;
+ VkBool32 fragmentShadingRateWithShaderSampleMask;
+ VkBool32 fragmentShadingRateWithConservativeRasterization;
+ VkBool32 fragmentShadingRateWithFragmentShaderInterlock;
+ VkBool32 fragmentShadingRateWithCustomSampleLocations;
+ VkBool32 fragmentShadingRateStrictMultiplyCombiner;
+} VkPhysicalDeviceFragmentShadingRatePropertiesKHR;
+
+typedef struct VkPhysicalDeviceFragmentShadingRateKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkSampleCountFlags sampleCounts;
+ VkExtent2D fragmentSize;
+} VkPhysicalDeviceFragmentShadingRateKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pFragmentShadingRateCount, VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates);
+typedef void (VKAPI_PTR *PFN_vkCmdSetFragmentShadingRateKHR)(VkCommandBuffer commandBuffer, const VkExtent2D* pFragmentSize, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceFragmentShadingRatesKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pFragmentShadingRateCount,
+ VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetFragmentShadingRateKHR(
+ VkCommandBuffer commandBuffer,
+ const VkExtent2D* pFragmentSize,
+ const VkFragmentShadingRateCombinerOpKHR combinerOps[2]);
+#endif
+
+
+#define VK_KHR_spirv_1_4 1
+#define VK_KHR_SPIRV_1_4_SPEC_VERSION 1
+#define VK_KHR_SPIRV_1_4_EXTENSION_NAME "VK_KHR_spirv_1_4"
+
+
+#define VK_KHR_surface_protected_capabilities 1
+#define VK_KHR_SURFACE_PROTECTED_CAPABILITIES_SPEC_VERSION 1
+#define VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME "VK_KHR_surface_protected_capabilities"
+typedef struct VkSurfaceProtectedCapabilitiesKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 supportsProtected;
+} VkSurfaceProtectedCapabilitiesKHR;
+
+
+
+#define VK_KHR_separate_depth_stencil_layouts 1
+#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION 1
+#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME "VK_KHR_separate_depth_stencil_layouts"
+typedef VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR;
+
+typedef VkAttachmentReferenceStencilLayout VkAttachmentReferenceStencilLayoutKHR;
+
+typedef VkAttachmentDescriptionStencilLayout VkAttachmentDescriptionStencilLayoutKHR;
+
+
+
+#define VK_KHR_present_wait 1
+#define VK_KHR_PRESENT_WAIT_SPEC_VERSION 1
+#define VK_KHR_PRESENT_WAIT_EXTENSION_NAME "VK_KHR_present_wait"
+typedef struct VkPhysicalDevicePresentWaitFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 presentWait;
+} VkPhysicalDevicePresentWaitFeaturesKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkWaitForPresentKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t presentId, uint64_t timeout);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkWaitForPresentKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint64_t presentId,
+ uint64_t timeout);
+#endif
+
+
+#define VK_KHR_uniform_buffer_standard_layout 1
+#define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION 1
+#define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME "VK_KHR_uniform_buffer_standard_layout"
+typedef VkPhysicalDeviceUniformBufferStandardLayoutFeatures VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR;
+
+
+
+#define VK_KHR_buffer_device_address 1
+#define VK_KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 1
+#define VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_KHR_buffer_device_address"
+typedef VkPhysicalDeviceBufferDeviceAddressFeatures VkPhysicalDeviceBufferDeviceAddressFeaturesKHR;
+
+typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoKHR;
+
+typedef VkBufferOpaqueCaptureAddressCreateInfo VkBufferOpaqueCaptureAddressCreateInfoKHR;
+
+typedef VkMemoryOpaqueCaptureAddressAllocateInfo VkMemoryOpaqueCaptureAddressAllocateInfoKHR;
+
+typedef VkDeviceMemoryOpaqueCaptureAddressInfo VkDeviceMemoryOpaqueCaptureAddressInfoKHR;
+
+typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressKHR(
+ VkDevice device,
+ const VkBufferDeviceAddressInfo* pInfo);
+
+VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddressKHR(
+ VkDevice device,
+ const VkBufferDeviceAddressInfo* pInfo);
+
+VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddressKHR(
+ VkDevice device,
+ const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
+#endif
+
+
+#define VK_KHR_deferred_host_operations 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeferredOperationKHR)
+#define VK_KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION 4
+#define VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME "VK_KHR_deferred_host_operations"
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDeferredOperationKHR)(VkDevice device, const VkAllocationCallbacks* pAllocator, VkDeferredOperationKHR* pDeferredOperation);
+typedef void (VKAPI_PTR *PFN_vkDestroyDeferredOperationKHR)(VkDevice device, VkDeferredOperationKHR operation, const VkAllocationCallbacks* pAllocator);
+typedef uint32_t (VKAPI_PTR *PFN_vkGetDeferredOperationMaxConcurrencyKHR)(VkDevice device, VkDeferredOperationKHR operation);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDeferredOperationResultKHR)(VkDevice device, VkDeferredOperationKHR operation);
+typedef VkResult (VKAPI_PTR *PFN_vkDeferredOperationJoinKHR)(VkDevice device, VkDeferredOperationKHR operation);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDeferredOperationKHR(
+ VkDevice device,
+ const VkAllocationCallbacks* pAllocator,
+ VkDeferredOperationKHR* pDeferredOperation);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDeferredOperationKHR(
+ VkDevice device,
+ VkDeferredOperationKHR operation,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR uint32_t VKAPI_CALL vkGetDeferredOperationMaxConcurrencyKHR(
+ VkDevice device,
+ VkDeferredOperationKHR operation);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDeferredOperationResultKHR(
+ VkDevice device,
+ VkDeferredOperationKHR operation);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkDeferredOperationJoinKHR(
+ VkDevice device,
+ VkDeferredOperationKHR operation);
+#endif
+
+
+#define VK_KHR_pipeline_executable_properties 1
+#define VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_SPEC_VERSION 1
+#define VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME "VK_KHR_pipeline_executable_properties"
+
+typedef enum VkPipelineExecutableStatisticFormatKHR {
+ VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR = 0,
+ VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR = 1,
+ VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR = 2,
+ VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR = 3,
+ VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkPipelineExecutableStatisticFormatKHR;
+typedef struct VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 pipelineExecutableInfo;
+} VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR;
+
+typedef struct VkPipelineInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipeline pipeline;
+} VkPipelineInfoKHR;
+
+typedef struct VkPipelineExecutablePropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkShaderStageFlags stages;
+ char name[VK_MAX_DESCRIPTION_SIZE];
+ char description[VK_MAX_DESCRIPTION_SIZE];
+ uint32_t subgroupSize;
+} VkPipelineExecutablePropertiesKHR;
+
+typedef struct VkPipelineExecutableInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipeline pipeline;
+ uint32_t executableIndex;
+} VkPipelineExecutableInfoKHR;
+
+typedef union VkPipelineExecutableStatisticValueKHR {
+ VkBool32 b32;
+ int64_t i64;
+ uint64_t u64;
+ double f64;
+} VkPipelineExecutableStatisticValueKHR;
+
+typedef struct VkPipelineExecutableStatisticKHR {
+ VkStructureType sType;
+ void* pNext;
+ char name[VK_MAX_DESCRIPTION_SIZE];
+ char description[VK_MAX_DESCRIPTION_SIZE];
+ VkPipelineExecutableStatisticFormatKHR format;
+ VkPipelineExecutableStatisticValueKHR value;
+} VkPipelineExecutableStatisticKHR;
+
+typedef struct VkPipelineExecutableInternalRepresentationKHR {
+ VkStructureType sType;
+ void* pNext;
+ char name[VK_MAX_DESCRIPTION_SIZE];
+ char description[VK_MAX_DESCRIPTION_SIZE];
+ VkBool32 isText;
+ size_t dataSize;
+ void* pData;
+} VkPipelineExecutableInternalRepresentationKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutablePropertiesKHR)(VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, uint32_t* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutableStatisticsKHR)(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutableInternalRepresentationsKHR)(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutablePropertiesKHR(
+ VkDevice device,
+ const VkPipelineInfoKHR* pPipelineInfo,
+ uint32_t* pExecutableCount,
+ VkPipelineExecutablePropertiesKHR* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableStatisticsKHR(
+ VkDevice device,
+ const VkPipelineExecutableInfoKHR* pExecutableInfo,
+ uint32_t* pStatisticCount,
+ VkPipelineExecutableStatisticKHR* pStatistics);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR(
+ VkDevice device,
+ const VkPipelineExecutableInfoKHR* pExecutableInfo,
+ uint32_t* pInternalRepresentationCount,
+ VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations);
+#endif
+
+
+#define VK_KHR_shader_integer_dot_product 1
+#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION 1
+#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME "VK_KHR_shader_integer_dot_product"
+typedef VkPhysicalDeviceShaderIntegerDotProductFeatures VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR;
+
+typedef VkPhysicalDeviceShaderIntegerDotProductProperties VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR;
+
+
+
+#define VK_KHR_pipeline_library 1
+#define VK_KHR_PIPELINE_LIBRARY_SPEC_VERSION 1
+#define VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME "VK_KHR_pipeline_library"
+typedef struct VkPipelineLibraryCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t libraryCount;
+ const VkPipeline* pLibraries;
+} VkPipelineLibraryCreateInfoKHR;
+
+
+
+#define VK_KHR_shader_non_semantic_info 1
+#define VK_KHR_SHADER_NON_SEMANTIC_INFO_SPEC_VERSION 1
+#define VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME "VK_KHR_shader_non_semantic_info"
+
+
+#define VK_KHR_present_id 1
+#define VK_KHR_PRESENT_ID_SPEC_VERSION 1
+#define VK_KHR_PRESENT_ID_EXTENSION_NAME "VK_KHR_present_id"
+typedef struct VkPresentIdKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t swapchainCount;
+ const uint64_t* pPresentIds;
+} VkPresentIdKHR;
+
+typedef struct VkPhysicalDevicePresentIdFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 presentId;
+} VkPhysicalDevicePresentIdFeaturesKHR;
+
+
+
+#define VK_KHR_synchronization2 1
+#define VK_KHR_SYNCHRONIZATION_2_SPEC_VERSION 1
+#define VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME "VK_KHR_synchronization2"
+typedef VkPipelineStageFlags2 VkPipelineStageFlags2KHR;
+
+typedef VkPipelineStageFlagBits2 VkPipelineStageFlagBits2KHR;
+
+typedef VkAccessFlags2 VkAccessFlags2KHR;
+
+typedef VkAccessFlagBits2 VkAccessFlagBits2KHR;
+
+typedef VkSubmitFlagBits VkSubmitFlagBitsKHR;
+
+typedef VkSubmitFlags VkSubmitFlagsKHR;
+
+typedef VkMemoryBarrier2 VkMemoryBarrier2KHR;
+
+typedef VkBufferMemoryBarrier2 VkBufferMemoryBarrier2KHR;
+
+typedef VkImageMemoryBarrier2 VkImageMemoryBarrier2KHR;
+
+typedef VkDependencyInfo VkDependencyInfoKHR;
+
+typedef VkSubmitInfo2 VkSubmitInfo2KHR;
+
+typedef VkSemaphoreSubmitInfo VkSemaphoreSubmitInfoKHR;
+
+typedef VkCommandBufferSubmitInfo VkCommandBufferSubmitInfoKHR;
+
+typedef VkPhysicalDeviceSynchronization2Features VkPhysicalDeviceSynchronization2FeaturesKHR;
+
+typedef struct VkQueueFamilyCheckpointProperties2NV {
+ VkStructureType sType;
+ void* pNext;
+ VkPipelineStageFlags2 checkpointExecutionStageMask;
+} VkQueueFamilyCheckpointProperties2NV;
+
+typedef struct VkCheckpointData2NV {
+ VkStructureType sType;
+ void* pNext;
+ VkPipelineStageFlags2 stage;
+ void* pCheckpointMarker;
+} VkCheckpointData2NV;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask);
+typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2KHR)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos);
+typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2KHR)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2KHR)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query);
+typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence);
+typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker);
+typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointData2NV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointData2NV* pCheckpointData);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2KHR(
+ VkCommandBuffer commandBuffer,
+ VkEvent event,
+ const VkDependencyInfo* pDependencyInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2KHR(
+ VkCommandBuffer commandBuffer,
+ VkEvent event,
+ VkPipelineStageFlags2 stageMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2KHR(
+ VkCommandBuffer commandBuffer,
+ uint32_t eventCount,
+ const VkEvent* pEvents,
+ const VkDependencyInfo* pDependencyInfos);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkDependencyInfo* pDependencyInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2KHR(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlags2 stage,
+ VkQueryPool queryPool,
+ uint32_t query);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2KHR(
+ VkQueue queue,
+ uint32_t submitCount,
+ const VkSubmitInfo2* pSubmits,
+ VkFence fence);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarker2AMD(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlags2 stage,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ uint32_t marker);
+
+VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointData2NV(
+ VkQueue queue,
+ uint32_t* pCheckpointDataCount,
+ VkCheckpointData2NV* pCheckpointData);
+#endif
+
+
+#define VK_KHR_fragment_shader_barycentric 1
+#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1
+#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_KHR_fragment_shader_barycentric"
+typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 fragmentShaderBarycentric;
+} VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR;
+
+typedef struct VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 triStripVertexOrderIndependentOfProvokingVertex;
+} VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR;
+
+
+
+#define VK_KHR_shader_subgroup_uniform_control_flow 1
+#define VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_SPEC_VERSION 1
+#define VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_EXTENSION_NAME "VK_KHR_shader_subgroup_uniform_control_flow"
+typedef struct VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderSubgroupUniformControlFlow;
+} VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR;
+
+
+
+#define VK_KHR_zero_initialize_workgroup_memory 1
+#define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_SPEC_VERSION 1
+#define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_EXTENSION_NAME "VK_KHR_zero_initialize_workgroup_memory"
+typedef VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR;
+
+
+
+#define VK_KHR_workgroup_memory_explicit_layout 1
+#define VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_SPEC_VERSION 1
+#define VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME "VK_KHR_workgroup_memory_explicit_layout"
+typedef struct VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 workgroupMemoryExplicitLayout;
+ VkBool32 workgroupMemoryExplicitLayoutScalarBlockLayout;
+ VkBool32 workgroupMemoryExplicitLayout8BitAccess;
+ VkBool32 workgroupMemoryExplicitLayout16BitAccess;
+} VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR;
+
+
+
+#define VK_KHR_copy_commands2 1
+#define VK_KHR_COPY_COMMANDS_2_SPEC_VERSION 1
+#define VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME "VK_KHR_copy_commands2"
+typedef VkCopyBufferInfo2 VkCopyBufferInfo2KHR;
+
+typedef VkCopyImageInfo2 VkCopyImageInfo2KHR;
+
+typedef VkCopyBufferToImageInfo2 VkCopyBufferToImageInfo2KHR;
+
+typedef VkCopyImageToBufferInfo2 VkCopyImageToBufferInfo2KHR;
+
+typedef VkBlitImageInfo2 VkBlitImageInfo2KHR;
+
+typedef VkResolveImageInfo2 VkResolveImageInfo2KHR;
+
+typedef VkBufferCopy2 VkBufferCopy2KHR;
+
+typedef VkImageCopy2 VkImageCopy2KHR;
+
+typedef VkImageBlit2 VkImageBlit2KHR;
+
+typedef VkBufferImageCopy2 VkBufferImageCopy2KHR;
+
+typedef VkImageResolve2 VkImageResolve2KHR;
+
+typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2KHR)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2KHR)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkCopyBufferInfo2* pCopyBufferInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageInfo2* pCopyImageInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkBlitImageInfo2* pBlitImageInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2KHR(
+ VkCommandBuffer commandBuffer,
+ const VkResolveImageInfo2* pResolveImageInfo);
+#endif
+
+
+#define VK_KHR_format_feature_flags2 1
+#define VK_KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION 2
+#define VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME "VK_KHR_format_feature_flags2"
+typedef VkFormatFeatureFlags2 VkFormatFeatureFlags2KHR;
+
+typedef VkFormatFeatureFlagBits2 VkFormatFeatureFlagBits2KHR;
+
+typedef VkFormatProperties3 VkFormatProperties3KHR;
+
+
+
+#define VK_KHR_ray_tracing_maintenance1 1
+#define VK_KHR_RAY_TRACING_MAINTENANCE_1_SPEC_VERSION 1
+#define VK_KHR_RAY_TRACING_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_ray_tracing_maintenance1"
+typedef struct VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 rayTracingMaintenance1;
+ VkBool32 rayTracingPipelineTraceRaysIndirect2;
+} VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR;
+
+typedef struct VkTraceRaysIndirectCommand2KHR {
+ VkDeviceAddress raygenShaderRecordAddress;
+ VkDeviceSize raygenShaderRecordSize;
+ VkDeviceAddress missShaderBindingTableAddress;
+ VkDeviceSize missShaderBindingTableSize;
+ VkDeviceSize missShaderBindingTableStride;
+ VkDeviceAddress hitShaderBindingTableAddress;
+ VkDeviceSize hitShaderBindingTableSize;
+ VkDeviceSize hitShaderBindingTableStride;
+ VkDeviceAddress callableShaderBindingTableAddress;
+ VkDeviceSize callableShaderBindingTableSize;
+ VkDeviceSize callableShaderBindingTableStride;
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth;
+} VkTraceRaysIndirectCommand2KHR;
+
+typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysIndirect2KHR)(VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirect2KHR(
+ VkCommandBuffer commandBuffer,
+ VkDeviceAddress indirectDeviceAddress);
+#endif
+
+
+#define VK_KHR_portability_enumeration 1
+#define VK_KHR_PORTABILITY_ENUMERATION_SPEC_VERSION 1
+#define VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME "VK_KHR_portability_enumeration"
+
+
+#define VK_KHR_maintenance4 1
+#define VK_KHR_MAINTENANCE_4_SPEC_VERSION 2
+#define VK_KHR_MAINTENANCE_4_EXTENSION_NAME "VK_KHR_maintenance4"
+typedef VkPhysicalDeviceMaintenance4Features VkPhysicalDeviceMaintenance4FeaturesKHR;
+
+typedef VkPhysicalDeviceMaintenance4Properties VkPhysicalDeviceMaintenance4PropertiesKHR;
+
+typedef VkDeviceBufferMemoryRequirements VkDeviceBufferMemoryRequirementsKHR;
+
+typedef VkDeviceImageMemoryRequirements VkDeviceImageMemoryRequirementsKHR;
+
+typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirementsKHR)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirementsKHR(
+ VkDevice device,
+ const VkDeviceBufferMemoryRequirements* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirementsKHR(
+ VkDevice device,
+ const VkDeviceImageMemoryRequirements* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirementsKHR(
+ VkDevice device,
+ const VkDeviceImageMemoryRequirements* pInfo,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2* pSparseMemoryRequirements);
+#endif
+
+
+#define VK_EXT_debug_report 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
+#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 10
+#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report"
+
+typedef enum VkDebugReportObjectTypeEXT {
+ VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0,
+ VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3,
+ VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5,
+ VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6,
+ VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8,
+ VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9,
+ VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10,
+ VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11,
+ VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12,
+ VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13,
+ VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17,
+ VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18,
+ VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23,
+ VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24,
+ VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT = 28,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30,
+ VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000,
+ VK_DEBUG_REPORT_OBJECT_TYPE_CU_MODULE_NVX_EXT = 1000029000,
+ VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT = 1000029001,
+ VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT = 1000150000,
+ VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT = 1000165000,
+ VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT = 1000366000,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDebugReportObjectTypeEXT;
+
+typedef enum VkDebugReportFlagBitsEXT {
+ VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 0x00000001,
+ VK_DEBUG_REPORT_WARNING_BIT_EXT = 0x00000002,
+ VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 0x00000004,
+ VK_DEBUG_REPORT_ERROR_BIT_EXT = 0x00000008,
+ VK_DEBUG_REPORT_DEBUG_BIT_EXT = 0x00000010,
+ VK_DEBUG_REPORT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDebugReportFlagBitsEXT;
+typedef VkFlags VkDebugReportFlagsEXT;
+typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)(
+ VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objectType,
+ uint64_t object,
+ size_t location,
+ int32_t messageCode,
+ const char* pLayerPrefix,
+ const char* pMessage,
+ void* pUserData);
+
+typedef struct VkDebugReportCallbackCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDebugReportFlagsEXT flags;
+ PFN_vkDebugReportCallbackEXT pfnCallback;
+ void* pUserData;
+} VkDebugReportCallbackCreateInfoEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback);
+typedef void (VKAPI_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkDebugReportMessageEXT)(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(
+ VkInstance instance,
+ const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDebugReportCallbackEXT* pCallback);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(
+ VkInstance instance,
+ VkDebugReportCallbackEXT callback,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(
+ VkInstance instance,
+ VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objectType,
+ uint64_t object,
+ size_t location,
+ int32_t messageCode,
+ const char* pLayerPrefix,
+ const char* pMessage);
+#endif
+
+
+#define VK_NV_glsl_shader 1
+#define VK_NV_GLSL_SHADER_SPEC_VERSION 1
+#define VK_NV_GLSL_SHADER_EXTENSION_NAME "VK_NV_glsl_shader"
+
+
+#define VK_EXT_depth_range_unrestricted 1
+#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_SPEC_VERSION 1
+#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME "VK_EXT_depth_range_unrestricted"
+
+
+#define VK_IMG_filter_cubic 1
+#define VK_IMG_FILTER_CUBIC_SPEC_VERSION 1
+#define VK_IMG_FILTER_CUBIC_EXTENSION_NAME "VK_IMG_filter_cubic"
+
+
+#define VK_AMD_rasterization_order 1
+#define VK_AMD_RASTERIZATION_ORDER_SPEC_VERSION 1
+#define VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME "VK_AMD_rasterization_order"
+
+typedef enum VkRasterizationOrderAMD {
+ VK_RASTERIZATION_ORDER_STRICT_AMD = 0,
+ VK_RASTERIZATION_ORDER_RELAXED_AMD = 1,
+ VK_RASTERIZATION_ORDER_MAX_ENUM_AMD = 0x7FFFFFFF
+} VkRasterizationOrderAMD;
+typedef struct VkPipelineRasterizationStateRasterizationOrderAMD {
+ VkStructureType sType;
+ const void* pNext;
+ VkRasterizationOrderAMD rasterizationOrder;
+} VkPipelineRasterizationStateRasterizationOrderAMD;
+
+
+
+#define VK_AMD_shader_trinary_minmax 1
+#define VK_AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION 1
+#define VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME "VK_AMD_shader_trinary_minmax"
+
+
+#define VK_AMD_shader_explicit_vertex_parameter 1
+#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION 1
+#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME "VK_AMD_shader_explicit_vertex_parameter"
+
+
+#define VK_EXT_debug_marker 1
+#define VK_EXT_DEBUG_MARKER_SPEC_VERSION 4
+#define VK_EXT_DEBUG_MARKER_EXTENSION_NAME "VK_EXT_debug_marker"
+typedef struct VkDebugMarkerObjectNameInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDebugReportObjectTypeEXT objectType;
+ uint64_t object;
+ const char* pObjectName;
+} VkDebugMarkerObjectNameInfoEXT;
+
+typedef struct VkDebugMarkerObjectTagInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDebugReportObjectTypeEXT objectType;
+ uint64_t object;
+ uint64_t tagName;
+ size_t tagSize;
+ const void* pTag;
+} VkDebugMarkerObjectTagInfoEXT;
+
+typedef struct VkDebugMarkerMarkerInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ const char* pMarkerName;
+ float color[4];
+} VkDebugMarkerMarkerInfoEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectTagEXT)(VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectNameEXT)(VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerBeginEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerEndEXT)(VkCommandBuffer commandBuffer);
+typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerInsertEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectTagEXT(
+ VkDevice device,
+ const VkDebugMarkerObjectTagInfoEXT* pTagInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectNameEXT(
+ VkDevice device,
+ const VkDebugMarkerObjectNameInfoEXT* pNameInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerBeginEXT(
+ VkCommandBuffer commandBuffer,
+ const VkDebugMarkerMarkerInfoEXT* pMarkerInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerEndEXT(
+ VkCommandBuffer commandBuffer);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerInsertEXT(
+ VkCommandBuffer commandBuffer,
+ const VkDebugMarkerMarkerInfoEXT* pMarkerInfo);
+#endif
+
+
+#define VK_AMD_gcn_shader 1
+#define VK_AMD_GCN_SHADER_SPEC_VERSION 1
+#define VK_AMD_GCN_SHADER_EXTENSION_NAME "VK_AMD_gcn_shader"
+
+
+#define VK_NV_dedicated_allocation 1
+#define VK_NV_DEDICATED_ALLOCATION_SPEC_VERSION 1
+#define VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_NV_dedicated_allocation"
+typedef struct VkDedicatedAllocationImageCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 dedicatedAllocation;
+} VkDedicatedAllocationImageCreateInfoNV;
+
+typedef struct VkDedicatedAllocationBufferCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 dedicatedAllocation;
+} VkDedicatedAllocationBufferCreateInfoNV;
+
+typedef struct VkDedicatedAllocationMemoryAllocateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkImage image;
+ VkBuffer buffer;
+} VkDedicatedAllocationMemoryAllocateInfoNV;
+
+
+
+#define VK_EXT_transform_feedback 1
+#define VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION 1
+#define VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME "VK_EXT_transform_feedback"
+typedef VkFlags VkPipelineRasterizationStateStreamCreateFlagsEXT;
+typedef struct VkPhysicalDeviceTransformFeedbackFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 transformFeedback;
+ VkBool32 geometryStreams;
+} VkPhysicalDeviceTransformFeedbackFeaturesEXT;
+
+typedef struct VkPhysicalDeviceTransformFeedbackPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxTransformFeedbackStreams;
+ uint32_t maxTransformFeedbackBuffers;
+ VkDeviceSize maxTransformFeedbackBufferSize;
+ uint32_t maxTransformFeedbackStreamDataSize;
+ uint32_t maxTransformFeedbackBufferDataSize;
+ uint32_t maxTransformFeedbackBufferDataStride;
+ VkBool32 transformFeedbackQueries;
+ VkBool32 transformFeedbackStreamsLinesTriangles;
+ VkBool32 transformFeedbackRasterizationStreamSelect;
+ VkBool32 transformFeedbackDraw;
+} VkPhysicalDeviceTransformFeedbackPropertiesEXT;
+
+typedef struct VkPipelineRasterizationStateStreamCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineRasterizationStateStreamCreateFlagsEXT flags;
+ uint32_t rasterizationStream;
+} VkPipelineRasterizationStateStreamCreateInfoEXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdBindTransformFeedbackBuffersEXT)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginTransformFeedbackEXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets);
+typedef void (VKAPI_PTR *PFN_vkCmdEndTransformFeedbackEXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginQueryIndexedEXT)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags, uint32_t index);
+typedef void (VKAPI_PTR *PFN_vkCmdEndQueryIndexedEXT)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, uint32_t index);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectByteCountEXT)(VkCommandBuffer commandBuffer, uint32_t instanceCount, uint32_t firstInstance, VkBuffer counterBuffer, VkDeviceSize counterBufferOffset, uint32_t counterOffset, uint32_t vertexStride);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdBindTransformFeedbackBuffersEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstBinding,
+ uint32_t bindingCount,
+ const VkBuffer* pBuffers,
+ const VkDeviceSize* pOffsets,
+ const VkDeviceSize* pSizes);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginTransformFeedbackEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstCounterBuffer,
+ uint32_t counterBufferCount,
+ const VkBuffer* pCounterBuffers,
+ const VkDeviceSize* pCounterBufferOffsets);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndTransformFeedbackEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstCounterBuffer,
+ uint32_t counterBufferCount,
+ const VkBuffer* pCounterBuffers,
+ const VkDeviceSize* pCounterBufferOffsets);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginQueryIndexedEXT(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t query,
+ VkQueryControlFlags flags,
+ uint32_t index);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndQueryIndexedEXT(
+ VkCommandBuffer commandBuffer,
+ VkQueryPool queryPool,
+ uint32_t query,
+ uint32_t index);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectByteCountEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t instanceCount,
+ uint32_t firstInstance,
+ VkBuffer counterBuffer,
+ VkDeviceSize counterBufferOffset,
+ uint32_t counterOffset,
+ uint32_t vertexStride);
+#endif
+
+
+#define VK_NVX_binary_import 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuModuleNVX)
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuFunctionNVX)
+#define VK_NVX_BINARY_IMPORT_SPEC_VERSION 1
+#define VK_NVX_BINARY_IMPORT_EXTENSION_NAME "VK_NVX_binary_import"
+typedef struct VkCuModuleCreateInfoNVX {
+ VkStructureType sType;
+ const void* pNext;
+ size_t dataSize;
+ const void* pData;
+} VkCuModuleCreateInfoNVX;
+
+typedef struct VkCuFunctionCreateInfoNVX {
+ VkStructureType sType;
+ const void* pNext;
+ VkCuModuleNVX module;
+ const char* pName;
+} VkCuFunctionCreateInfoNVX;
+
+typedef struct VkCuLaunchInfoNVX {
+ VkStructureType sType;
+ const void* pNext;
+ VkCuFunctionNVX function;
+ uint32_t gridDimX;
+ uint32_t gridDimY;
+ uint32_t gridDimZ;
+ uint32_t blockDimX;
+ uint32_t blockDimY;
+ uint32_t blockDimZ;
+ uint32_t sharedMemBytes;
+ size_t paramCount;
+ const void* const * pParams;
+ size_t extraCount;
+ const void* const * pExtras;
+} VkCuLaunchInfoNVX;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateCuModuleNVX)(VkDevice device, const VkCuModuleCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCuModuleNVX* pModule);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateCuFunctionNVX)(VkDevice device, const VkCuFunctionCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCuFunctionNVX* pFunction);
+typedef void (VKAPI_PTR *PFN_vkDestroyCuModuleNVX)(VkDevice device, VkCuModuleNVX module, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkDestroyCuFunctionNVX)(VkDevice device, VkCuFunctionNVX function, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkCmdCuLaunchKernelNVX)(VkCommandBuffer commandBuffer, const VkCuLaunchInfoNVX* pLaunchInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateCuModuleNVX(
+ VkDevice device,
+ const VkCuModuleCreateInfoNVX* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkCuModuleNVX* pModule);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateCuFunctionNVX(
+ VkDevice device,
+ const VkCuFunctionCreateInfoNVX* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkCuFunctionNVX* pFunction);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyCuModuleNVX(
+ VkDevice device,
+ VkCuModuleNVX module,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyCuFunctionNVX(
+ VkDevice device,
+ VkCuFunctionNVX function,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCuLaunchKernelNVX(
+ VkCommandBuffer commandBuffer,
+ const VkCuLaunchInfoNVX* pLaunchInfo);
+#endif
+
+
+#define VK_NVX_image_view_handle 1
+#define VK_NVX_IMAGE_VIEW_HANDLE_SPEC_VERSION 2
+#define VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME "VK_NVX_image_view_handle"
+typedef struct VkImageViewHandleInfoNVX {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageView imageView;
+ VkDescriptorType descriptorType;
+ VkSampler sampler;
+} VkImageViewHandleInfoNVX;
+
+typedef struct VkImageViewAddressPropertiesNVX {
+ VkStructureType sType;
+ void* pNext;
+ VkDeviceAddress deviceAddress;
+ VkDeviceSize size;
+} VkImageViewAddressPropertiesNVX;
+
+typedef uint32_t (VKAPI_PTR *PFN_vkGetImageViewHandleNVX)(VkDevice device, const VkImageViewHandleInfoNVX* pInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkGetImageViewAddressNVX)(VkDevice device, VkImageView imageView, VkImageViewAddressPropertiesNVX* pProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR uint32_t VKAPI_CALL vkGetImageViewHandleNVX(
+ VkDevice device,
+ const VkImageViewHandleInfoNVX* pInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetImageViewAddressNVX(
+ VkDevice device,
+ VkImageView imageView,
+ VkImageViewAddressPropertiesNVX* pProperties);
+#endif
+
+
+#define VK_AMD_draw_indirect_count 1
+#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 2
+#define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count"
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountAMD(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+#endif
+
+
+#define VK_AMD_negative_viewport_height 1
+#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION 1
+#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME "VK_AMD_negative_viewport_height"
+
+
+#define VK_AMD_gpu_shader_half_float 1
+#define VK_AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION 2
+#define VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME "VK_AMD_gpu_shader_half_float"
+
+
+#define VK_AMD_shader_ballot 1
+#define VK_AMD_SHADER_BALLOT_SPEC_VERSION 1
+#define VK_AMD_SHADER_BALLOT_EXTENSION_NAME "VK_AMD_shader_ballot"
+
+
+#define VK_AMD_texture_gather_bias_lod 1
+#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_SPEC_VERSION 1
+#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_EXTENSION_NAME "VK_AMD_texture_gather_bias_lod"
+typedef struct VkTextureLODGatherFormatPropertiesAMD {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 supportsTextureGatherLODBiasAMD;
+} VkTextureLODGatherFormatPropertiesAMD;
+
+
+
+#define VK_AMD_shader_info 1
+#define VK_AMD_SHADER_INFO_SPEC_VERSION 1
+#define VK_AMD_SHADER_INFO_EXTENSION_NAME "VK_AMD_shader_info"
+
+typedef enum VkShaderInfoTypeAMD {
+ VK_SHADER_INFO_TYPE_STATISTICS_AMD = 0,
+ VK_SHADER_INFO_TYPE_BINARY_AMD = 1,
+ VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD = 2,
+ VK_SHADER_INFO_TYPE_MAX_ENUM_AMD = 0x7FFFFFFF
+} VkShaderInfoTypeAMD;
+typedef struct VkShaderResourceUsageAMD {
+ uint32_t numUsedVgprs;
+ uint32_t numUsedSgprs;
+ uint32_t ldsSizePerLocalWorkGroup;
+ size_t ldsUsageSizeInBytes;
+ size_t scratchMemUsageInBytes;
+} VkShaderResourceUsageAMD;
+
+typedef struct VkShaderStatisticsInfoAMD {
+ VkShaderStageFlags shaderStageMask;
+ VkShaderResourceUsageAMD resourceUsage;
+ uint32_t numPhysicalVgprs;
+ uint32_t numPhysicalSgprs;
+ uint32_t numAvailableVgprs;
+ uint32_t numAvailableSgprs;
+ uint32_t computeWorkGroupSize[3];
+} VkShaderStatisticsInfoAMD;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetShaderInfoAMD)(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits shaderStage, VkShaderInfoTypeAMD infoType, size_t* pInfoSize, void* pInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderInfoAMD(
+ VkDevice device,
+ VkPipeline pipeline,
+ VkShaderStageFlagBits shaderStage,
+ VkShaderInfoTypeAMD infoType,
+ size_t* pInfoSize,
+ void* pInfo);
+#endif
+
+
+#define VK_AMD_shader_image_load_store_lod 1
+#define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_SPEC_VERSION 1
+#define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME "VK_AMD_shader_image_load_store_lod"
+
+
+#define VK_NV_corner_sampled_image 1
+#define VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION 2
+#define VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME "VK_NV_corner_sampled_image"
+typedef struct VkPhysicalDeviceCornerSampledImageFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 cornerSampledImage;
+} VkPhysicalDeviceCornerSampledImageFeaturesNV;
+
+
+
+#define VK_IMG_format_pvrtc 1
+#define VK_IMG_FORMAT_PVRTC_SPEC_VERSION 1
+#define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc"
+
+
+#define VK_NV_external_memory_capabilities 1
+#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1
+#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_NV_external_memory_capabilities"
+
+typedef enum VkExternalMemoryHandleTypeFlagBitsNV {
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV = 0x00000001,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV = 0x00000002,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV = 0x00000004,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV = 0x00000008,
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF
+} VkExternalMemoryHandleTypeFlagBitsNV;
+typedef VkFlags VkExternalMemoryHandleTypeFlagsNV;
+
+typedef enum VkExternalMemoryFeatureFlagBitsNV {
+ VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV = 0x00000001,
+ VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV = 0x00000002,
+ VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV = 0x00000004,
+ VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF
+} VkExternalMemoryFeatureFlagBitsNV;
+typedef VkFlags VkExternalMemoryFeatureFlagsNV;
+typedef struct VkExternalImageFormatPropertiesNV {
+ VkImageFormatProperties imageFormatProperties;
+ VkExternalMemoryFeatureFlagsNV externalMemoryFeatures;
+ VkExternalMemoryHandleTypeFlagsNV exportFromImportedHandleTypes;
+ VkExternalMemoryHandleTypeFlagsNV compatibleHandleTypes;
+} VkExternalImageFormatPropertiesNV;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType, VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceExternalImageFormatPropertiesNV(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags flags,
+ VkExternalMemoryHandleTypeFlagsNV externalHandleType,
+ VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties);
+#endif
+
+
+#define VK_NV_external_memory 1
+#define VK_NV_EXTERNAL_MEMORY_SPEC_VERSION 1
+#define VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME "VK_NV_external_memory"
+typedef struct VkExternalMemoryImageCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagsNV handleTypes;
+} VkExternalMemoryImageCreateInfoNV;
+
+typedef struct VkExportMemoryAllocateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagsNV handleTypes;
+} VkExportMemoryAllocateInfoNV;
+
+
+
+#define VK_EXT_validation_flags 1
+#define VK_EXT_VALIDATION_FLAGS_SPEC_VERSION 2
+#define VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME "VK_EXT_validation_flags"
+
+typedef enum VkValidationCheckEXT {
+ VK_VALIDATION_CHECK_ALL_EXT = 0,
+ VK_VALIDATION_CHECK_SHADERS_EXT = 1,
+ VK_VALIDATION_CHECK_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkValidationCheckEXT;
+typedef struct VkValidationFlagsEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t disabledValidationCheckCount;
+ const VkValidationCheckEXT* pDisabledValidationChecks;
+} VkValidationFlagsEXT;
+
+
+
+#define VK_EXT_shader_subgroup_ballot 1
+#define VK_EXT_SHADER_SUBGROUP_BALLOT_SPEC_VERSION 1
+#define VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME "VK_EXT_shader_subgroup_ballot"
+
+
+#define VK_EXT_shader_subgroup_vote 1
+#define VK_EXT_SHADER_SUBGROUP_VOTE_SPEC_VERSION 1
+#define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote"
+
+
+#define VK_EXT_texture_compression_astc_hdr 1
+#define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_SPEC_VERSION 1
+#define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME "VK_EXT_texture_compression_astc_hdr"
+typedef VkPhysicalDeviceTextureCompressionASTCHDRFeatures VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT;
+
+
+
+#define VK_EXT_astc_decode_mode 1
+#define VK_EXT_ASTC_DECODE_MODE_SPEC_VERSION 1
+#define VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME "VK_EXT_astc_decode_mode"
+typedef struct VkImageViewASTCDecodeModeEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkFormat decodeMode;
+} VkImageViewASTCDecodeModeEXT;
+
+typedef struct VkPhysicalDeviceASTCDecodeFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 decodeModeSharedExponent;
+} VkPhysicalDeviceASTCDecodeFeaturesEXT;
+
+
+
+#define VK_EXT_pipeline_robustness 1
+#define VK_EXT_PIPELINE_ROBUSTNESS_SPEC_VERSION 1
+#define VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_pipeline_robustness"
+
+typedef enum VkPipelineRobustnessBufferBehaviorEXT {
+ VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT = 0,
+ VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT = 1,
+ VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT = 2,
+ VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT = 3,
+ VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkPipelineRobustnessBufferBehaviorEXT;
+
+typedef enum VkPipelineRobustnessImageBehaviorEXT {
+ VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT_EXT = 0,
+ VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT = 1,
+ VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_EXT = 2,
+ VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2_EXT = 3,
+ VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkPipelineRobustnessImageBehaviorEXT;
+typedef struct VkPhysicalDevicePipelineRobustnessFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 pipelineRobustness;
+} VkPhysicalDevicePipelineRobustnessFeaturesEXT;
+
+typedef struct VkPhysicalDevicePipelineRobustnessPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessStorageBuffers;
+ VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessUniformBuffers;
+ VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessVertexInputs;
+ VkPipelineRobustnessImageBehaviorEXT defaultRobustnessImages;
+} VkPhysicalDevicePipelineRobustnessPropertiesEXT;
+
+typedef struct VkPipelineRobustnessCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineRobustnessBufferBehaviorEXT storageBuffers;
+ VkPipelineRobustnessBufferBehaviorEXT uniformBuffers;
+ VkPipelineRobustnessBufferBehaviorEXT vertexInputs;
+ VkPipelineRobustnessImageBehaviorEXT images;
+} VkPipelineRobustnessCreateInfoEXT;
+
+
+
+#define VK_EXT_conditional_rendering 1
+#define VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION 2
+#define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering"
+
+typedef enum VkConditionalRenderingFlagBitsEXT {
+ VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT = 0x00000001,
+ VK_CONDITIONAL_RENDERING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkConditionalRenderingFlagBitsEXT;
+typedef VkFlags VkConditionalRenderingFlagsEXT;
+typedef struct VkConditionalRenderingBeginInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkBuffer buffer;
+ VkDeviceSize offset;
+ VkConditionalRenderingFlagsEXT flags;
+} VkConditionalRenderingBeginInfoEXT;
+
+typedef struct VkPhysicalDeviceConditionalRenderingFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 conditionalRendering;
+ VkBool32 inheritedConditionalRendering;
+} VkPhysicalDeviceConditionalRenderingFeaturesEXT;
+
+typedef struct VkCommandBufferInheritanceConditionalRenderingInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 conditionalRenderingEnable;
+} VkCommandBufferInheritanceConditionalRenderingInfoEXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdBeginConditionalRenderingEXT)(VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin);
+typedef void (VKAPI_PTR *PFN_vkCmdEndConditionalRenderingEXT)(VkCommandBuffer commandBuffer);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginConditionalRenderingEXT(
+ VkCommandBuffer commandBuffer,
+ const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndConditionalRenderingEXT(
+ VkCommandBuffer commandBuffer);
+#endif
+
+
+#define VK_NV_clip_space_w_scaling 1
+#define VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION 1
+#define VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME "VK_NV_clip_space_w_scaling"
+typedef struct VkViewportWScalingNV {
+ float xcoeff;
+ float ycoeff;
+} VkViewportWScalingNV;
+
+typedef struct VkPipelineViewportWScalingStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 viewportWScalingEnable;
+ uint32_t viewportCount;
+ const VkViewportWScalingNV* pViewportWScalings;
+} VkPipelineViewportWScalingStateCreateInfoNV;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWScalingNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportWScalingNV* pViewportWScalings);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWScalingNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkViewportWScalingNV* pViewportWScalings);
+#endif
+
+
+#define VK_EXT_direct_mode_display 1
+#define VK_EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION 1
+#define VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME "VK_EXT_direct_mode_display"
+typedef VkResult (VKAPI_PTR *PFN_vkReleaseDisplayEXT)(VkPhysicalDevice physicalDevice, VkDisplayKHR display);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkReleaseDisplayEXT(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display);
+#endif
+
+
+#define VK_EXT_display_surface_counter 1
+#define VK_EXT_DISPLAY_SURFACE_COUNTER_SPEC_VERSION 1
+#define VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME "VK_EXT_display_surface_counter"
+
+typedef enum VkSurfaceCounterFlagBitsEXT {
+ VK_SURFACE_COUNTER_VBLANK_BIT_EXT = 0x00000001,
+ VK_SURFACE_COUNTER_VBLANK_EXT = VK_SURFACE_COUNTER_VBLANK_BIT_EXT,
+ VK_SURFACE_COUNTER_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkSurfaceCounterFlagBitsEXT;
+typedef VkFlags VkSurfaceCounterFlagsEXT;
+typedef struct VkSurfaceCapabilities2EXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t minImageCount;
+ uint32_t maxImageCount;
+ VkExtent2D currentExtent;
+ VkExtent2D minImageExtent;
+ VkExtent2D maxImageExtent;
+ uint32_t maxImageArrayLayers;
+ VkSurfaceTransformFlagsKHR supportedTransforms;
+ VkSurfaceTransformFlagBitsKHR currentTransform;
+ VkCompositeAlphaFlagsKHR supportedCompositeAlpha;
+ VkImageUsageFlags supportedUsageFlags;
+ VkSurfaceCounterFlagsEXT supportedSurfaceCounters;
+} VkSurfaceCapabilities2EXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT* pSurfaceCapabilities);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2EXT(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilities2EXT* pSurfaceCapabilities);
+#endif
+
+
+#define VK_EXT_display_control 1
+#define VK_EXT_DISPLAY_CONTROL_SPEC_VERSION 1
+#define VK_EXT_DISPLAY_CONTROL_EXTENSION_NAME "VK_EXT_display_control"
+
+typedef enum VkDisplayPowerStateEXT {
+ VK_DISPLAY_POWER_STATE_OFF_EXT = 0,
+ VK_DISPLAY_POWER_STATE_SUSPEND_EXT = 1,
+ VK_DISPLAY_POWER_STATE_ON_EXT = 2,
+ VK_DISPLAY_POWER_STATE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDisplayPowerStateEXT;
+
+typedef enum VkDeviceEventTypeEXT {
+ VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT = 0,
+ VK_DEVICE_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDeviceEventTypeEXT;
+
+typedef enum VkDisplayEventTypeEXT {
+ VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT = 0,
+ VK_DISPLAY_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDisplayEventTypeEXT;
+typedef struct VkDisplayPowerInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDisplayPowerStateEXT powerState;
+} VkDisplayPowerInfoEXT;
+
+typedef struct VkDeviceEventInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceEventTypeEXT deviceEvent;
+} VkDeviceEventInfoEXT;
+
+typedef struct VkDisplayEventInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDisplayEventTypeEXT displayEvent;
+} VkDisplayEventInfoEXT;
+
+typedef struct VkSwapchainCounterCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkSurfaceCounterFlagsEXT surfaceCounters;
+} VkSwapchainCounterCreateInfoEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkDisplayPowerControlEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayPowerInfoEXT* pDisplayPowerInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkRegisterDeviceEventEXT)(VkDevice device, const VkDeviceEventInfoEXT* pDeviceEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence);
+typedef VkResult (VKAPI_PTR *PFN_vkRegisterDisplayEventEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayEventInfoEXT* pDisplayEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence);
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainCounterEXT)(VkDevice device, VkSwapchainKHR swapchain, VkSurfaceCounterFlagBitsEXT counter, uint64_t* pCounterValue);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkDisplayPowerControlEXT(
+ VkDevice device,
+ VkDisplayKHR display,
+ const VkDisplayPowerInfoEXT* pDisplayPowerInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDeviceEventEXT(
+ VkDevice device,
+ const VkDeviceEventInfoEXT* pDeviceEventInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFence* pFence);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDisplayEventEXT(
+ VkDevice device,
+ VkDisplayKHR display,
+ const VkDisplayEventInfoEXT* pDisplayEventInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFence* pFence);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainCounterEXT(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ VkSurfaceCounterFlagBitsEXT counter,
+ uint64_t* pCounterValue);
+#endif
+
+
+#define VK_GOOGLE_display_timing 1
+#define VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION 1
+#define VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME "VK_GOOGLE_display_timing"
+typedef struct VkRefreshCycleDurationGOOGLE {
+ uint64_t refreshDuration;
+} VkRefreshCycleDurationGOOGLE;
+
+typedef struct VkPastPresentationTimingGOOGLE {
+ uint32_t presentID;
+ uint64_t desiredPresentTime;
+ uint64_t actualPresentTime;
+ uint64_t earliestPresentTime;
+ uint64_t presentMargin;
+} VkPastPresentationTimingGOOGLE;
+
+typedef struct VkPresentTimeGOOGLE {
+ uint32_t presentID;
+ uint64_t desiredPresentTime;
+} VkPresentTimeGOOGLE;
+
+typedef struct VkPresentTimesInfoGOOGLE {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t swapchainCount;
+ const VkPresentTimeGOOGLE* pTimes;
+} VkPresentTimesInfoGOOGLE;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetRefreshCycleDurationGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPastPresentationTimingGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetRefreshCycleDurationGOOGLE(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint32_t* pPresentationTimingCount,
+ VkPastPresentationTimingGOOGLE* pPresentationTimings);
+#endif
+
+
+#define VK_NV_sample_mask_override_coverage 1
+#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_SPEC_VERSION 1
+#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME "VK_NV_sample_mask_override_coverage"
+
+
+#define VK_NV_geometry_shader_passthrough 1
+#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_SPEC_VERSION 1
+#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME "VK_NV_geometry_shader_passthrough"
+
+
+#define VK_NV_viewport_array2 1
+#define VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION 1
+#define VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME "VK_NV_viewport_array2"
+#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION
+#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME
+
+
+#define VK_NVX_multiview_per_view_attributes 1
+#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION 1
+#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME "VK_NVX_multiview_per_view_attributes"
+typedef struct VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 perViewPositionAllComponents;
+} VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX;
+
+
+
+#define VK_NV_viewport_swizzle 1
+#define VK_NV_VIEWPORT_SWIZZLE_SPEC_VERSION 1
+#define VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME "VK_NV_viewport_swizzle"
+
+typedef enum VkViewportCoordinateSwizzleNV {
+ VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV = 0,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV = 1,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV = 2,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV = 3,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV = 4,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV = 5,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV = 6,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV = 7,
+ VK_VIEWPORT_COORDINATE_SWIZZLE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkViewportCoordinateSwizzleNV;
+typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV;
+typedef struct VkViewportSwizzleNV {
+ VkViewportCoordinateSwizzleNV x;
+ VkViewportCoordinateSwizzleNV y;
+ VkViewportCoordinateSwizzleNV z;
+ VkViewportCoordinateSwizzleNV w;
+} VkViewportSwizzleNV;
+
+typedef struct VkPipelineViewportSwizzleStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineViewportSwizzleStateCreateFlagsNV flags;
+ uint32_t viewportCount;
+ const VkViewportSwizzleNV* pViewportSwizzles;
+} VkPipelineViewportSwizzleStateCreateInfoNV;
+
+
+
+#define VK_EXT_discard_rectangles 1
+#define VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION 1
+#define VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME "VK_EXT_discard_rectangles"
+
+typedef enum VkDiscardRectangleModeEXT {
+ VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT = 0,
+ VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT = 1,
+ VK_DISCARD_RECTANGLE_MODE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDiscardRectangleModeEXT;
+typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT;
+typedef struct VkPhysicalDeviceDiscardRectanglePropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxDiscardRectangles;
+} VkPhysicalDeviceDiscardRectanglePropertiesEXT;
+
+typedef struct VkPipelineDiscardRectangleStateCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineDiscardRectangleStateCreateFlagsEXT flags;
+ VkDiscardRectangleModeEXT discardRectangleMode;
+ uint32_t discardRectangleCount;
+ const VkRect2D* pDiscardRectangles;
+} VkPipelineDiscardRectangleStateCreateInfoEXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleEXT)(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle, uint32_t discardRectangleCount, const VkRect2D* pDiscardRectangles);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstDiscardRectangle,
+ uint32_t discardRectangleCount,
+ const VkRect2D* pDiscardRectangles);
+#endif
+
+
+#define VK_EXT_conservative_rasterization 1
+#define VK_EXT_CONSERVATIVE_RASTERIZATION_SPEC_VERSION 1
+#define VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME "VK_EXT_conservative_rasterization"
+
+typedef enum VkConservativeRasterizationModeEXT {
+ VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT = 0,
+ VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT = 1,
+ VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT = 2,
+ VK_CONSERVATIVE_RASTERIZATION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkConservativeRasterizationModeEXT;
+typedef VkFlags VkPipelineRasterizationConservativeStateCreateFlagsEXT;
+typedef struct VkPhysicalDeviceConservativeRasterizationPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ float primitiveOverestimationSize;
+ float maxExtraPrimitiveOverestimationSize;
+ float extraPrimitiveOverestimationSizeGranularity;
+ VkBool32 primitiveUnderestimation;
+ VkBool32 conservativePointAndLineRasterization;
+ VkBool32 degenerateTrianglesRasterized;
+ VkBool32 degenerateLinesRasterized;
+ VkBool32 fullyCoveredFragmentShaderInputVariable;
+ VkBool32 conservativeRasterizationPostDepthCoverage;
+} VkPhysicalDeviceConservativeRasterizationPropertiesEXT;
+
+typedef struct VkPipelineRasterizationConservativeStateCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
+ VkConservativeRasterizationModeEXT conservativeRasterizationMode;
+ float extraPrimitiveOverestimationSize;
+} VkPipelineRasterizationConservativeStateCreateInfoEXT;
+
+
+
+#define VK_EXT_depth_clip_enable 1
+#define VK_EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION 1
+#define VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME "VK_EXT_depth_clip_enable"
+typedef VkFlags VkPipelineRasterizationDepthClipStateCreateFlagsEXT;
+typedef struct VkPhysicalDeviceDepthClipEnableFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 depthClipEnable;
+} VkPhysicalDeviceDepthClipEnableFeaturesEXT;
+
+typedef struct VkPipelineRasterizationDepthClipStateCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineRasterizationDepthClipStateCreateFlagsEXT flags;
+ VkBool32 depthClipEnable;
+} VkPipelineRasterizationDepthClipStateCreateInfoEXT;
+
+
+
+#define VK_EXT_swapchain_colorspace 1
+#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 4
+#define VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace"
+
+
+#define VK_EXT_hdr_metadata 1
+#define VK_EXT_HDR_METADATA_SPEC_VERSION 2
+#define VK_EXT_HDR_METADATA_EXTENSION_NAME "VK_EXT_hdr_metadata"
+typedef struct VkXYColorEXT {
+ float x;
+ float y;
+} VkXYColorEXT;
+
+typedef struct VkHdrMetadataEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkXYColorEXT displayPrimaryRed;
+ VkXYColorEXT displayPrimaryGreen;
+ VkXYColorEXT displayPrimaryBlue;
+ VkXYColorEXT whitePoint;
+ float maxLuminance;
+ float minLuminance;
+ float maxContentLightLevel;
+ float maxFrameAverageLightLevel;
+} VkHdrMetadataEXT;
+
+typedef void (VKAPI_PTR *PFN_vkSetHdrMetadataEXT)(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkSetHdrMetadataEXT(
+ VkDevice device,
+ uint32_t swapchainCount,
+ const VkSwapchainKHR* pSwapchains,
+ const VkHdrMetadataEXT* pMetadata);
+#endif
+
+
+#define VK_EXT_external_memory_dma_buf 1
+#define VK_EXT_EXTERNAL_MEMORY_DMA_BUF_SPEC_VERSION 1
+#define VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME "VK_EXT_external_memory_dma_buf"
+
+
+#define VK_EXT_queue_family_foreign 1
+#define VK_EXT_QUEUE_FAMILY_FOREIGN_SPEC_VERSION 1
+#define VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME "VK_EXT_queue_family_foreign"
+#define VK_QUEUE_FAMILY_FOREIGN_EXT (~2U)
+
+
+#define VK_EXT_debug_utils 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugUtilsMessengerEXT)
+#define VK_EXT_DEBUG_UTILS_SPEC_VERSION 2
+#define VK_EXT_DEBUG_UTILS_EXTENSION_NAME "VK_EXT_debug_utils"
+typedef VkFlags VkDebugUtilsMessengerCallbackDataFlagsEXT;
+
+typedef enum VkDebugUtilsMessageSeverityFlagBitsEXT {
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT = 0x00000001,
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT = 0x00000010,
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT = 0x00000100,
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT = 0x00001000,
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDebugUtilsMessageSeverityFlagBitsEXT;
+
+typedef enum VkDebugUtilsMessageTypeFlagBitsEXT {
+ VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT = 0x00000001,
+ VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT = 0x00000002,
+ VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT = 0x00000004,
+ VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT = 0x00000008,
+ VK_DEBUG_UTILS_MESSAGE_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDebugUtilsMessageTypeFlagBitsEXT;
+typedef VkFlags VkDebugUtilsMessageTypeFlagsEXT;
+typedef VkFlags VkDebugUtilsMessageSeverityFlagsEXT;
+typedef VkFlags VkDebugUtilsMessengerCreateFlagsEXT;
+typedef struct VkDebugUtilsLabelEXT {
+ VkStructureType sType;
+ const void* pNext;
+ const char* pLabelName;
+ float color[4];
+} VkDebugUtilsLabelEXT;
+
+typedef struct VkDebugUtilsObjectNameInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkObjectType objectType;
+ uint64_t objectHandle;
+ const char* pObjectName;
+} VkDebugUtilsObjectNameInfoEXT;
+
+typedef struct VkDebugUtilsMessengerCallbackDataEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDebugUtilsMessengerCallbackDataFlagsEXT flags;
+ const char* pMessageIdName;
+ int32_t messageIdNumber;
+ const char* pMessage;
+ uint32_t queueLabelCount;
+ const VkDebugUtilsLabelEXT* pQueueLabels;
+ uint32_t cmdBufLabelCount;
+ const VkDebugUtilsLabelEXT* pCmdBufLabels;
+ uint32_t objectCount;
+ const VkDebugUtilsObjectNameInfoEXT* pObjects;
+} VkDebugUtilsMessengerCallbackDataEXT;
+
+typedef VkBool32 (VKAPI_PTR *PFN_vkDebugUtilsMessengerCallbackEXT)(
+ VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
+ void* pUserData);
+
+typedef struct VkDebugUtilsMessengerCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDebugUtilsMessengerCreateFlagsEXT flags;
+ VkDebugUtilsMessageSeverityFlagsEXT messageSeverity;
+ VkDebugUtilsMessageTypeFlagsEXT messageType;
+ PFN_vkDebugUtilsMessengerCallbackEXT pfnUserCallback;
+ void* pUserData;
+} VkDebugUtilsMessengerCreateInfoEXT;
+
+typedef struct VkDebugUtilsObjectTagInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkObjectType objectType;
+ uint64_t objectHandle;
+ uint64_t tagName;
+ size_t tagSize;
+ const void* pTag;
+} VkDebugUtilsObjectTagInfoEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkSetDebugUtilsObjectNameEXT)(VkDevice device, const VkDebugUtilsObjectNameInfoEXT* pNameInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkSetDebugUtilsObjectTagEXT)(VkDevice device, const VkDebugUtilsObjectTagInfoEXT* pTagInfo);
+typedef void (VKAPI_PTR *PFN_vkQueueBeginDebugUtilsLabelEXT)(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo);
+typedef void (VKAPI_PTR *PFN_vkQueueEndDebugUtilsLabelEXT)(VkQueue queue);
+typedef void (VKAPI_PTR *PFN_vkQueueInsertDebugUtilsLabelEXT)(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdBeginDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdEndDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer);
+typedef void (VKAPI_PTR *PFN_vkCmdInsertDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugUtilsMessengerEXT)(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger);
+typedef void (VKAPI_PTR *PFN_vkDestroyDebugUtilsMessengerEXT)(VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkSubmitDebugUtilsMessageEXT)(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkSetDebugUtilsObjectNameEXT(
+ VkDevice device,
+ const VkDebugUtilsObjectNameInfoEXT* pNameInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSetDebugUtilsObjectTagEXT(
+ VkDevice device,
+ const VkDebugUtilsObjectTagInfoEXT* pTagInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkQueueBeginDebugUtilsLabelEXT(
+ VkQueue queue,
+ const VkDebugUtilsLabelEXT* pLabelInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkQueueEndDebugUtilsLabelEXT(
+ VkQueue queue);
+
+VKAPI_ATTR void VKAPI_CALL vkQueueInsertDebugUtilsLabelEXT(
+ VkQueue queue,
+ const VkDebugUtilsLabelEXT* pLabelInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBeginDebugUtilsLabelEXT(
+ VkCommandBuffer commandBuffer,
+ const VkDebugUtilsLabelEXT* pLabelInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdEndDebugUtilsLabelEXT(
+ VkCommandBuffer commandBuffer);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdInsertDebugUtilsLabelEXT(
+ VkCommandBuffer commandBuffer,
+ const VkDebugUtilsLabelEXT* pLabelInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT(
+ VkInstance instance,
+ const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDebugUtilsMessengerEXT* pMessenger);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT(
+ VkInstance instance,
+ VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkSubmitDebugUtilsMessageEXT(
+ VkInstance instance,
+ VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData);
+#endif
+
+
+#define VK_EXT_sampler_filter_minmax 1
+#define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 2
+#define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax"
+typedef VkSamplerReductionMode VkSamplerReductionModeEXT;
+
+typedef VkSamplerReductionModeCreateInfo VkSamplerReductionModeCreateInfoEXT;
+
+typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT;
+
+
+
+#define VK_AMD_gpu_shader_int16 1
+#define VK_AMD_GPU_SHADER_INT16_SPEC_VERSION 2
+#define VK_AMD_GPU_SHADER_INT16_EXTENSION_NAME "VK_AMD_gpu_shader_int16"
+
+
+#define VK_AMD_mixed_attachment_samples 1
+#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_SPEC_VERSION 1
+#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME "VK_AMD_mixed_attachment_samples"
+
+
+#define VK_AMD_shader_fragment_mask 1
+#define VK_AMD_SHADER_FRAGMENT_MASK_SPEC_VERSION 1
+#define VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME "VK_AMD_shader_fragment_mask"
+
+
+#define VK_EXT_inline_uniform_block 1
+#define VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION 1
+#define VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME "VK_EXT_inline_uniform_block"
+typedef VkPhysicalDeviceInlineUniformBlockFeatures VkPhysicalDeviceInlineUniformBlockFeaturesEXT;
+
+typedef VkPhysicalDeviceInlineUniformBlockProperties VkPhysicalDeviceInlineUniformBlockPropertiesEXT;
+
+typedef VkWriteDescriptorSetInlineUniformBlock VkWriteDescriptorSetInlineUniformBlockEXT;
+
+typedef VkDescriptorPoolInlineUniformBlockCreateInfo VkDescriptorPoolInlineUniformBlockCreateInfoEXT;
+
+
+
+#define VK_EXT_shader_stencil_export 1
+#define VK_EXT_SHADER_STENCIL_EXPORT_SPEC_VERSION 1
+#define VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME "VK_EXT_shader_stencil_export"
+
+
+#define VK_EXT_sample_locations 1
+#define VK_EXT_SAMPLE_LOCATIONS_SPEC_VERSION 1
+#define VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME "VK_EXT_sample_locations"
+typedef struct VkSampleLocationEXT {
+ float x;
+ float y;
+} VkSampleLocationEXT;
+
+typedef struct VkSampleLocationsInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkSampleCountFlagBits sampleLocationsPerPixel;
+ VkExtent2D sampleLocationGridSize;
+ uint32_t sampleLocationsCount;
+ const VkSampleLocationEXT* pSampleLocations;
+} VkSampleLocationsInfoEXT;
+
+typedef struct VkAttachmentSampleLocationsEXT {
+ uint32_t attachmentIndex;
+ VkSampleLocationsInfoEXT sampleLocationsInfo;
+} VkAttachmentSampleLocationsEXT;
+
+typedef struct VkSubpassSampleLocationsEXT {
+ uint32_t subpassIndex;
+ VkSampleLocationsInfoEXT sampleLocationsInfo;
+} VkSubpassSampleLocationsEXT;
+
+typedef struct VkRenderPassSampleLocationsBeginInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t attachmentInitialSampleLocationsCount;
+ const VkAttachmentSampleLocationsEXT* pAttachmentInitialSampleLocations;
+ uint32_t postSubpassSampleLocationsCount;
+ const VkSubpassSampleLocationsEXT* pPostSubpassSampleLocations;
+} VkRenderPassSampleLocationsBeginInfoEXT;
+
+typedef struct VkPipelineSampleLocationsStateCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 sampleLocationsEnable;
+ VkSampleLocationsInfoEXT sampleLocationsInfo;
+} VkPipelineSampleLocationsStateCreateInfoEXT;
+
+typedef struct VkPhysicalDeviceSampleLocationsPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkSampleCountFlags sampleLocationSampleCounts;
+ VkExtent2D maxSampleLocationGridSize;
+ float sampleLocationCoordinateRange[2];
+ uint32_t sampleLocationSubPixelBits;
+ VkBool32 variableSampleLocations;
+} VkPhysicalDeviceSampleLocationsPropertiesEXT;
+
+typedef struct VkMultisamplePropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkExtent2D maxSampleLocationGridSize;
+} VkMultisamplePropertiesEXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetSampleLocationsEXT)(VkCommandBuffer commandBuffer, const VkSampleLocationsInfoEXT* pSampleLocationsInfo);
+typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)(VkPhysicalDevice physicalDevice, VkSampleCountFlagBits samples, VkMultisamplePropertiesEXT* pMultisampleProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleLocationsEXT(
+ VkCommandBuffer commandBuffer,
+ const VkSampleLocationsInfoEXT* pSampleLocationsInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMultisamplePropertiesEXT(
+ VkPhysicalDevice physicalDevice,
+ VkSampleCountFlagBits samples,
+ VkMultisamplePropertiesEXT* pMultisampleProperties);
+#endif
+
+
+#define VK_EXT_blend_operation_advanced 1
+#define VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION 2
+#define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME "VK_EXT_blend_operation_advanced"
+
+typedef enum VkBlendOverlapEXT {
+ VK_BLEND_OVERLAP_UNCORRELATED_EXT = 0,
+ VK_BLEND_OVERLAP_DISJOINT_EXT = 1,
+ VK_BLEND_OVERLAP_CONJOINT_EXT = 2,
+ VK_BLEND_OVERLAP_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkBlendOverlapEXT;
+typedef struct VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 advancedBlendCoherentOperations;
+} VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT;
+
+typedef struct VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t advancedBlendMaxColorAttachments;
+ VkBool32 advancedBlendIndependentBlend;
+ VkBool32 advancedBlendNonPremultipliedSrcColor;
+ VkBool32 advancedBlendNonPremultipliedDstColor;
+ VkBool32 advancedBlendCorrelatedOverlap;
+ VkBool32 advancedBlendAllOperations;
+} VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT;
+
+typedef struct VkPipelineColorBlendAdvancedStateCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 srcPremultiplied;
+ VkBool32 dstPremultiplied;
+ VkBlendOverlapEXT blendOverlap;
+} VkPipelineColorBlendAdvancedStateCreateInfoEXT;
+
+
+
+#define VK_NV_fragment_coverage_to_color 1
+#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_SPEC_VERSION 1
+#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME "VK_NV_fragment_coverage_to_color"
+typedef VkFlags VkPipelineCoverageToColorStateCreateFlagsNV;
+typedef struct VkPipelineCoverageToColorStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCoverageToColorStateCreateFlagsNV flags;
+ VkBool32 coverageToColorEnable;
+ uint32_t coverageToColorLocation;
+} VkPipelineCoverageToColorStateCreateInfoNV;
+
+
+
+#define VK_NV_framebuffer_mixed_samples 1
+#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_SPEC_VERSION 1
+#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME "VK_NV_framebuffer_mixed_samples"
+
+typedef enum VkCoverageModulationModeNV {
+ VK_COVERAGE_MODULATION_MODE_NONE_NV = 0,
+ VK_COVERAGE_MODULATION_MODE_RGB_NV = 1,
+ VK_COVERAGE_MODULATION_MODE_ALPHA_NV = 2,
+ VK_COVERAGE_MODULATION_MODE_RGBA_NV = 3,
+ VK_COVERAGE_MODULATION_MODE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkCoverageModulationModeNV;
+typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV;
+typedef struct VkPipelineCoverageModulationStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCoverageModulationStateCreateFlagsNV flags;
+ VkCoverageModulationModeNV coverageModulationMode;
+ VkBool32 coverageModulationTableEnable;
+ uint32_t coverageModulationTableCount;
+ const float* pCoverageModulationTable;
+} VkPipelineCoverageModulationStateCreateInfoNV;
+
+
+
+#define VK_NV_fill_rectangle 1
+#define VK_NV_FILL_RECTANGLE_SPEC_VERSION 1
+#define VK_NV_FILL_RECTANGLE_EXTENSION_NAME "VK_NV_fill_rectangle"
+
+
+#define VK_NV_shader_sm_builtins 1
+#define VK_NV_SHADER_SM_BUILTINS_SPEC_VERSION 1
+#define VK_NV_SHADER_SM_BUILTINS_EXTENSION_NAME "VK_NV_shader_sm_builtins"
+typedef struct VkPhysicalDeviceShaderSMBuiltinsPropertiesNV {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t shaderSMCount;
+ uint32_t shaderWarpsPerSM;
+} VkPhysicalDeviceShaderSMBuiltinsPropertiesNV;
+
+typedef struct VkPhysicalDeviceShaderSMBuiltinsFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderSMBuiltins;
+} VkPhysicalDeviceShaderSMBuiltinsFeaturesNV;
+
+
+
+#define VK_EXT_post_depth_coverage 1
+#define VK_EXT_POST_DEPTH_COVERAGE_SPEC_VERSION 1
+#define VK_EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME "VK_EXT_post_depth_coverage"
+
+
+#define VK_EXT_image_drm_format_modifier 1
+#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION 2
+#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME "VK_EXT_image_drm_format_modifier"
+typedef struct VkDrmFormatModifierPropertiesEXT {
+ uint64_t drmFormatModifier;
+ uint32_t drmFormatModifierPlaneCount;
+ VkFormatFeatureFlags drmFormatModifierTilingFeatures;
+} VkDrmFormatModifierPropertiesEXT;
+
+typedef struct VkDrmFormatModifierPropertiesListEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t drmFormatModifierCount;
+ VkDrmFormatModifierPropertiesEXT* pDrmFormatModifierProperties;
+} VkDrmFormatModifierPropertiesListEXT;
+
+typedef struct VkPhysicalDeviceImageDrmFormatModifierInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint64_t drmFormatModifier;
+ VkSharingMode sharingMode;
+ uint32_t queueFamilyIndexCount;
+ const uint32_t* pQueueFamilyIndices;
+} VkPhysicalDeviceImageDrmFormatModifierInfoEXT;
+
+typedef struct VkImageDrmFormatModifierListCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t drmFormatModifierCount;
+ const uint64_t* pDrmFormatModifiers;
+} VkImageDrmFormatModifierListCreateInfoEXT;
+
+typedef struct VkImageDrmFormatModifierExplicitCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint64_t drmFormatModifier;
+ uint32_t drmFormatModifierPlaneCount;
+ const VkSubresourceLayout* pPlaneLayouts;
+} VkImageDrmFormatModifierExplicitCreateInfoEXT;
+
+typedef struct VkImageDrmFormatModifierPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint64_t drmFormatModifier;
+} VkImageDrmFormatModifierPropertiesEXT;
+
+typedef struct VkDrmFormatModifierProperties2EXT {
+ uint64_t drmFormatModifier;
+ uint32_t drmFormatModifierPlaneCount;
+ VkFormatFeatureFlags2 drmFormatModifierTilingFeatures;
+} VkDrmFormatModifierProperties2EXT;
+
+typedef struct VkDrmFormatModifierPropertiesList2EXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t drmFormatModifierCount;
+ VkDrmFormatModifierProperties2EXT* pDrmFormatModifierProperties;
+} VkDrmFormatModifierPropertiesList2EXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetImageDrmFormatModifierPropertiesEXT)(VkDevice device, VkImage image, VkImageDrmFormatModifierPropertiesEXT* pProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetImageDrmFormatModifierPropertiesEXT(
+ VkDevice device,
+ VkImage image,
+ VkImageDrmFormatModifierPropertiesEXT* pProperties);
+#endif
+
+
+#define VK_EXT_validation_cache 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkValidationCacheEXT)
+#define VK_EXT_VALIDATION_CACHE_SPEC_VERSION 1
+#define VK_EXT_VALIDATION_CACHE_EXTENSION_NAME "VK_EXT_validation_cache"
+
+typedef enum VkValidationCacheHeaderVersionEXT {
+ VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT = 1,
+ VK_VALIDATION_CACHE_HEADER_VERSION_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkValidationCacheHeaderVersionEXT;
+typedef VkFlags VkValidationCacheCreateFlagsEXT;
+typedef struct VkValidationCacheCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkValidationCacheCreateFlagsEXT flags;
+ size_t initialDataSize;
+ const void* pInitialData;
+} VkValidationCacheCreateInfoEXT;
+
+typedef struct VkShaderModuleValidationCacheCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkValidationCacheEXT validationCache;
+} VkShaderModuleValidationCacheCreateInfoEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateValidationCacheEXT)(VkDevice device, const VkValidationCacheCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkValidationCacheEXT* pValidationCache);
+typedef void (VKAPI_PTR *PFN_vkDestroyValidationCacheEXT)(VkDevice device, VkValidationCacheEXT validationCache, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkMergeValidationCachesEXT)(VkDevice device, VkValidationCacheEXT dstCache, uint32_t srcCacheCount, const VkValidationCacheEXT* pSrcCaches);
+typedef VkResult (VKAPI_PTR *PFN_vkGetValidationCacheDataEXT)(VkDevice device, VkValidationCacheEXT validationCache, size_t* pDataSize, void* pData);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateValidationCacheEXT(
+ VkDevice device,
+ const VkValidationCacheCreateInfoEXT* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkValidationCacheEXT* pValidationCache);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyValidationCacheEXT(
+ VkDevice device,
+ VkValidationCacheEXT validationCache,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkMergeValidationCachesEXT(
+ VkDevice device,
+ VkValidationCacheEXT dstCache,
+ uint32_t srcCacheCount,
+ const VkValidationCacheEXT* pSrcCaches);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetValidationCacheDataEXT(
+ VkDevice device,
+ VkValidationCacheEXT validationCache,
+ size_t* pDataSize,
+ void* pData);
+#endif
+
+
+#define VK_EXT_descriptor_indexing 1
+#define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2
+#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing"
+typedef VkDescriptorBindingFlagBits VkDescriptorBindingFlagBitsEXT;
+
+typedef VkDescriptorBindingFlags VkDescriptorBindingFlagsEXT;
+
+typedef VkDescriptorSetLayoutBindingFlagsCreateInfo VkDescriptorSetLayoutBindingFlagsCreateInfoEXT;
+
+typedef VkPhysicalDeviceDescriptorIndexingFeatures VkPhysicalDeviceDescriptorIndexingFeaturesEXT;
+
+typedef VkPhysicalDeviceDescriptorIndexingProperties VkPhysicalDeviceDescriptorIndexingPropertiesEXT;
+
+typedef VkDescriptorSetVariableDescriptorCountAllocateInfo VkDescriptorSetVariableDescriptorCountAllocateInfoEXT;
+
+typedef VkDescriptorSetVariableDescriptorCountLayoutSupport VkDescriptorSetVariableDescriptorCountLayoutSupportEXT;
+
+
+
+#define VK_EXT_shader_viewport_index_layer 1
+#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1
+#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer"
+
+
+#define VK_NV_shading_rate_image 1
+#define VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION 3
+#define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image"
+
+typedef enum VkShadingRatePaletteEntryNV {
+ VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV = 0,
+ VK_SHADING_RATE_PALETTE_ENTRY_16_INVOCATIONS_PER_PIXEL_NV = 1,
+ VK_SHADING_RATE_PALETTE_ENTRY_8_INVOCATIONS_PER_PIXEL_NV = 2,
+ VK_SHADING_RATE_PALETTE_ENTRY_4_INVOCATIONS_PER_PIXEL_NV = 3,
+ VK_SHADING_RATE_PALETTE_ENTRY_2_INVOCATIONS_PER_PIXEL_NV = 4,
+ VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV = 5,
+ VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV = 6,
+ VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV = 7,
+ VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV = 8,
+ VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV = 9,
+ VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV = 10,
+ VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV = 11,
+ VK_SHADING_RATE_PALETTE_ENTRY_MAX_ENUM_NV = 0x7FFFFFFF
+} VkShadingRatePaletteEntryNV;
+
+typedef enum VkCoarseSampleOrderTypeNV {
+ VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV = 0,
+ VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV = 1,
+ VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV = 2,
+ VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV = 3,
+ VK_COARSE_SAMPLE_ORDER_TYPE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkCoarseSampleOrderTypeNV;
+typedef struct VkShadingRatePaletteNV {
+ uint32_t shadingRatePaletteEntryCount;
+ const VkShadingRatePaletteEntryNV* pShadingRatePaletteEntries;
+} VkShadingRatePaletteNV;
+
+typedef struct VkPipelineViewportShadingRateImageStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 shadingRateImageEnable;
+ uint32_t viewportCount;
+ const VkShadingRatePaletteNV* pShadingRatePalettes;
+} VkPipelineViewportShadingRateImageStateCreateInfoNV;
+
+typedef struct VkPhysicalDeviceShadingRateImageFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shadingRateImage;
+ VkBool32 shadingRateCoarseSampleOrder;
+} VkPhysicalDeviceShadingRateImageFeaturesNV;
+
+typedef struct VkPhysicalDeviceShadingRateImagePropertiesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkExtent2D shadingRateTexelSize;
+ uint32_t shadingRatePaletteSize;
+ uint32_t shadingRateMaxCoarseSamples;
+} VkPhysicalDeviceShadingRateImagePropertiesNV;
+
+typedef struct VkCoarseSampleLocationNV {
+ uint32_t pixelX;
+ uint32_t pixelY;
+ uint32_t sample;
+} VkCoarseSampleLocationNV;
+
+typedef struct VkCoarseSampleOrderCustomNV {
+ VkShadingRatePaletteEntryNV shadingRate;
+ uint32_t sampleCount;
+ uint32_t sampleLocationCount;
+ const VkCoarseSampleLocationNV* pSampleLocations;
+} VkCoarseSampleOrderCustomNV;
+
+typedef struct VkPipelineViewportCoarseSampleOrderStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkCoarseSampleOrderTypeNV sampleOrderType;
+ uint32_t customSampleOrderCount;
+ const VkCoarseSampleOrderCustomNV* pCustomSampleOrders;
+} VkPipelineViewportCoarseSampleOrderStateCreateInfoNV;
+
+typedef void (VKAPI_PTR *PFN_vkCmdBindShadingRateImageNV)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout);
+typedef void (VKAPI_PTR *PFN_vkCmdSetViewportShadingRatePaletteNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkShadingRatePaletteNV* pShadingRatePalettes);
+typedef void (VKAPI_PTR *PFN_vkCmdSetCoarseSampleOrderNV)(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, uint32_t customSampleOrderCount, const VkCoarseSampleOrderCustomNV* pCustomSampleOrders);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdBindShadingRateImageNV(
+ VkCommandBuffer commandBuffer,
+ VkImageView imageView,
+ VkImageLayout imageLayout);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportShadingRatePaletteNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkShadingRatePaletteNV* pShadingRatePalettes);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCoarseSampleOrderNV(
+ VkCommandBuffer commandBuffer,
+ VkCoarseSampleOrderTypeNV sampleOrderType,
+ uint32_t customSampleOrderCount,
+ const VkCoarseSampleOrderCustomNV* pCustomSampleOrders);
+#endif
+
+
+#define VK_NV_ray_tracing 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNV)
+#define VK_NV_RAY_TRACING_SPEC_VERSION 3
+#define VK_NV_RAY_TRACING_EXTENSION_NAME "VK_NV_ray_tracing"
+#define VK_SHADER_UNUSED_KHR (~0U)
+#define VK_SHADER_UNUSED_NV VK_SHADER_UNUSED_KHR
+
+typedef enum VkRayTracingShaderGroupTypeKHR {
+ VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR = 0,
+ VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR = 1,
+ VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR = 2,
+ VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR,
+ VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR,
+ VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR,
+ VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkRayTracingShaderGroupTypeKHR;
+typedef VkRayTracingShaderGroupTypeKHR VkRayTracingShaderGroupTypeNV;
+
+
+typedef enum VkGeometryTypeKHR {
+ VK_GEOMETRY_TYPE_TRIANGLES_KHR = 0,
+ VK_GEOMETRY_TYPE_AABBS_KHR = 1,
+ VK_GEOMETRY_TYPE_INSTANCES_KHR = 2,
+ VK_GEOMETRY_TYPE_TRIANGLES_NV = VK_GEOMETRY_TYPE_TRIANGLES_KHR,
+ VK_GEOMETRY_TYPE_AABBS_NV = VK_GEOMETRY_TYPE_AABBS_KHR,
+ VK_GEOMETRY_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkGeometryTypeKHR;
+typedef VkGeometryTypeKHR VkGeometryTypeNV;
+
+
+typedef enum VkAccelerationStructureTypeKHR {
+ VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR = 0,
+ VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR = 1,
+ VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR = 2,
+ VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR,
+ VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,
+ VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkAccelerationStructureTypeKHR;
+typedef VkAccelerationStructureTypeKHR VkAccelerationStructureTypeNV;
+
+
+typedef enum VkCopyAccelerationStructureModeKHR {
+ VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR = 0,
+ VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR = 1,
+ VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR = 2,
+ VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR = 3,
+ VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR,
+ VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR,
+ VK_COPY_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkCopyAccelerationStructureModeKHR;
+typedef VkCopyAccelerationStructureModeKHR VkCopyAccelerationStructureModeNV;
+
+
+typedef enum VkAccelerationStructureMemoryRequirementsTypeNV {
+ VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV = 0,
+ VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV = 1,
+ VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV = 2,
+ VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkAccelerationStructureMemoryRequirementsTypeNV;
+
+typedef enum VkGeometryFlagBitsKHR {
+ VK_GEOMETRY_OPAQUE_BIT_KHR = 0x00000001,
+ VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR = 0x00000002,
+ VK_GEOMETRY_OPAQUE_BIT_NV = VK_GEOMETRY_OPAQUE_BIT_KHR,
+ VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NV = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR,
+ VK_GEOMETRY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkGeometryFlagBitsKHR;
+typedef VkFlags VkGeometryFlagsKHR;
+typedef VkGeometryFlagsKHR VkGeometryFlagsNV;
+
+typedef VkGeometryFlagBitsKHR VkGeometryFlagBitsNV;
+
+
+typedef enum VkGeometryInstanceFlagBitsKHR {
+ VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR = 0x00000001,
+ VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR = 0x00000002,
+ VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR = 0x00000004,
+ VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR = 0x00000008,
+ VK_GEOMETRY_INSTANCE_FORCE_OPACITY_MICROMAP_2_STATE_EXT = 0x00000010,
+ VK_GEOMETRY_INSTANCE_DISABLE_OPACITY_MICROMAPS_EXT = 0x00000020,
+ VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR,
+ VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR,
+ VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR,
+ VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR,
+ VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR,
+ VK_GEOMETRY_INSTANCE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkGeometryInstanceFlagBitsKHR;
+typedef VkFlags VkGeometryInstanceFlagsKHR;
+typedef VkGeometryInstanceFlagsKHR VkGeometryInstanceFlagsNV;
+
+typedef VkGeometryInstanceFlagBitsKHR VkGeometryInstanceFlagBitsNV;
+
+
+typedef enum VkBuildAccelerationStructureFlagBitsKHR {
+ VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR = 0x00000001,
+ VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR = 0x00000002,
+ VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR = 0x00000004,
+ VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR = 0x00000008,
+ VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR = 0x00000010,
+ VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV = 0x00000020,
+ VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_EXT = 0x00000040,
+ VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISABLE_OPACITY_MICROMAPS_EXT = 0x00000080,
+ VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_DATA_UPDATE_EXT = 0x00000100,
+ VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR,
+ VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR,
+ VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR,
+ VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR,
+ VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR,
+ VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkBuildAccelerationStructureFlagBitsKHR;
+typedef VkFlags VkBuildAccelerationStructureFlagsKHR;
+typedef VkBuildAccelerationStructureFlagsKHR VkBuildAccelerationStructureFlagsNV;
+
+typedef VkBuildAccelerationStructureFlagBitsKHR VkBuildAccelerationStructureFlagBitsNV;
+
+typedef struct VkRayTracingShaderGroupCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkRayTracingShaderGroupTypeKHR type;
+ uint32_t generalShader;
+ uint32_t closestHitShader;
+ uint32_t anyHitShader;
+ uint32_t intersectionShader;
+} VkRayTracingShaderGroupCreateInfoNV;
+
+typedef struct VkRayTracingPipelineCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCreateFlags flags;
+ uint32_t stageCount;
+ const VkPipelineShaderStageCreateInfo* pStages;
+ uint32_t groupCount;
+ const VkRayTracingShaderGroupCreateInfoNV* pGroups;
+ uint32_t maxRecursionDepth;
+ VkPipelineLayout layout;
+ VkPipeline basePipelineHandle;
+ int32_t basePipelineIndex;
+} VkRayTracingPipelineCreateInfoNV;
+
+typedef struct VkGeometryTrianglesNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkBuffer vertexData;
+ VkDeviceSize vertexOffset;
+ uint32_t vertexCount;
+ VkDeviceSize vertexStride;
+ VkFormat vertexFormat;
+ VkBuffer indexData;
+ VkDeviceSize indexOffset;
+ uint32_t indexCount;
+ VkIndexType indexType;
+ VkBuffer transformData;
+ VkDeviceSize transformOffset;
+} VkGeometryTrianglesNV;
+
+typedef struct VkGeometryAABBNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkBuffer aabbData;
+ uint32_t numAABBs;
+ uint32_t stride;
+ VkDeviceSize offset;
+} VkGeometryAABBNV;
+
+typedef struct VkGeometryDataNV {
+ VkGeometryTrianglesNV triangles;
+ VkGeometryAABBNV aabbs;
+} VkGeometryDataNV;
+
+typedef struct VkGeometryNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkGeometryTypeKHR geometryType;
+ VkGeometryDataNV geometry;
+ VkGeometryFlagsKHR flags;
+} VkGeometryNV;
+
+typedef struct VkAccelerationStructureInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccelerationStructureTypeNV type;
+ VkBuildAccelerationStructureFlagsNV flags;
+ uint32_t instanceCount;
+ uint32_t geometryCount;
+ const VkGeometryNV* pGeometries;
+} VkAccelerationStructureInfoNV;
+
+typedef struct VkAccelerationStructureCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceSize compactedSize;
+ VkAccelerationStructureInfoNV info;
+} VkAccelerationStructureCreateInfoNV;
+
+typedef struct VkBindAccelerationStructureMemoryInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccelerationStructureNV accelerationStructure;
+ VkDeviceMemory memory;
+ VkDeviceSize memoryOffset;
+ uint32_t deviceIndexCount;
+ const uint32_t* pDeviceIndices;
+} VkBindAccelerationStructureMemoryInfoNV;
+
+typedef struct VkWriteDescriptorSetAccelerationStructureNV {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t accelerationStructureCount;
+ const VkAccelerationStructureNV* pAccelerationStructures;
+} VkWriteDescriptorSetAccelerationStructureNV;
+
+typedef struct VkAccelerationStructureMemoryRequirementsInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccelerationStructureMemoryRequirementsTypeNV type;
+ VkAccelerationStructureNV accelerationStructure;
+} VkAccelerationStructureMemoryRequirementsInfoNV;
+
+typedef struct VkPhysicalDeviceRayTracingPropertiesNV {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t shaderGroupHandleSize;
+ uint32_t maxRecursionDepth;
+ uint32_t maxShaderGroupStride;
+ uint32_t shaderGroupBaseAlignment;
+ uint64_t maxGeometryCount;
+ uint64_t maxInstanceCount;
+ uint64_t maxTriangleCount;
+ uint32_t maxDescriptorSetAccelerationStructures;
+} VkPhysicalDeviceRayTracingPropertiesNV;
+
+typedef struct VkTransformMatrixKHR {
+ float matrix[3][4];
+} VkTransformMatrixKHR;
+
+typedef VkTransformMatrixKHR VkTransformMatrixNV;
+
+typedef struct VkAabbPositionsKHR {
+ float minX;
+ float minY;
+ float minZ;
+ float maxX;
+ float maxY;
+ float maxZ;
+} VkAabbPositionsKHR;
+
+typedef VkAabbPositionsKHR VkAabbPositionsNV;
+
+typedef struct VkAccelerationStructureInstanceKHR {
+ VkTransformMatrixKHR transform;
+ uint32_t instanceCustomIndex:24;
+ uint32_t mask:8;
+ uint32_t instanceShaderBindingTableRecordOffset:24;
+ VkGeometryInstanceFlagsKHR flags:8;
+ uint64_t accelerationStructureReference;
+} VkAccelerationStructureInstanceKHR;
+
+typedef VkAccelerationStructureInstanceKHR VkAccelerationStructureInstanceNV;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureNV)(VkDevice device, const VkAccelerationStructureCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNV* pAccelerationStructure);
+typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsNV)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements);
+typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryNV)(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV* pBindInfos);
+typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureNV)(VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV* pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset, VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNV)(VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkCopyAccelerationStructureModeKHR mode);
+typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysNV)(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer, VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer, VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride, VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset, VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer, VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride, uint32_t width, uint32_t height, uint32_t depth);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesNV)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoNV* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
+typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesKHR)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData);
+typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesNV)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData);
+typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureHandleNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, size_t dataSize, void* pData);
+typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesNV)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureNV* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery);
+typedef VkResult (VKAPI_PTR *PFN_vkCompileDeferredNV)(VkDevice device, VkPipeline pipeline, uint32_t shader);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureNV(
+ VkDevice device,
+ const VkAccelerationStructureCreateInfoNV* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkAccelerationStructureNV* pAccelerationStructure);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureNV(
+ VkDevice device,
+ VkAccelerationStructureNV accelerationStructure,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureMemoryRequirementsNV(
+ VkDevice device,
+ const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo,
+ VkMemoryRequirements2KHR* pMemoryRequirements);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindAccelerationStructureMemoryNV(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindAccelerationStructureMemoryInfoNV* pBindInfos);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureNV(
+ VkCommandBuffer commandBuffer,
+ const VkAccelerationStructureInfoNV* pInfo,
+ VkBuffer instanceData,
+ VkDeviceSize instanceOffset,
+ VkBool32 update,
+ VkAccelerationStructureNV dst,
+ VkAccelerationStructureNV src,
+ VkBuffer scratch,
+ VkDeviceSize scratchOffset);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureNV(
+ VkCommandBuffer commandBuffer,
+ VkAccelerationStructureNV dst,
+ VkAccelerationStructureNV src,
+ VkCopyAccelerationStructureModeKHR mode);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysNV(
+ VkCommandBuffer commandBuffer,
+ VkBuffer raygenShaderBindingTableBuffer,
+ VkDeviceSize raygenShaderBindingOffset,
+ VkBuffer missShaderBindingTableBuffer,
+ VkDeviceSize missShaderBindingOffset,
+ VkDeviceSize missShaderBindingStride,
+ VkBuffer hitShaderBindingTableBuffer,
+ VkDeviceSize hitShaderBindingOffset,
+ VkDeviceSize hitShaderBindingStride,
+ VkBuffer callableShaderBindingTableBuffer,
+ VkDeviceSize callableShaderBindingOffset,
+ VkDeviceSize callableShaderBindingStride,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesNV(
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkRayTracingPipelineCreateInfoNV* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipeline* pPipelines);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesKHR(
+ VkDevice device,
+ VkPipeline pipeline,
+ uint32_t firstGroup,
+ uint32_t groupCount,
+ size_t dataSize,
+ void* pData);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesNV(
+ VkDevice device,
+ VkPipeline pipeline,
+ uint32_t firstGroup,
+ uint32_t groupCount,
+ size_t dataSize,
+ void* pData);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetAccelerationStructureHandleNV(
+ VkDevice device,
+ VkAccelerationStructureNV accelerationStructure,
+ size_t dataSize,
+ void* pData);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t accelerationStructureCount,
+ const VkAccelerationStructureNV* pAccelerationStructures,
+ VkQueryType queryType,
+ VkQueryPool queryPool,
+ uint32_t firstQuery);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCompileDeferredNV(
+ VkDevice device,
+ VkPipeline pipeline,
+ uint32_t shader);
+#endif
+
+
+#define VK_NV_representative_fragment_test 1
+#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 2
+#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME "VK_NV_representative_fragment_test"
+typedef struct VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 representativeFragmentTest;
+} VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV;
+
+typedef struct VkPipelineRepresentativeFragmentTestStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 representativeFragmentTestEnable;
+} VkPipelineRepresentativeFragmentTestStateCreateInfoNV;
+
+
+
+#define VK_EXT_filter_cubic 1
+#define VK_EXT_FILTER_CUBIC_SPEC_VERSION 3
+#define VK_EXT_FILTER_CUBIC_EXTENSION_NAME "VK_EXT_filter_cubic"
+typedef struct VkPhysicalDeviceImageViewImageFormatInfoEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkImageViewType imageViewType;
+} VkPhysicalDeviceImageViewImageFormatInfoEXT;
+
+typedef struct VkFilterCubicImageViewImageFormatPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 filterCubic;
+ VkBool32 filterCubicMinmax;
+} VkFilterCubicImageViewImageFormatPropertiesEXT;
+
+
+
+#define VK_QCOM_render_pass_shader_resolve 1
+#define VK_QCOM_RENDER_PASS_SHADER_RESOLVE_SPEC_VERSION 4
+#define VK_QCOM_RENDER_PASS_SHADER_RESOLVE_EXTENSION_NAME "VK_QCOM_render_pass_shader_resolve"
+
+
+#define VK_EXT_global_priority 1
+#define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2
+#define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority"
+typedef VkQueueGlobalPriorityKHR VkQueueGlobalPriorityEXT;
+
+typedef VkDeviceQueueGlobalPriorityCreateInfoKHR VkDeviceQueueGlobalPriorityCreateInfoEXT;
+
+
+
+#define VK_EXT_external_memory_host 1
+#define VK_EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION 1
+#define VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME "VK_EXT_external_memory_host"
+typedef struct VkImportMemoryHostPointerInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkExternalMemoryHandleTypeFlagBits handleType;
+ void* pHostPointer;
+} VkImportMemoryHostPointerInfoEXT;
+
+typedef struct VkMemoryHostPointerPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t memoryTypeBits;
+} VkMemoryHostPointerPropertiesEXT;
+
+typedef struct VkPhysicalDeviceExternalMemoryHostPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkDeviceSize minImportedHostPointerAlignment;
+} VkPhysicalDeviceExternalMemoryHostPropertiesEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryHostPointerPropertiesEXT)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, const void* pHostPointer, VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT(
+ VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ const void* pHostPointer,
+ VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties);
+#endif
+
+
+#define VK_AMD_buffer_marker 1
+#define VK_AMD_BUFFER_MARKER_SPEC_VERSION 1
+#define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_AMD_buffer_marker"
+typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarkerAMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarkerAMD(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlagBits pipelineStage,
+ VkBuffer dstBuffer,
+ VkDeviceSize dstOffset,
+ uint32_t marker);
+#endif
+
+
+#define VK_AMD_pipeline_compiler_control 1
+#define VK_AMD_PIPELINE_COMPILER_CONTROL_SPEC_VERSION 1
+#define VK_AMD_PIPELINE_COMPILER_CONTROL_EXTENSION_NAME "VK_AMD_pipeline_compiler_control"
+
+typedef enum VkPipelineCompilerControlFlagBitsAMD {
+ VK_PIPELINE_COMPILER_CONTROL_FLAG_BITS_MAX_ENUM_AMD = 0x7FFFFFFF
+} VkPipelineCompilerControlFlagBitsAMD;
+typedef VkFlags VkPipelineCompilerControlFlagsAMD;
+typedef struct VkPipelineCompilerControlCreateInfoAMD {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCompilerControlFlagsAMD compilerControlFlags;
+} VkPipelineCompilerControlCreateInfoAMD;
+
+
+
+#define VK_EXT_calibrated_timestamps 1
+#define VK_EXT_CALIBRATED_TIMESTAMPS_SPEC_VERSION 2
+#define VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME "VK_EXT_calibrated_timestamps"
+
+typedef enum VkTimeDomainEXT {
+ VK_TIME_DOMAIN_DEVICE_EXT = 0,
+ VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT = 1,
+ VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT = 2,
+ VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT = 3,
+ VK_TIME_DOMAIN_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkTimeDomainEXT;
+typedef struct VkCalibratedTimestampInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkTimeDomainEXT timeDomain;
+} VkCalibratedTimestampInfoEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)(VkPhysicalDevice physicalDevice, uint32_t* pTimeDomainCount, VkTimeDomainEXT* pTimeDomains);
+typedef VkResult (VKAPI_PTR *PFN_vkGetCalibratedTimestampsEXT)(VkDevice device, uint32_t timestampCount, const VkCalibratedTimestampInfoEXT* pTimestampInfos, uint64_t* pTimestamps, uint64_t* pMaxDeviation);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCalibrateableTimeDomainsEXT(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pTimeDomainCount,
+ VkTimeDomainEXT* pTimeDomains);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetCalibratedTimestampsEXT(
+ VkDevice device,
+ uint32_t timestampCount,
+ const VkCalibratedTimestampInfoEXT* pTimestampInfos,
+ uint64_t* pTimestamps,
+ uint64_t* pMaxDeviation);
+#endif
+
+
+#define VK_AMD_shader_core_properties 1
+#define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 2
+#define VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_AMD_shader_core_properties"
+typedef struct VkPhysicalDeviceShaderCorePropertiesAMD {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t shaderEngineCount;
+ uint32_t shaderArraysPerEngineCount;
+ uint32_t computeUnitsPerShaderArray;
+ uint32_t simdPerComputeUnit;
+ uint32_t wavefrontsPerSimd;
+ uint32_t wavefrontSize;
+ uint32_t sgprsPerSimd;
+ uint32_t minSgprAllocation;
+ uint32_t maxSgprAllocation;
+ uint32_t sgprAllocationGranularity;
+ uint32_t vgprsPerSimd;
+ uint32_t minVgprAllocation;
+ uint32_t maxVgprAllocation;
+ uint32_t vgprAllocationGranularity;
+} VkPhysicalDeviceShaderCorePropertiesAMD;
+
+
+
+#define VK_AMD_memory_overallocation_behavior 1
+#define VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_SPEC_VERSION 1
+#define VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_EXTENSION_NAME "VK_AMD_memory_overallocation_behavior"
+
+typedef enum VkMemoryOverallocationBehaviorAMD {
+ VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD = 0,
+ VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD = 1,
+ VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD = 2,
+ VK_MEMORY_OVERALLOCATION_BEHAVIOR_MAX_ENUM_AMD = 0x7FFFFFFF
+} VkMemoryOverallocationBehaviorAMD;
+typedef struct VkDeviceMemoryOverallocationCreateInfoAMD {
+ VkStructureType sType;
+ const void* pNext;
+ VkMemoryOverallocationBehaviorAMD overallocationBehavior;
+} VkDeviceMemoryOverallocationCreateInfoAMD;
+
+
+
+#define VK_EXT_vertex_attribute_divisor 1
+#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION 3
+#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME "VK_EXT_vertex_attribute_divisor"
+typedef struct VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxVertexAttribDivisor;
+} VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT;
+
+typedef struct VkVertexInputBindingDivisorDescriptionEXT {
+ uint32_t binding;
+ uint32_t divisor;
+} VkVertexInputBindingDivisorDescriptionEXT;
+
+typedef struct VkPipelineVertexInputDivisorStateCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t vertexBindingDivisorCount;
+ const VkVertexInputBindingDivisorDescriptionEXT* pVertexBindingDivisors;
+} VkPipelineVertexInputDivisorStateCreateInfoEXT;
+
+typedef struct VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 vertexAttributeInstanceRateDivisor;
+ VkBool32 vertexAttributeInstanceRateZeroDivisor;
+} VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT;
+
+
+
+#define VK_EXT_pipeline_creation_feedback 1
+#define VK_EXT_PIPELINE_CREATION_FEEDBACK_SPEC_VERSION 1
+#define VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME "VK_EXT_pipeline_creation_feedback"
+typedef VkPipelineCreationFeedbackFlagBits VkPipelineCreationFeedbackFlagBitsEXT;
+
+typedef VkPipelineCreationFeedbackFlags VkPipelineCreationFeedbackFlagsEXT;
+
+typedef VkPipelineCreationFeedbackCreateInfo VkPipelineCreationFeedbackCreateInfoEXT;
+
+typedef VkPipelineCreationFeedback VkPipelineCreationFeedbackEXT;
+
+
+
+#define VK_NV_shader_subgroup_partitioned 1
+#define VK_NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1
+#define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned"
+
+
+#define VK_NV_compute_shader_derivatives 1
+#define VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION 1
+#define VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_NV_compute_shader_derivatives"
+typedef struct VkPhysicalDeviceComputeShaderDerivativesFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 computeDerivativeGroupQuads;
+ VkBool32 computeDerivativeGroupLinear;
+} VkPhysicalDeviceComputeShaderDerivativesFeaturesNV;
+
+
+
+#define VK_NV_mesh_shader 1
+#define VK_NV_MESH_SHADER_SPEC_VERSION 1
+#define VK_NV_MESH_SHADER_EXTENSION_NAME "VK_NV_mesh_shader"
+typedef struct VkPhysicalDeviceMeshShaderFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 taskShader;
+ VkBool32 meshShader;
+} VkPhysicalDeviceMeshShaderFeaturesNV;
+
+typedef struct VkPhysicalDeviceMeshShaderPropertiesNV {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxDrawMeshTasksCount;
+ uint32_t maxTaskWorkGroupInvocations;
+ uint32_t maxTaskWorkGroupSize[3];
+ uint32_t maxTaskTotalMemorySize;
+ uint32_t maxTaskOutputCount;
+ uint32_t maxMeshWorkGroupInvocations;
+ uint32_t maxMeshWorkGroupSize[3];
+ uint32_t maxMeshTotalMemorySize;
+ uint32_t maxMeshOutputVertices;
+ uint32_t maxMeshOutputPrimitives;
+ uint32_t maxMeshMultiviewViewCount;
+ uint32_t meshOutputPerVertexGranularity;
+ uint32_t meshOutputPerPrimitiveGranularity;
+} VkPhysicalDeviceMeshShaderPropertiesNV;
+
+typedef struct VkDrawMeshTasksIndirectCommandNV {
+ uint32_t taskCount;
+ uint32_t firstTask;
+} VkDrawMeshTasksIndirectCommandNV;
+
+typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksNV)(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCountNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t taskCount,
+ uint32_t firstTask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectNV(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ uint32_t drawCount,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountNV(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+#endif
+
+
+#define VK_NV_fragment_shader_barycentric 1
+#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1
+#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_NV_fragment_shader_barycentric"
+typedef VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV;
+
+
+
+#define VK_NV_shader_image_footprint 1
+#define VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION 2
+#define VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME "VK_NV_shader_image_footprint"
+typedef struct VkPhysicalDeviceShaderImageFootprintFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 imageFootprint;
+} VkPhysicalDeviceShaderImageFootprintFeaturesNV;
+
+
+
+#define VK_NV_scissor_exclusive 1
+#define VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION 1
+#define VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME "VK_NV_scissor_exclusive"
+typedef struct VkPipelineViewportExclusiveScissorStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t exclusiveScissorCount;
+ const VkRect2D* pExclusiveScissors;
+} VkPipelineViewportExclusiveScissorStateCreateInfoNV;
+
+typedef struct VkPhysicalDeviceExclusiveScissorFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 exclusiveScissor;
+} VkPhysicalDeviceExclusiveScissorFeaturesNV;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetExclusiveScissorNV)(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkRect2D* pExclusiveScissors);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetExclusiveScissorNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstExclusiveScissor,
+ uint32_t exclusiveScissorCount,
+ const VkRect2D* pExclusiveScissors);
+#endif
+
+
+#define VK_NV_device_diagnostic_checkpoints 1
+#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION 2
+#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME "VK_NV_device_diagnostic_checkpoints"
+typedef struct VkQueueFamilyCheckpointPropertiesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkPipelineStageFlags checkpointExecutionStageMask;
+} VkQueueFamilyCheckpointPropertiesNV;
+
+typedef struct VkCheckpointDataNV {
+ VkStructureType sType;
+ void* pNext;
+ VkPipelineStageFlagBits stage;
+ void* pCheckpointMarker;
+} VkCheckpointDataNV;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetCheckpointNV)(VkCommandBuffer commandBuffer, const void* pCheckpointMarker);
+typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointDataNV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointDataNV* pCheckpointData);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCheckpointNV(
+ VkCommandBuffer commandBuffer,
+ const void* pCheckpointMarker);
+
+VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointDataNV(
+ VkQueue queue,
+ uint32_t* pCheckpointDataCount,
+ VkCheckpointDataNV* pCheckpointData);
+#endif
+
+
+#define VK_INTEL_shader_integer_functions2 1
+#define VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_SPEC_VERSION 1
+#define VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_EXTENSION_NAME "VK_INTEL_shader_integer_functions2"
+typedef struct VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderIntegerFunctions2;
+} VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL;
+
+
+
+#define VK_INTEL_performance_query 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPerformanceConfigurationINTEL)
+#define VK_INTEL_PERFORMANCE_QUERY_SPEC_VERSION 2
+#define VK_INTEL_PERFORMANCE_QUERY_EXTENSION_NAME "VK_INTEL_performance_query"
+
+typedef enum VkPerformanceConfigurationTypeINTEL {
+ VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL = 0,
+ VK_PERFORMANCE_CONFIGURATION_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF
+} VkPerformanceConfigurationTypeINTEL;
+
+typedef enum VkQueryPoolSamplingModeINTEL {
+ VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL = 0,
+ VK_QUERY_POOL_SAMPLING_MODE_MAX_ENUM_INTEL = 0x7FFFFFFF
+} VkQueryPoolSamplingModeINTEL;
+
+typedef enum VkPerformanceOverrideTypeINTEL {
+ VK_PERFORMANCE_OVERRIDE_TYPE_NULL_HARDWARE_INTEL = 0,
+ VK_PERFORMANCE_OVERRIDE_TYPE_FLUSH_GPU_CACHES_INTEL = 1,
+ VK_PERFORMANCE_OVERRIDE_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF
+} VkPerformanceOverrideTypeINTEL;
+
+typedef enum VkPerformanceParameterTypeINTEL {
+ VK_PERFORMANCE_PARAMETER_TYPE_HW_COUNTERS_SUPPORTED_INTEL = 0,
+ VK_PERFORMANCE_PARAMETER_TYPE_STREAM_MARKER_VALID_BITS_INTEL = 1,
+ VK_PERFORMANCE_PARAMETER_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF
+} VkPerformanceParameterTypeINTEL;
+
+typedef enum VkPerformanceValueTypeINTEL {
+ VK_PERFORMANCE_VALUE_TYPE_UINT32_INTEL = 0,
+ VK_PERFORMANCE_VALUE_TYPE_UINT64_INTEL = 1,
+ VK_PERFORMANCE_VALUE_TYPE_FLOAT_INTEL = 2,
+ VK_PERFORMANCE_VALUE_TYPE_BOOL_INTEL = 3,
+ VK_PERFORMANCE_VALUE_TYPE_STRING_INTEL = 4,
+ VK_PERFORMANCE_VALUE_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF
+} VkPerformanceValueTypeINTEL;
+typedef union VkPerformanceValueDataINTEL {
+ uint32_t value32;
+ uint64_t value64;
+ float valueFloat;
+ VkBool32 valueBool;
+ const char* valueString;
+} VkPerformanceValueDataINTEL;
+
+typedef struct VkPerformanceValueINTEL {
+ VkPerformanceValueTypeINTEL type;
+ VkPerformanceValueDataINTEL data;
+} VkPerformanceValueINTEL;
+
+typedef struct VkInitializePerformanceApiInfoINTEL {
+ VkStructureType sType;
+ const void* pNext;
+ void* pUserData;
+} VkInitializePerformanceApiInfoINTEL;
+
+typedef struct VkQueryPoolPerformanceQueryCreateInfoINTEL {
+ VkStructureType sType;
+ const void* pNext;
+ VkQueryPoolSamplingModeINTEL performanceCountersSampling;
+} VkQueryPoolPerformanceQueryCreateInfoINTEL;
+
+typedef VkQueryPoolPerformanceQueryCreateInfoINTEL VkQueryPoolCreateInfoINTEL;
+
+typedef struct VkPerformanceMarkerInfoINTEL {
+ VkStructureType sType;
+ const void* pNext;
+ uint64_t marker;
+} VkPerformanceMarkerInfoINTEL;
+
+typedef struct VkPerformanceStreamMarkerInfoINTEL {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t marker;
+} VkPerformanceStreamMarkerInfoINTEL;
+
+typedef struct VkPerformanceOverrideInfoINTEL {
+ VkStructureType sType;
+ const void* pNext;
+ VkPerformanceOverrideTypeINTEL type;
+ VkBool32 enable;
+ uint64_t parameter;
+} VkPerformanceOverrideInfoINTEL;
+
+typedef struct VkPerformanceConfigurationAcquireInfoINTEL {
+ VkStructureType sType;
+ const void* pNext;
+ VkPerformanceConfigurationTypeINTEL type;
+} VkPerformanceConfigurationAcquireInfoINTEL;
+
+typedef VkResult (VKAPI_PTR *PFN_vkInitializePerformanceApiINTEL)(VkDevice device, const VkInitializePerformanceApiInfoINTEL* pInitializeInfo);
+typedef void (VKAPI_PTR *PFN_vkUninitializePerformanceApiINTEL)(VkDevice device);
+typedef VkResult (VKAPI_PTR *PFN_vkCmdSetPerformanceMarkerINTEL)(VkCommandBuffer commandBuffer, const VkPerformanceMarkerInfoINTEL* pMarkerInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkCmdSetPerformanceStreamMarkerINTEL)(VkCommandBuffer commandBuffer, const VkPerformanceStreamMarkerInfoINTEL* pMarkerInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkCmdSetPerformanceOverrideINTEL)(VkCommandBuffer commandBuffer, const VkPerformanceOverrideInfoINTEL* pOverrideInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkAcquirePerformanceConfigurationINTEL)(VkDevice device, const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo, VkPerformanceConfigurationINTEL* pConfiguration);
+typedef VkResult (VKAPI_PTR *PFN_vkReleasePerformanceConfigurationINTEL)(VkDevice device, VkPerformanceConfigurationINTEL configuration);
+typedef VkResult (VKAPI_PTR *PFN_vkQueueSetPerformanceConfigurationINTEL)(VkQueue queue, VkPerformanceConfigurationINTEL configuration);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPerformanceParameterINTEL)(VkDevice device, VkPerformanceParameterTypeINTEL parameter, VkPerformanceValueINTEL* pValue);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkInitializePerformanceApiINTEL(
+ VkDevice device,
+ const VkInitializePerformanceApiInfoINTEL* pInitializeInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkUninitializePerformanceApiINTEL(
+ VkDevice device);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceMarkerINTEL(
+ VkCommandBuffer commandBuffer,
+ const VkPerformanceMarkerInfoINTEL* pMarkerInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceStreamMarkerINTEL(
+ VkCommandBuffer commandBuffer,
+ const VkPerformanceStreamMarkerInfoINTEL* pMarkerInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceOverrideINTEL(
+ VkCommandBuffer commandBuffer,
+ const VkPerformanceOverrideInfoINTEL* pOverrideInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquirePerformanceConfigurationINTEL(
+ VkDevice device,
+ const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo,
+ VkPerformanceConfigurationINTEL* pConfiguration);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkReleasePerformanceConfigurationINTEL(
+ VkDevice device,
+ VkPerformanceConfigurationINTEL configuration);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueueSetPerformanceConfigurationINTEL(
+ VkQueue queue,
+ VkPerformanceConfigurationINTEL configuration);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPerformanceParameterINTEL(
+ VkDevice device,
+ VkPerformanceParameterTypeINTEL parameter,
+ VkPerformanceValueINTEL* pValue);
+#endif
+
+
+#define VK_EXT_pci_bus_info 1
+#define VK_EXT_PCI_BUS_INFO_SPEC_VERSION 2
+#define VK_EXT_PCI_BUS_INFO_EXTENSION_NAME "VK_EXT_pci_bus_info"
+typedef struct VkPhysicalDevicePCIBusInfoPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t pciDomain;
+ uint32_t pciBus;
+ uint32_t pciDevice;
+ uint32_t pciFunction;
+} VkPhysicalDevicePCIBusInfoPropertiesEXT;
+
+
+
+#define VK_AMD_display_native_hdr 1
+#define VK_AMD_DISPLAY_NATIVE_HDR_SPEC_VERSION 1
+#define VK_AMD_DISPLAY_NATIVE_HDR_EXTENSION_NAME "VK_AMD_display_native_hdr"
+typedef struct VkDisplayNativeHdrSurfaceCapabilitiesAMD {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 localDimmingSupport;
+} VkDisplayNativeHdrSurfaceCapabilitiesAMD;
+
+typedef struct VkSwapchainDisplayNativeHdrCreateInfoAMD {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 localDimmingEnable;
+} VkSwapchainDisplayNativeHdrCreateInfoAMD;
+
+typedef void (VKAPI_PTR *PFN_vkSetLocalDimmingAMD)(VkDevice device, VkSwapchainKHR swapChain, VkBool32 localDimmingEnable);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkSetLocalDimmingAMD(
+ VkDevice device,
+ VkSwapchainKHR swapChain,
+ VkBool32 localDimmingEnable);
+#endif
+
+
+#define VK_EXT_fragment_density_map 1
+#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 2
+#define VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME "VK_EXT_fragment_density_map"
+typedef struct VkPhysicalDeviceFragmentDensityMapFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 fragmentDensityMap;
+ VkBool32 fragmentDensityMapDynamic;
+ VkBool32 fragmentDensityMapNonSubsampledImages;
+} VkPhysicalDeviceFragmentDensityMapFeaturesEXT;
+
+typedef struct VkPhysicalDeviceFragmentDensityMapPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkExtent2D minFragmentDensityTexelSize;
+ VkExtent2D maxFragmentDensityTexelSize;
+ VkBool32 fragmentDensityInvocations;
+} VkPhysicalDeviceFragmentDensityMapPropertiesEXT;
+
+typedef struct VkRenderPassFragmentDensityMapCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkAttachmentReference fragmentDensityMapAttachment;
+} VkRenderPassFragmentDensityMapCreateInfoEXT;
+
+
+
+#define VK_EXT_scalar_block_layout 1
+#define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1
+#define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout"
+typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLayoutFeaturesEXT;
+
+
+
+#define VK_GOOGLE_hlsl_functionality1 1
+#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION 1
+#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1"
+#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION
+#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME
+
+
+#define VK_GOOGLE_decorate_string 1
+#define VK_GOOGLE_DECORATE_STRING_SPEC_VERSION 1
+#define VK_GOOGLE_DECORATE_STRING_EXTENSION_NAME "VK_GOOGLE_decorate_string"
+
+
+#define VK_EXT_subgroup_size_control 1
+#define VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION 2
+#define VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME "VK_EXT_subgroup_size_control"
+typedef VkPhysicalDeviceSubgroupSizeControlFeatures VkPhysicalDeviceSubgroupSizeControlFeaturesEXT;
+
+typedef VkPhysicalDeviceSubgroupSizeControlProperties VkPhysicalDeviceSubgroupSizeControlPropertiesEXT;
+
+typedef VkPipelineShaderStageRequiredSubgroupSizeCreateInfo VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT;
+
+
+
+#define VK_AMD_shader_core_properties2 1
+#define VK_AMD_SHADER_CORE_PROPERTIES_2_SPEC_VERSION 1
+#define VK_AMD_SHADER_CORE_PROPERTIES_2_EXTENSION_NAME "VK_AMD_shader_core_properties2"
+
+typedef enum VkShaderCorePropertiesFlagBitsAMD {
+ VK_SHADER_CORE_PROPERTIES_FLAG_BITS_MAX_ENUM_AMD = 0x7FFFFFFF
+} VkShaderCorePropertiesFlagBitsAMD;
+typedef VkFlags VkShaderCorePropertiesFlagsAMD;
+typedef struct VkPhysicalDeviceShaderCoreProperties2AMD {
+ VkStructureType sType;
+ void* pNext;
+ VkShaderCorePropertiesFlagsAMD shaderCoreFeatures;
+ uint32_t activeComputeUnitCount;
+} VkPhysicalDeviceShaderCoreProperties2AMD;
+
+
+
+#define VK_AMD_device_coherent_memory 1
+#define VK_AMD_DEVICE_COHERENT_MEMORY_SPEC_VERSION 1
+#define VK_AMD_DEVICE_COHERENT_MEMORY_EXTENSION_NAME "VK_AMD_device_coherent_memory"
+typedef struct VkPhysicalDeviceCoherentMemoryFeaturesAMD {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 deviceCoherentMemory;
+} VkPhysicalDeviceCoherentMemoryFeaturesAMD;
+
+
+
+#define VK_EXT_shader_image_atomic_int64 1
+#define VK_EXT_SHADER_IMAGE_ATOMIC_INT64_SPEC_VERSION 1
+#define VK_EXT_SHADER_IMAGE_ATOMIC_INT64_EXTENSION_NAME "VK_EXT_shader_image_atomic_int64"
+typedef struct VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderImageInt64Atomics;
+ VkBool32 sparseImageInt64Atomics;
+} VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT;
+
+
+
+#define VK_EXT_memory_budget 1
+#define VK_EXT_MEMORY_BUDGET_SPEC_VERSION 1
+#define VK_EXT_MEMORY_BUDGET_EXTENSION_NAME "VK_EXT_memory_budget"
+typedef struct VkPhysicalDeviceMemoryBudgetPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkDeviceSize heapBudget[VK_MAX_MEMORY_HEAPS];
+ VkDeviceSize heapUsage[VK_MAX_MEMORY_HEAPS];
+} VkPhysicalDeviceMemoryBudgetPropertiesEXT;
+
+
+
+#define VK_EXT_memory_priority 1
+#define VK_EXT_MEMORY_PRIORITY_SPEC_VERSION 1
+#define VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME "VK_EXT_memory_priority"
+typedef struct VkPhysicalDeviceMemoryPriorityFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 memoryPriority;
+} VkPhysicalDeviceMemoryPriorityFeaturesEXT;
+
+typedef struct VkMemoryPriorityAllocateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ float priority;
+} VkMemoryPriorityAllocateInfoEXT;
+
+
+
+#define VK_NV_dedicated_allocation_image_aliasing 1
+#define VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_SPEC_VERSION 1
+#define VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_EXTENSION_NAME "VK_NV_dedicated_allocation_image_aliasing"
+typedef struct VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 dedicatedAllocationImageAliasing;
+} VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV;
+
+
+
+#define VK_EXT_buffer_device_address 1
+#define VK_EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 2
+#define VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_EXT_buffer_device_address"
+typedef struct VkPhysicalDeviceBufferDeviceAddressFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 bufferDeviceAddress;
+ VkBool32 bufferDeviceAddressCaptureReplay;
+ VkBool32 bufferDeviceAddressMultiDevice;
+} VkPhysicalDeviceBufferDeviceAddressFeaturesEXT;
+
+typedef VkPhysicalDeviceBufferDeviceAddressFeaturesEXT VkPhysicalDeviceBufferAddressFeaturesEXT;
+
+typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoEXT;
+
+typedef struct VkBufferDeviceAddressCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceAddress deviceAddress;
+} VkBufferDeviceAddressCreateInfoEXT;
+
+typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT(
+ VkDevice device,
+ const VkBufferDeviceAddressInfo* pInfo);
+#endif
+
+
+#define VK_EXT_tooling_info 1
+#define VK_EXT_TOOLING_INFO_SPEC_VERSION 1
+#define VK_EXT_TOOLING_INFO_EXTENSION_NAME "VK_EXT_tooling_info"
+typedef VkToolPurposeFlagBits VkToolPurposeFlagBitsEXT;
+
+typedef VkToolPurposeFlags VkToolPurposeFlagsEXT;
+
+typedef VkPhysicalDeviceToolProperties VkPhysicalDeviceToolPropertiesEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolPropertiesEXT(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pToolCount,
+ VkPhysicalDeviceToolProperties* pToolProperties);
+#endif
+
+
+#define VK_EXT_separate_stencil_usage 1
+#define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1
+#define VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME "VK_EXT_separate_stencil_usage"
+typedef VkImageStencilUsageCreateInfo VkImageStencilUsageCreateInfoEXT;
+
+
+
+#define VK_EXT_validation_features 1
+#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 5
+#define VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME "VK_EXT_validation_features"
+
+typedef enum VkValidationFeatureEnableEXT {
+ VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT = 0,
+ VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT = 1,
+ VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT = 2,
+ VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT = 3,
+ VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT = 4,
+ VK_VALIDATION_FEATURE_ENABLE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkValidationFeatureEnableEXT;
+
+typedef enum VkValidationFeatureDisableEXT {
+ VK_VALIDATION_FEATURE_DISABLE_ALL_EXT = 0,
+ VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT = 1,
+ VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT = 2,
+ VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT = 3,
+ VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT = 4,
+ VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT = 5,
+ VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT = 6,
+ VK_VALIDATION_FEATURE_DISABLE_SHADER_VALIDATION_CACHE_EXT = 7,
+ VK_VALIDATION_FEATURE_DISABLE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkValidationFeatureDisableEXT;
+typedef struct VkValidationFeaturesEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t enabledValidationFeatureCount;
+ const VkValidationFeatureEnableEXT* pEnabledValidationFeatures;
+ uint32_t disabledValidationFeatureCount;
+ const VkValidationFeatureDisableEXT* pDisabledValidationFeatures;
+} VkValidationFeaturesEXT;
+
+
+
+#define VK_NV_cooperative_matrix 1
+#define VK_NV_COOPERATIVE_MATRIX_SPEC_VERSION 1
+#define VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME "VK_NV_cooperative_matrix"
+
+typedef enum VkComponentTypeNV {
+ VK_COMPONENT_TYPE_FLOAT16_NV = 0,
+ VK_COMPONENT_TYPE_FLOAT32_NV = 1,
+ VK_COMPONENT_TYPE_FLOAT64_NV = 2,
+ VK_COMPONENT_TYPE_SINT8_NV = 3,
+ VK_COMPONENT_TYPE_SINT16_NV = 4,
+ VK_COMPONENT_TYPE_SINT32_NV = 5,
+ VK_COMPONENT_TYPE_SINT64_NV = 6,
+ VK_COMPONENT_TYPE_UINT8_NV = 7,
+ VK_COMPONENT_TYPE_UINT16_NV = 8,
+ VK_COMPONENT_TYPE_UINT32_NV = 9,
+ VK_COMPONENT_TYPE_UINT64_NV = 10,
+ VK_COMPONENT_TYPE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkComponentTypeNV;
+
+typedef enum VkScopeNV {
+ VK_SCOPE_DEVICE_NV = 1,
+ VK_SCOPE_WORKGROUP_NV = 2,
+ VK_SCOPE_SUBGROUP_NV = 3,
+ VK_SCOPE_QUEUE_FAMILY_NV = 5,
+ VK_SCOPE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkScopeNV;
+typedef struct VkCooperativeMatrixPropertiesNV {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t MSize;
+ uint32_t NSize;
+ uint32_t KSize;
+ VkComponentTypeNV AType;
+ VkComponentTypeNV BType;
+ VkComponentTypeNV CType;
+ VkComponentTypeNV DType;
+ VkScopeNV scope;
+} VkCooperativeMatrixPropertiesNV;
+
+typedef struct VkPhysicalDeviceCooperativeMatrixFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 cooperativeMatrix;
+ VkBool32 cooperativeMatrixRobustBufferAccess;
+} VkPhysicalDeviceCooperativeMatrixFeaturesNV;
+
+typedef struct VkPhysicalDeviceCooperativeMatrixPropertiesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkShaderStageFlags cooperativeMatrixSupportedStages;
+} VkPhysicalDeviceCooperativeMatrixPropertiesNV;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkCooperativeMatrixPropertiesNV* pProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCooperativeMatrixPropertiesNV(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pPropertyCount,
+ VkCooperativeMatrixPropertiesNV* pProperties);
+#endif
+
+
+#define VK_NV_coverage_reduction_mode 1
+#define VK_NV_COVERAGE_REDUCTION_MODE_SPEC_VERSION 1
+#define VK_NV_COVERAGE_REDUCTION_MODE_EXTENSION_NAME "VK_NV_coverage_reduction_mode"
+
+typedef enum VkCoverageReductionModeNV {
+ VK_COVERAGE_REDUCTION_MODE_MERGE_NV = 0,
+ VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV = 1,
+ VK_COVERAGE_REDUCTION_MODE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkCoverageReductionModeNV;
+typedef VkFlags VkPipelineCoverageReductionStateCreateFlagsNV;
+typedef struct VkPhysicalDeviceCoverageReductionModeFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 coverageReductionMode;
+} VkPhysicalDeviceCoverageReductionModeFeaturesNV;
+
+typedef struct VkPipelineCoverageReductionStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCoverageReductionStateCreateFlagsNV flags;
+ VkCoverageReductionModeNV coverageReductionMode;
+} VkPipelineCoverageReductionStateCreateInfoNV;
+
+typedef struct VkFramebufferMixedSamplesCombinationNV {
+ VkStructureType sType;
+ void* pNext;
+ VkCoverageReductionModeNV coverageReductionMode;
+ VkSampleCountFlagBits rasterizationSamples;
+ VkSampleCountFlags depthStencilSamples;
+ VkSampleCountFlags colorSamples;
+} VkFramebufferMixedSamplesCombinationNV;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV)(VkPhysicalDevice physicalDevice, uint32_t* pCombinationCount, VkFramebufferMixedSamplesCombinationNV* pCombinations);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pCombinationCount,
+ VkFramebufferMixedSamplesCombinationNV* pCombinations);
+#endif
+
+
+#define VK_EXT_fragment_shader_interlock 1
+#define VK_EXT_FRAGMENT_SHADER_INTERLOCK_SPEC_VERSION 1
+#define VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME "VK_EXT_fragment_shader_interlock"
+typedef struct VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 fragmentShaderSampleInterlock;
+ VkBool32 fragmentShaderPixelInterlock;
+ VkBool32 fragmentShaderShadingRateInterlock;
+} VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT;
+
+
+
+#define VK_EXT_ycbcr_image_arrays 1
+#define VK_EXT_YCBCR_IMAGE_ARRAYS_SPEC_VERSION 1
+#define VK_EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME "VK_EXT_ycbcr_image_arrays"
+typedef struct VkPhysicalDeviceYcbcrImageArraysFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 ycbcrImageArrays;
+} VkPhysicalDeviceYcbcrImageArraysFeaturesEXT;
+
+
+
+#define VK_EXT_provoking_vertex 1
+#define VK_EXT_PROVOKING_VERTEX_SPEC_VERSION 1
+#define VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME "VK_EXT_provoking_vertex"
+
+typedef enum VkProvokingVertexModeEXT {
+ VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT = 0,
+ VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT = 1,
+ VK_PROVOKING_VERTEX_MODE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkProvokingVertexModeEXT;
+typedef struct VkPhysicalDeviceProvokingVertexFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 provokingVertexLast;
+ VkBool32 transformFeedbackPreservesProvokingVertex;
+} VkPhysicalDeviceProvokingVertexFeaturesEXT;
+
+typedef struct VkPhysicalDeviceProvokingVertexPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 provokingVertexModePerPipeline;
+ VkBool32 transformFeedbackPreservesTriangleFanProvokingVertex;
+} VkPhysicalDeviceProvokingVertexPropertiesEXT;
+
+typedef struct VkPipelineRasterizationProvokingVertexStateCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkProvokingVertexModeEXT provokingVertexMode;
+} VkPipelineRasterizationProvokingVertexStateCreateInfoEXT;
+
+
+
+#define VK_EXT_headless_surface 1
+#define VK_EXT_HEADLESS_SURFACE_SPEC_VERSION 1
+#define VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME "VK_EXT_headless_surface"
+typedef VkFlags VkHeadlessSurfaceCreateFlagsEXT;
+typedef struct VkHeadlessSurfaceCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkHeadlessSurfaceCreateFlagsEXT flags;
+} VkHeadlessSurfaceCreateInfoEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateHeadlessSurfaceEXT)(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateHeadlessSurfaceEXT(
+ VkInstance instance,
+ const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+#endif
+
+
+#define VK_EXT_line_rasterization 1
+#define VK_EXT_LINE_RASTERIZATION_SPEC_VERSION 1
+#define VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME "VK_EXT_line_rasterization"
+
+typedef enum VkLineRasterizationModeEXT {
+ VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT = 0,
+ VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT = 1,
+ VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT = 2,
+ VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT = 3,
+ VK_LINE_RASTERIZATION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkLineRasterizationModeEXT;
+typedef struct VkPhysicalDeviceLineRasterizationFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 rectangularLines;
+ VkBool32 bresenhamLines;
+ VkBool32 smoothLines;
+ VkBool32 stippledRectangularLines;
+ VkBool32 stippledBresenhamLines;
+ VkBool32 stippledSmoothLines;
+} VkPhysicalDeviceLineRasterizationFeaturesEXT;
+
+typedef struct VkPhysicalDeviceLineRasterizationPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t lineSubPixelPrecisionBits;
+} VkPhysicalDeviceLineRasterizationPropertiesEXT;
+
+typedef struct VkPipelineRasterizationLineStateCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkLineRasterizationModeEXT lineRasterizationMode;
+ VkBool32 stippledLineEnable;
+ uint32_t lineStippleFactor;
+ uint16_t lineStipplePattern;
+} VkPipelineRasterizationLineStateCreateInfoEXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetLineStippleEXT)(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStippleEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t lineStippleFactor,
+ uint16_t lineStipplePattern);
+#endif
+
+
+#define VK_EXT_shader_atomic_float 1
+#define VK_EXT_SHADER_ATOMIC_FLOAT_SPEC_VERSION 1
+#define VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME "VK_EXT_shader_atomic_float"
+typedef struct VkPhysicalDeviceShaderAtomicFloatFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderBufferFloat32Atomics;
+ VkBool32 shaderBufferFloat32AtomicAdd;
+ VkBool32 shaderBufferFloat64Atomics;
+ VkBool32 shaderBufferFloat64AtomicAdd;
+ VkBool32 shaderSharedFloat32Atomics;
+ VkBool32 shaderSharedFloat32AtomicAdd;
+ VkBool32 shaderSharedFloat64Atomics;
+ VkBool32 shaderSharedFloat64AtomicAdd;
+ VkBool32 shaderImageFloat32Atomics;
+ VkBool32 shaderImageFloat32AtomicAdd;
+ VkBool32 sparseImageFloat32Atomics;
+ VkBool32 sparseImageFloat32AtomicAdd;
+} VkPhysicalDeviceShaderAtomicFloatFeaturesEXT;
+
+
+
+#define VK_EXT_host_query_reset 1
+#define VK_EXT_HOST_QUERY_RESET_SPEC_VERSION 1
+#define VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME "VK_EXT_host_query_reset"
+typedef VkPhysicalDeviceHostQueryResetFeatures VkPhysicalDeviceHostQueryResetFeaturesEXT;
+
+typedef void (VKAPI_PTR *PFN_vkResetQueryPoolEXT)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkResetQueryPoolEXT(
+ VkDevice device,
+ VkQueryPool queryPool,
+ uint32_t firstQuery,
+ uint32_t queryCount);
+#endif
+
+
+#define VK_EXT_index_type_uint8 1
+#define VK_EXT_INDEX_TYPE_UINT8_SPEC_VERSION 1
+#define VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME "VK_EXT_index_type_uint8"
+typedef struct VkPhysicalDeviceIndexTypeUint8FeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 indexTypeUint8;
+} VkPhysicalDeviceIndexTypeUint8FeaturesEXT;
+
+
+
+#define VK_EXT_extended_dynamic_state 1
+#define VK_EXT_EXTENDED_DYNAMIC_STATE_SPEC_VERSION 1
+#define VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME "VK_EXT_extended_dynamic_state"
+typedef struct VkPhysicalDeviceExtendedDynamicStateFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 extendedDynamicState;
+} VkPhysicalDeviceExtendedDynamicStateFeaturesEXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetCullModeEXT)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode);
+typedef void (VKAPI_PTR *PFN_vkCmdSetFrontFaceEXT)(VkCommandBuffer commandBuffer, VkFrontFace frontFace);
+typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveTopologyEXT)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology);
+typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWithCountEXT)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport* pViewports);
+typedef void (VKAPI_PTR *PFN_vkCmdSetScissorWithCountEXT)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors);
+typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers2EXT)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthWriteEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthCompareOpEXT)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBoundsTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetStencilTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOpEXT)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCullModeEXT(
+ VkCommandBuffer commandBuffer,
+ VkCullModeFlags cullMode);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFaceEXT(
+ VkCommandBuffer commandBuffer,
+ VkFrontFace frontFace);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopologyEXT(
+ VkCommandBuffer commandBuffer,
+ VkPrimitiveTopology primitiveTopology);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCountEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t viewportCount,
+ const VkViewport* pViewports);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCountEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t scissorCount,
+ const VkRect2D* pScissors);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2EXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstBinding,
+ uint32_t bindingCount,
+ const VkBuffer* pBuffers,
+ const VkDeviceSize* pOffsets,
+ const VkDeviceSize* pSizes,
+ const VkDeviceSize* pStrides);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 depthTestEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 depthWriteEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOpEXT(
+ VkCommandBuffer commandBuffer,
+ VkCompareOp depthCompareOp);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 depthBoundsTestEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 stencilTestEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOpEXT(
+ VkCommandBuffer commandBuffer,
+ VkStencilFaceFlags faceMask,
+ VkStencilOp failOp,
+ VkStencilOp passOp,
+ VkStencilOp depthFailOp,
+ VkCompareOp compareOp);
+#endif
+
+
+#define VK_EXT_shader_atomic_float2 1
+#define VK_EXT_SHADER_ATOMIC_FLOAT_2_SPEC_VERSION 1
+#define VK_EXT_SHADER_ATOMIC_FLOAT_2_EXTENSION_NAME "VK_EXT_shader_atomic_float2"
+typedef struct VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderBufferFloat16Atomics;
+ VkBool32 shaderBufferFloat16AtomicAdd;
+ VkBool32 shaderBufferFloat16AtomicMinMax;
+ VkBool32 shaderBufferFloat32AtomicMinMax;
+ VkBool32 shaderBufferFloat64AtomicMinMax;
+ VkBool32 shaderSharedFloat16Atomics;
+ VkBool32 shaderSharedFloat16AtomicAdd;
+ VkBool32 shaderSharedFloat16AtomicMinMax;
+ VkBool32 shaderSharedFloat32AtomicMinMax;
+ VkBool32 shaderSharedFloat64AtomicMinMax;
+ VkBool32 shaderImageFloat32AtomicMinMax;
+ VkBool32 sparseImageFloat32AtomicMinMax;
+} VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT;
+
+
+
+#define VK_EXT_shader_demote_to_helper_invocation 1
+#define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION 1
+#define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME "VK_EXT_shader_demote_to_helper_invocation"
+typedef VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT;
+
+
+
+#define VK_NV_device_generated_commands 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNV)
+#define VK_NV_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 3
+#define VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_NV_device_generated_commands"
+
+typedef enum VkIndirectCommandsTokenTypeNV {
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV = 0,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV = 1,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV = 2,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV = 3,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV = 4,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV = 5,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV = 6,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_TASKS_NV = 7,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_NV = 1000328000,
+ VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkIndirectCommandsTokenTypeNV;
+
+typedef enum VkIndirectStateFlagBitsNV {
+ VK_INDIRECT_STATE_FLAG_FRONTFACE_BIT_NV = 0x00000001,
+ VK_INDIRECT_STATE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF
+} VkIndirectStateFlagBitsNV;
+typedef VkFlags VkIndirectStateFlagsNV;
+
+typedef enum VkIndirectCommandsLayoutUsageFlagBitsNV {
+ VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EXPLICIT_PREPROCESS_BIT_NV = 0x00000001,
+ VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NV = 0x00000002,
+ VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NV = 0x00000004,
+ VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF
+} VkIndirectCommandsLayoutUsageFlagBitsNV;
+typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNV;
+typedef struct VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxGraphicsShaderGroupCount;
+ uint32_t maxIndirectSequenceCount;
+ uint32_t maxIndirectCommandsTokenCount;
+ uint32_t maxIndirectCommandsStreamCount;
+ uint32_t maxIndirectCommandsTokenOffset;
+ uint32_t maxIndirectCommandsStreamStride;
+ uint32_t minSequencesCountBufferOffsetAlignment;
+ uint32_t minSequencesIndexBufferOffsetAlignment;
+ uint32_t minIndirectCommandsBufferOffsetAlignment;
+} VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV;
+
+typedef struct VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 deviceGeneratedCommands;
+} VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV;
+
+typedef struct VkGraphicsShaderGroupCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t stageCount;
+ const VkPipelineShaderStageCreateInfo* pStages;
+ const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
+ const VkPipelineTessellationStateCreateInfo* pTessellationState;
+} VkGraphicsShaderGroupCreateInfoNV;
+
+typedef struct VkGraphicsPipelineShaderGroupsCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t groupCount;
+ const VkGraphicsShaderGroupCreateInfoNV* pGroups;
+ uint32_t pipelineCount;
+ const VkPipeline* pPipelines;
+} VkGraphicsPipelineShaderGroupsCreateInfoNV;
+
+typedef struct VkBindShaderGroupIndirectCommandNV {
+ uint32_t groupIndex;
+} VkBindShaderGroupIndirectCommandNV;
+
+typedef struct VkBindIndexBufferIndirectCommandNV {
+ VkDeviceAddress bufferAddress;
+ uint32_t size;
+ VkIndexType indexType;
+} VkBindIndexBufferIndirectCommandNV;
+
+typedef struct VkBindVertexBufferIndirectCommandNV {
+ VkDeviceAddress bufferAddress;
+ uint32_t size;
+ uint32_t stride;
+} VkBindVertexBufferIndirectCommandNV;
+
+typedef struct VkSetStateFlagsIndirectCommandNV {
+ uint32_t data;
+} VkSetStateFlagsIndirectCommandNV;
+
+typedef struct VkIndirectCommandsStreamNV {
+ VkBuffer buffer;
+ VkDeviceSize offset;
+} VkIndirectCommandsStreamNV;
+
+typedef struct VkIndirectCommandsLayoutTokenNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkIndirectCommandsTokenTypeNV tokenType;
+ uint32_t stream;
+ uint32_t offset;
+ uint32_t vertexBindingUnit;
+ VkBool32 vertexDynamicStride;
+ VkPipelineLayout pushconstantPipelineLayout;
+ VkShaderStageFlags pushconstantShaderStageFlags;
+ uint32_t pushconstantOffset;
+ uint32_t pushconstantSize;
+ VkIndirectStateFlagsNV indirectStateFlags;
+ uint32_t indexTypeCount;
+ const VkIndexType* pIndexTypes;
+ const uint32_t* pIndexTypeValues;
+} VkIndirectCommandsLayoutTokenNV;
+
+typedef struct VkIndirectCommandsLayoutCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkIndirectCommandsLayoutUsageFlagsNV flags;
+ VkPipelineBindPoint pipelineBindPoint;
+ uint32_t tokenCount;
+ const VkIndirectCommandsLayoutTokenNV* pTokens;
+ uint32_t streamCount;
+ const uint32_t* pStreamStrides;
+} VkIndirectCommandsLayoutCreateInfoNV;
+
+typedef struct VkGeneratedCommandsInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineBindPoint pipelineBindPoint;
+ VkPipeline pipeline;
+ VkIndirectCommandsLayoutNV indirectCommandsLayout;
+ uint32_t streamCount;
+ const VkIndirectCommandsStreamNV* pStreams;
+ uint32_t sequencesCount;
+ VkBuffer preprocessBuffer;
+ VkDeviceSize preprocessOffset;
+ VkDeviceSize preprocessSize;
+ VkBuffer sequencesCountBuffer;
+ VkDeviceSize sequencesCountOffset;
+ VkBuffer sequencesIndexBuffer;
+ VkDeviceSize sequencesIndexOffset;
+} VkGeneratedCommandsInfoNV;
+
+typedef struct VkGeneratedCommandsMemoryRequirementsInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineBindPoint pipelineBindPoint;
+ VkPipeline pipeline;
+ VkIndirectCommandsLayoutNV indirectCommandsLayout;
+ uint32_t maxSequencesCount;
+} VkGeneratedCommandsMemoryRequirementsInfoNV;
+
+typedef void (VKAPI_PTR *PFN_vkGetGeneratedCommandsMemoryRequirementsNV)(VkDevice device, const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2* pMemoryRequirements);
+typedef void (VKAPI_PTR *PFN_vkCmdPreprocessGeneratedCommandsNV)(VkCommandBuffer commandBuffer, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdExecuteGeneratedCommandsNV)(VkCommandBuffer commandBuffer, VkBool32 isPreprocessed, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdBindPipelineShaderGroupNV)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline, uint32_t groupIndex);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNV)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNV* pIndirectCommandsLayout);
+typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNV)(VkDevice device, VkIndirectCommandsLayoutNV indirectCommandsLayout, const VkAllocationCallbacks* pAllocator);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetGeneratedCommandsMemoryRequirementsNV(
+ VkDevice device,
+ const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdPreprocessGeneratedCommandsNV(
+ VkCommandBuffer commandBuffer,
+ const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdExecuteGeneratedCommandsNV(
+ VkCommandBuffer commandBuffer,
+ VkBool32 isPreprocessed,
+ const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBindPipelineShaderGroupNV(
+ VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipeline pipeline,
+ uint32_t groupIndex);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNV(
+ VkDevice device,
+ const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkIndirectCommandsLayoutNV* pIndirectCommandsLayout);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNV(
+ VkDevice device,
+ VkIndirectCommandsLayoutNV indirectCommandsLayout,
+ const VkAllocationCallbacks* pAllocator);
+#endif
+
+
+#define VK_NV_inherited_viewport_scissor 1
+#define VK_NV_INHERITED_VIEWPORT_SCISSOR_SPEC_VERSION 1
+#define VK_NV_INHERITED_VIEWPORT_SCISSOR_EXTENSION_NAME "VK_NV_inherited_viewport_scissor"
+typedef struct VkPhysicalDeviceInheritedViewportScissorFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 inheritedViewportScissor2D;
+} VkPhysicalDeviceInheritedViewportScissorFeaturesNV;
+
+typedef struct VkCommandBufferInheritanceViewportScissorInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 viewportScissor2D;
+ uint32_t viewportDepthCount;
+ const VkViewport* pViewportDepths;
+} VkCommandBufferInheritanceViewportScissorInfoNV;
+
+
+
+#define VK_EXT_texel_buffer_alignment 1
+#define VK_EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION 1
+#define VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME "VK_EXT_texel_buffer_alignment"
+typedef struct VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 texelBufferAlignment;
+} VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT;
+
+typedef VkPhysicalDeviceTexelBufferAlignmentProperties VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT;
+
+
+
+#define VK_QCOM_render_pass_transform 1
+#define VK_QCOM_RENDER_PASS_TRANSFORM_SPEC_VERSION 3
+#define VK_QCOM_RENDER_PASS_TRANSFORM_EXTENSION_NAME "VK_QCOM_render_pass_transform"
+typedef struct VkRenderPassTransformBeginInfoQCOM {
+ VkStructureType sType;
+ void* pNext;
+ VkSurfaceTransformFlagBitsKHR transform;
+} VkRenderPassTransformBeginInfoQCOM;
+
+typedef struct VkCommandBufferInheritanceRenderPassTransformInfoQCOM {
+ VkStructureType sType;
+ void* pNext;
+ VkSurfaceTransformFlagBitsKHR transform;
+ VkRect2D renderArea;
+} VkCommandBufferInheritanceRenderPassTransformInfoQCOM;
+
+
+
+#define VK_EXT_device_memory_report 1
+#define VK_EXT_DEVICE_MEMORY_REPORT_SPEC_VERSION 2
+#define VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME "VK_EXT_device_memory_report"
+
+typedef enum VkDeviceMemoryReportEventTypeEXT {
+ VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT = 0,
+ VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT = 1,
+ VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT = 2,
+ VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT = 3,
+ VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATION_FAILED_EXT = 4,
+ VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDeviceMemoryReportEventTypeEXT;
+typedef VkFlags VkDeviceMemoryReportFlagsEXT;
+typedef struct VkPhysicalDeviceDeviceMemoryReportFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 deviceMemoryReport;
+} VkPhysicalDeviceDeviceMemoryReportFeaturesEXT;
+
+typedef struct VkDeviceMemoryReportCallbackDataEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkDeviceMemoryReportFlagsEXT flags;
+ VkDeviceMemoryReportEventTypeEXT type;
+ uint64_t memoryObjectId;
+ VkDeviceSize size;
+ VkObjectType objectType;
+ uint64_t objectHandle;
+ uint32_t heapIndex;
+} VkDeviceMemoryReportCallbackDataEXT;
+
+typedef void (VKAPI_PTR *PFN_vkDeviceMemoryReportCallbackEXT)(
+ const VkDeviceMemoryReportCallbackDataEXT* pCallbackData,
+ void* pUserData);
+
+typedef struct VkDeviceDeviceMemoryReportCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceMemoryReportFlagsEXT flags;
+ PFN_vkDeviceMemoryReportCallbackEXT pfnUserCallback;
+ void* pUserData;
+} VkDeviceDeviceMemoryReportCreateInfoEXT;
+
+
+
+#define VK_EXT_acquire_drm_display 1
+#define VK_EXT_ACQUIRE_DRM_DISPLAY_SPEC_VERSION 1
+#define VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_drm_display"
+typedef VkResult (VKAPI_PTR *PFN_vkAcquireDrmDisplayEXT)(VkPhysicalDevice physicalDevice, int32_t drmFd, VkDisplayKHR display);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDrmDisplayEXT)(VkPhysicalDevice physicalDevice, int32_t drmFd, uint32_t connectorId, VkDisplayKHR* display);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireDrmDisplayEXT(
+ VkPhysicalDevice physicalDevice,
+ int32_t drmFd,
+ VkDisplayKHR display);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDrmDisplayEXT(
+ VkPhysicalDevice physicalDevice,
+ int32_t drmFd,
+ uint32_t connectorId,
+ VkDisplayKHR* display);
+#endif
+
+
+#define VK_EXT_robustness2 1
+#define VK_EXT_ROBUSTNESS_2_SPEC_VERSION 1
+#define VK_EXT_ROBUSTNESS_2_EXTENSION_NAME "VK_EXT_robustness2"
+typedef struct VkPhysicalDeviceRobustness2FeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 robustBufferAccess2;
+ VkBool32 robustImageAccess2;
+ VkBool32 nullDescriptor;
+} VkPhysicalDeviceRobustness2FeaturesEXT;
+
+typedef struct VkPhysicalDeviceRobustness2PropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkDeviceSize robustStorageBufferAccessSizeAlignment;
+ VkDeviceSize robustUniformBufferAccessSizeAlignment;
+} VkPhysicalDeviceRobustness2PropertiesEXT;
+
+
+
+#define VK_EXT_custom_border_color 1
+#define VK_EXT_CUSTOM_BORDER_COLOR_SPEC_VERSION 12
+#define VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME "VK_EXT_custom_border_color"
+typedef struct VkSamplerCustomBorderColorCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkClearColorValue customBorderColor;
+ VkFormat format;
+} VkSamplerCustomBorderColorCreateInfoEXT;
+
+typedef struct VkPhysicalDeviceCustomBorderColorPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxCustomBorderColorSamplers;
+} VkPhysicalDeviceCustomBorderColorPropertiesEXT;
+
+typedef struct VkPhysicalDeviceCustomBorderColorFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 customBorderColors;
+ VkBool32 customBorderColorWithoutFormat;
+} VkPhysicalDeviceCustomBorderColorFeaturesEXT;
+
+
+
+#define VK_GOOGLE_user_type 1
+#define VK_GOOGLE_USER_TYPE_SPEC_VERSION 1
+#define VK_GOOGLE_USER_TYPE_EXTENSION_NAME "VK_GOOGLE_user_type"
+
+
+#define VK_NV_present_barrier 1
+#define VK_NV_PRESENT_BARRIER_SPEC_VERSION 1
+#define VK_NV_PRESENT_BARRIER_EXTENSION_NAME "VK_NV_present_barrier"
+typedef struct VkPhysicalDevicePresentBarrierFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 presentBarrier;
+} VkPhysicalDevicePresentBarrierFeaturesNV;
+
+typedef struct VkSurfaceCapabilitiesPresentBarrierNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 presentBarrierSupported;
+} VkSurfaceCapabilitiesPresentBarrierNV;
+
+typedef struct VkSwapchainPresentBarrierCreateInfoNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 presentBarrierEnable;
+} VkSwapchainPresentBarrierCreateInfoNV;
+
+
+
+#define VK_EXT_private_data 1
+typedef VkPrivateDataSlot VkPrivateDataSlotEXT;
+
+#define VK_EXT_PRIVATE_DATA_SPEC_VERSION 1
+#define VK_EXT_PRIVATE_DATA_EXTENSION_NAME "VK_EXT_private_data"
+typedef VkPrivateDataSlotCreateFlags VkPrivateDataSlotCreateFlagsEXT;
+
+typedef VkPhysicalDevicePrivateDataFeatures VkPhysicalDevicePrivateDataFeaturesEXT;
+
+typedef VkDevicePrivateDataCreateInfo VkDevicePrivateDataCreateInfoEXT;
+
+typedef VkPrivateDataSlotCreateInfo VkPrivateDataSlotCreateInfoEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlotEXT)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot);
+typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlotEXT)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data);
+typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlotEXT(
+ VkDevice device,
+ const VkPrivateDataSlotCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkPrivateDataSlot* pPrivateDataSlot);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlotEXT(
+ VkDevice device,
+ VkPrivateDataSlot privateDataSlot,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateDataEXT(
+ VkDevice device,
+ VkObjectType objectType,
+ uint64_t objectHandle,
+ VkPrivateDataSlot privateDataSlot,
+ uint64_t data);
+
+VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT(
+ VkDevice device,
+ VkObjectType objectType,
+ uint64_t objectHandle,
+ VkPrivateDataSlot privateDataSlot,
+ uint64_t* pData);
+#endif
+
+
+#define VK_EXT_pipeline_creation_cache_control 1
+#define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_SPEC_VERSION 3
+#define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME "VK_EXT_pipeline_creation_cache_control"
+typedef VkPhysicalDevicePipelineCreationCacheControlFeatures VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT;
+
+
+
+#define VK_NV_device_diagnostics_config 1
+#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_SPEC_VERSION 2
+#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME "VK_NV_device_diagnostics_config"
+
+typedef enum VkDeviceDiagnosticsConfigFlagBitsNV {
+ VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV = 0x00000001,
+ VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV = 0x00000002,
+ VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV = 0x00000004,
+ VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_ERROR_REPORTING_BIT_NV = 0x00000008,
+ VK_DEVICE_DIAGNOSTICS_CONFIG_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF
+} VkDeviceDiagnosticsConfigFlagBitsNV;
+typedef VkFlags VkDeviceDiagnosticsConfigFlagsNV;
+typedef struct VkPhysicalDeviceDiagnosticsConfigFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 diagnosticsConfig;
+} VkPhysicalDeviceDiagnosticsConfigFeaturesNV;
+
+typedef struct VkDeviceDiagnosticsConfigCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceDiagnosticsConfigFlagsNV flags;
+} VkDeviceDiagnosticsConfigCreateInfoNV;
+
+
+
+#define VK_QCOM_render_pass_store_ops 1
+#define VK_QCOM_RENDER_PASS_STORE_OPS_SPEC_VERSION 2
+#define VK_QCOM_RENDER_PASS_STORE_OPS_EXTENSION_NAME "VK_QCOM_render_pass_store_ops"
+
+
+#define VK_EXT_graphics_pipeline_library 1
+#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_SPEC_VERSION 1
+#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME "VK_EXT_graphics_pipeline_library"
+
+typedef enum VkGraphicsPipelineLibraryFlagBitsEXT {
+ VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT = 0x00000001,
+ VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT = 0x00000002,
+ VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT = 0x00000004,
+ VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT = 0x00000008,
+ VK_GRAPHICS_PIPELINE_LIBRARY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkGraphicsPipelineLibraryFlagBitsEXT;
+typedef VkFlags VkGraphicsPipelineLibraryFlagsEXT;
+typedef struct VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 graphicsPipelineLibrary;
+} VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT;
+
+typedef struct VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 graphicsPipelineLibraryFastLinking;
+ VkBool32 graphicsPipelineLibraryIndependentInterpolationDecoration;
+} VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT;
+
+typedef struct VkGraphicsPipelineLibraryCreateInfoEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkGraphicsPipelineLibraryFlagsEXT flags;
+} VkGraphicsPipelineLibraryCreateInfoEXT;
+
+
+
+#define VK_AMD_shader_early_and_late_fragment_tests 1
+#define VK_AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_SPEC_VERSION 1
+#define VK_AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_EXTENSION_NAME "VK_AMD_shader_early_and_late_fragment_tests"
+typedef struct VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderEarlyAndLateFragmentTests;
+} VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD;
+
+
+
+#define VK_NV_fragment_shading_rate_enums 1
+#define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_SPEC_VERSION 1
+#define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME "VK_NV_fragment_shading_rate_enums"
+
+typedef enum VkFragmentShadingRateTypeNV {
+ VK_FRAGMENT_SHADING_RATE_TYPE_FRAGMENT_SIZE_NV = 0,
+ VK_FRAGMENT_SHADING_RATE_TYPE_ENUMS_NV = 1,
+ VK_FRAGMENT_SHADING_RATE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkFragmentShadingRateTypeNV;
+
+typedef enum VkFragmentShadingRateNV {
+ VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV = 0,
+ VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV = 1,
+ VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV = 4,
+ VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV = 5,
+ VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV = 6,
+ VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV = 9,
+ VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV = 10,
+ VK_FRAGMENT_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV = 11,
+ VK_FRAGMENT_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV = 12,
+ VK_FRAGMENT_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV = 13,
+ VK_FRAGMENT_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV = 14,
+ VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV = 15,
+ VK_FRAGMENT_SHADING_RATE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkFragmentShadingRateNV;
+typedef struct VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 fragmentShadingRateEnums;
+ VkBool32 supersampleFragmentShadingRates;
+ VkBool32 noInvocationFragmentShadingRates;
+} VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV;
+
+typedef struct VkPhysicalDeviceFragmentShadingRateEnumsPropertiesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkSampleCountFlagBits maxFragmentShadingRateInvocationCount;
+} VkPhysicalDeviceFragmentShadingRateEnumsPropertiesNV;
+
+typedef struct VkPipelineFragmentShadingRateEnumStateCreateInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkFragmentShadingRateTypeNV shadingRateType;
+ VkFragmentShadingRateNV shadingRate;
+ VkFragmentShadingRateCombinerOpKHR combinerOps[2];
+} VkPipelineFragmentShadingRateEnumStateCreateInfoNV;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetFragmentShadingRateEnumNV)(VkCommandBuffer commandBuffer, VkFragmentShadingRateNV shadingRate, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetFragmentShadingRateEnumNV(
+ VkCommandBuffer commandBuffer,
+ VkFragmentShadingRateNV shadingRate,
+ const VkFragmentShadingRateCombinerOpKHR combinerOps[2]);
+#endif
+
+
+#define VK_NV_ray_tracing_motion_blur 1
+#define VK_NV_RAY_TRACING_MOTION_BLUR_SPEC_VERSION 1
+#define VK_NV_RAY_TRACING_MOTION_BLUR_EXTENSION_NAME "VK_NV_ray_tracing_motion_blur"
+
+typedef enum VkAccelerationStructureMotionInstanceTypeNV {
+ VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_STATIC_NV = 0,
+ VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_MATRIX_MOTION_NV = 1,
+ VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_SRT_MOTION_NV = 2,
+ VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF
+} VkAccelerationStructureMotionInstanceTypeNV;
+typedef VkFlags VkAccelerationStructureMotionInfoFlagsNV;
+typedef VkFlags VkAccelerationStructureMotionInstanceFlagsNV;
+typedef union VkDeviceOrHostAddressConstKHR {
+ VkDeviceAddress deviceAddress;
+ const void* hostAddress;
+} VkDeviceOrHostAddressConstKHR;
+
+typedef struct VkAccelerationStructureGeometryMotionTrianglesDataNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceOrHostAddressConstKHR vertexData;
+} VkAccelerationStructureGeometryMotionTrianglesDataNV;
+
+typedef struct VkAccelerationStructureMotionInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t maxInstances;
+ VkAccelerationStructureMotionInfoFlagsNV flags;
+} VkAccelerationStructureMotionInfoNV;
+
+typedef struct VkAccelerationStructureMatrixMotionInstanceNV {
+ VkTransformMatrixKHR transformT0;
+ VkTransformMatrixKHR transformT1;
+ uint32_t instanceCustomIndex:24;
+ uint32_t mask:8;
+ uint32_t instanceShaderBindingTableRecordOffset:24;
+ VkGeometryInstanceFlagsKHR flags:8;
+ uint64_t accelerationStructureReference;
+} VkAccelerationStructureMatrixMotionInstanceNV;
+
+typedef struct VkSRTDataNV {
+ float sx;
+ float a;
+ float b;
+ float pvx;
+ float sy;
+ float c;
+ float pvy;
+ float sz;
+ float pvz;
+ float qx;
+ float qy;
+ float qz;
+ float qw;
+ float tx;
+ float ty;
+ float tz;
+} VkSRTDataNV;
+
+typedef struct VkAccelerationStructureSRTMotionInstanceNV {
+ VkSRTDataNV transformT0;
+ VkSRTDataNV transformT1;
+ uint32_t instanceCustomIndex:24;
+ uint32_t mask:8;
+ uint32_t instanceShaderBindingTableRecordOffset:24;
+ VkGeometryInstanceFlagsKHR flags:8;
+ uint64_t accelerationStructureReference;
+} VkAccelerationStructureSRTMotionInstanceNV;
+
+typedef union VkAccelerationStructureMotionInstanceDataNV {
+ VkAccelerationStructureInstanceKHR staticInstance;
+ VkAccelerationStructureMatrixMotionInstanceNV matrixMotionInstance;
+ VkAccelerationStructureSRTMotionInstanceNV srtMotionInstance;
+} VkAccelerationStructureMotionInstanceDataNV;
+
+typedef struct VkAccelerationStructureMotionInstanceNV {
+ VkAccelerationStructureMotionInstanceTypeNV type;
+ VkAccelerationStructureMotionInstanceFlagsNV flags;
+ VkAccelerationStructureMotionInstanceDataNV data;
+} VkAccelerationStructureMotionInstanceNV;
+
+typedef struct VkPhysicalDeviceRayTracingMotionBlurFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 rayTracingMotionBlur;
+ VkBool32 rayTracingMotionBlurPipelineTraceRaysIndirect;
+} VkPhysicalDeviceRayTracingMotionBlurFeaturesNV;
+
+
+
+#define VK_EXT_ycbcr_2plane_444_formats 1
+#define VK_EXT_YCBCR_2PLANE_444_FORMATS_SPEC_VERSION 1
+#define VK_EXT_YCBCR_2PLANE_444_FORMATS_EXTENSION_NAME "VK_EXT_ycbcr_2plane_444_formats"
+typedef struct VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 ycbcr2plane444Formats;
+} VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT;
+
+
+
+#define VK_EXT_fragment_density_map2 1
+#define VK_EXT_FRAGMENT_DENSITY_MAP_2_SPEC_VERSION 1
+#define VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME "VK_EXT_fragment_density_map2"
+typedef struct VkPhysicalDeviceFragmentDensityMap2FeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 fragmentDensityMapDeferred;
+} VkPhysicalDeviceFragmentDensityMap2FeaturesEXT;
+
+typedef struct VkPhysicalDeviceFragmentDensityMap2PropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 subsampledLoads;
+ VkBool32 subsampledCoarseReconstructionEarlyAccess;
+ uint32_t maxSubsampledArrayLayers;
+ uint32_t maxDescriptorSetSubsampledSamplers;
+} VkPhysicalDeviceFragmentDensityMap2PropertiesEXT;
+
+
+
+#define VK_QCOM_rotated_copy_commands 1
+#define VK_QCOM_ROTATED_COPY_COMMANDS_SPEC_VERSION 1
+#define VK_QCOM_ROTATED_COPY_COMMANDS_EXTENSION_NAME "VK_QCOM_rotated_copy_commands"
+typedef struct VkCopyCommandTransformInfoQCOM {
+ VkStructureType sType;
+ const void* pNext;
+ VkSurfaceTransformFlagBitsKHR transform;
+} VkCopyCommandTransformInfoQCOM;
+
+
+
+#define VK_EXT_image_robustness 1
+#define VK_EXT_IMAGE_ROBUSTNESS_SPEC_VERSION 1
+#define VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_image_robustness"
+typedef VkPhysicalDeviceImageRobustnessFeatures VkPhysicalDeviceImageRobustnessFeaturesEXT;
+
+
+
+#define VK_EXT_image_compression_control 1
+#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SPEC_VERSION 1
+#define VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME "VK_EXT_image_compression_control"
+
+typedef enum VkImageCompressionFlagBitsEXT {
+ VK_IMAGE_COMPRESSION_DEFAULT_EXT = 0,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT = 0x00000001,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT = 0x00000002,
+ VK_IMAGE_COMPRESSION_DISABLED_EXT = 0x00000004,
+ VK_IMAGE_COMPRESSION_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkImageCompressionFlagBitsEXT;
+typedef VkFlags VkImageCompressionFlagsEXT;
+
+typedef enum VkImageCompressionFixedRateFlagBitsEXT {
+ VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT = 0,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_1BPC_BIT_EXT = 0x00000001,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_2BPC_BIT_EXT = 0x00000002,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_3BPC_BIT_EXT = 0x00000004,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_4BPC_BIT_EXT = 0x00000008,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_5BPC_BIT_EXT = 0x00000010,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_6BPC_BIT_EXT = 0x00000020,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_7BPC_BIT_EXT = 0x00000040,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_8BPC_BIT_EXT = 0x00000080,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_9BPC_BIT_EXT = 0x00000100,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_10BPC_BIT_EXT = 0x00000200,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_11BPC_BIT_EXT = 0x00000400,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_12BPC_BIT_EXT = 0x00000800,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_13BPC_BIT_EXT = 0x00001000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_14BPC_BIT_EXT = 0x00002000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_15BPC_BIT_EXT = 0x00004000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_16BPC_BIT_EXT = 0x00008000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_17BPC_BIT_EXT = 0x00010000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_18BPC_BIT_EXT = 0x00020000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_19BPC_BIT_EXT = 0x00040000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_20BPC_BIT_EXT = 0x00080000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_21BPC_BIT_EXT = 0x00100000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_22BPC_BIT_EXT = 0x00200000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_23BPC_BIT_EXT = 0x00400000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_24BPC_BIT_EXT = 0x00800000,
+ VK_IMAGE_COMPRESSION_FIXED_RATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkImageCompressionFixedRateFlagBitsEXT;
+typedef VkFlags VkImageCompressionFixedRateFlagsEXT;
+typedef struct VkPhysicalDeviceImageCompressionControlFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 imageCompressionControl;
+} VkPhysicalDeviceImageCompressionControlFeaturesEXT;
+
+typedef struct VkImageCompressionControlEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageCompressionFlagsEXT flags;
+ uint32_t compressionControlPlaneCount;
+ VkImageCompressionFixedRateFlagsEXT* pFixedRateFlags;
+} VkImageCompressionControlEXT;
+
+typedef struct VkSubresourceLayout2EXT {
+ VkStructureType sType;
+ void* pNext;
+ VkSubresourceLayout subresourceLayout;
+} VkSubresourceLayout2EXT;
+
+typedef struct VkImageSubresource2EXT {
+ VkStructureType sType;
+ void* pNext;
+ VkImageSubresource imageSubresource;
+} VkImageSubresource2EXT;
+
+typedef struct VkImageCompressionPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkImageCompressionFlagsEXT imageCompressionFlags;
+ VkImageCompressionFixedRateFlagsEXT imageCompressionFixedRateFlags;
+} VkImageCompressionPropertiesEXT;
+
+typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout2EXT)(VkDevice device, VkImage image, const VkImageSubresource2EXT* pSubresource, VkSubresourceLayout2EXT* pLayout);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout2EXT(
+ VkDevice device,
+ VkImage image,
+ const VkImageSubresource2EXT* pSubresource,
+ VkSubresourceLayout2EXT* pLayout);
+#endif
+
+
+#define VK_EXT_attachment_feedback_loop_layout 1
+#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_SPEC_VERSION 2
+#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME "VK_EXT_attachment_feedback_loop_layout"
+typedef struct VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 attachmentFeedbackLoopLayout;
+} VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT;
+
+
+
+#define VK_EXT_4444_formats 1
+#define VK_EXT_4444_FORMATS_SPEC_VERSION 1
+#define VK_EXT_4444_FORMATS_EXTENSION_NAME "VK_EXT_4444_formats"
+typedef struct VkPhysicalDevice4444FormatsFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 formatA4R4G4B4;
+ VkBool32 formatA4B4G4R4;
+} VkPhysicalDevice4444FormatsFeaturesEXT;
+
+
+
+#define VK_EXT_device_fault 1
+#define VK_EXT_DEVICE_FAULT_SPEC_VERSION 1
+#define VK_EXT_DEVICE_FAULT_EXTENSION_NAME "VK_EXT_device_fault"
+
+typedef enum VkDeviceFaultAddressTypeEXT {
+ VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT = 0,
+ VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT = 1,
+ VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT = 2,
+ VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT = 3,
+ VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT = 4,
+ VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT = 5,
+ VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT = 6,
+ VK_DEVICE_FAULT_ADDRESS_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDeviceFaultAddressTypeEXT;
+
+typedef enum VkDeviceFaultVendorBinaryHeaderVersionEXT {
+ VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT = 1,
+ VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDeviceFaultVendorBinaryHeaderVersionEXT;
+typedef struct VkPhysicalDeviceFaultFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 deviceFault;
+ VkBool32 deviceFaultVendorBinary;
+} VkPhysicalDeviceFaultFeaturesEXT;
+
+typedef struct VkDeviceFaultCountsEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t addressInfoCount;
+ uint32_t vendorInfoCount;
+ VkDeviceSize vendorBinarySize;
+} VkDeviceFaultCountsEXT;
+
+typedef struct VkDeviceFaultAddressInfoEXT {
+ VkDeviceFaultAddressTypeEXT addressType;
+ VkDeviceAddress reportedAddress;
+ VkDeviceSize addressPrecision;
+} VkDeviceFaultAddressInfoEXT;
+
+typedef struct VkDeviceFaultVendorInfoEXT {
+ char description[VK_MAX_DESCRIPTION_SIZE];
+ uint64_t vendorFaultCode;
+ uint64_t vendorFaultData;
+} VkDeviceFaultVendorInfoEXT;
+
+typedef struct VkDeviceFaultInfoEXT {
+ VkStructureType sType;
+ void* pNext;
+ char description[VK_MAX_DESCRIPTION_SIZE];
+ VkDeviceFaultAddressInfoEXT* pAddressInfos;
+ VkDeviceFaultVendorInfoEXT* pVendorInfos;
+ void* pVendorBinaryData;
+} VkDeviceFaultInfoEXT;
+
+typedef struct VkDeviceFaultVendorBinaryHeaderVersionOneEXT {
+ uint32_t headerSize;
+ VkDeviceFaultVendorBinaryHeaderVersionEXT headerVersion;
+ uint32_t vendorID;
+ uint32_t deviceID;
+ uint32_t driverVersion;
+ uint8_t pipelineCacheUUID[VK_UUID_SIZE];
+ uint32_t applicationNameOffset;
+ uint32_t applicationVersion;
+ uint32_t engineNameOffset;
+} VkDeviceFaultVendorBinaryHeaderVersionOneEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceFaultInfoEXT)(VkDevice device, VkDeviceFaultCountsEXT* pFaultCounts, VkDeviceFaultInfoEXT* pFaultInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceFaultInfoEXT(
+ VkDevice device,
+ VkDeviceFaultCountsEXT* pFaultCounts,
+ VkDeviceFaultInfoEXT* pFaultInfo);
+#endif
+
+
+#define VK_ARM_rasterization_order_attachment_access 1
+#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_SPEC_VERSION 1
+#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME "VK_ARM_rasterization_order_attachment_access"
+typedef struct VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 rasterizationOrderColorAttachmentAccess;
+ VkBool32 rasterizationOrderDepthAttachmentAccess;
+ VkBool32 rasterizationOrderStencilAttachmentAccess;
+} VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT;
+
+typedef VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM;
+
+
+
+#define VK_EXT_rgba10x6_formats 1
+#define VK_EXT_RGBA10X6_FORMATS_SPEC_VERSION 1
+#define VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME "VK_EXT_rgba10x6_formats"
+typedef struct VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 formatRgba10x6WithoutYCbCrSampler;
+} VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT;
+
+
+
+#define VK_NV_acquire_winrt_display 1
+#define VK_NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION 1
+#define VK_NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME "VK_NV_acquire_winrt_display"
+typedef VkResult (VKAPI_PTR *PFN_vkAcquireWinrtDisplayNV)(VkPhysicalDevice physicalDevice, VkDisplayKHR display);
+typedef VkResult (VKAPI_PTR *PFN_vkGetWinrtDisplayNV)(VkPhysicalDevice physicalDevice, uint32_t deviceRelativeId, VkDisplayKHR* pDisplay);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireWinrtDisplayNV(
+ VkPhysicalDevice physicalDevice,
+ VkDisplayKHR display);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetWinrtDisplayNV(
+ VkPhysicalDevice physicalDevice,
+ uint32_t deviceRelativeId,
+ VkDisplayKHR* pDisplay);
+#endif
+
+
+#define VK_VALVE_mutable_descriptor_type 1
+#define VK_VALVE_MUTABLE_DESCRIPTOR_TYPE_SPEC_VERSION 1
+#define VK_VALVE_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME "VK_VALVE_mutable_descriptor_type"
+typedef struct VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 mutableDescriptorType;
+} VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT;
+
+typedef VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE;
+
+typedef struct VkMutableDescriptorTypeListEXT {
+ uint32_t descriptorTypeCount;
+ const VkDescriptorType* pDescriptorTypes;
+} VkMutableDescriptorTypeListEXT;
+
+typedef VkMutableDescriptorTypeListEXT VkMutableDescriptorTypeListVALVE;
+
+typedef struct VkMutableDescriptorTypeCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t mutableDescriptorTypeListCount;
+ const VkMutableDescriptorTypeListEXT* pMutableDescriptorTypeLists;
+} VkMutableDescriptorTypeCreateInfoEXT;
+
+typedef VkMutableDescriptorTypeCreateInfoEXT VkMutableDescriptorTypeCreateInfoVALVE;
+
+
+
+#define VK_EXT_vertex_input_dynamic_state 1
+#define VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_SPEC_VERSION 2
+#define VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME "VK_EXT_vertex_input_dynamic_state"
+typedef struct VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 vertexInputDynamicState;
+} VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT;
+
+typedef struct VkVertexInputBindingDescription2EXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t binding;
+ uint32_t stride;
+ VkVertexInputRate inputRate;
+ uint32_t divisor;
+} VkVertexInputBindingDescription2EXT;
+
+typedef struct VkVertexInputAttributeDescription2EXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t location;
+ uint32_t binding;
+ VkFormat format;
+ uint32_t offset;
+} VkVertexInputAttributeDescription2EXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetVertexInputEXT)(VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount, const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions, uint32_t vertexAttributeDescriptionCount, const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetVertexInputEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t vertexBindingDescriptionCount,
+ const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions,
+ uint32_t vertexAttributeDescriptionCount,
+ const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions);
+#endif
+
+
+#define VK_EXT_physical_device_drm 1
+#define VK_EXT_PHYSICAL_DEVICE_DRM_SPEC_VERSION 1
+#define VK_EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME "VK_EXT_physical_device_drm"
+typedef struct VkPhysicalDeviceDrmPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 hasPrimary;
+ VkBool32 hasRender;
+ int64_t primaryMajor;
+ int64_t primaryMinor;
+ int64_t renderMajor;
+ int64_t renderMinor;
+} VkPhysicalDeviceDrmPropertiesEXT;
+
+
+
+#define VK_EXT_device_address_binding_report 1
+#define VK_EXT_DEVICE_ADDRESS_BINDING_REPORT_SPEC_VERSION 1
+#define VK_EXT_DEVICE_ADDRESS_BINDING_REPORT_EXTENSION_NAME "VK_EXT_device_address_binding_report"
+
+typedef enum VkDeviceAddressBindingTypeEXT {
+ VK_DEVICE_ADDRESS_BINDING_TYPE_BIND_EXT = 0,
+ VK_DEVICE_ADDRESS_BINDING_TYPE_UNBIND_EXT = 1,
+ VK_DEVICE_ADDRESS_BINDING_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDeviceAddressBindingTypeEXT;
+
+typedef enum VkDeviceAddressBindingFlagBitsEXT {
+ VK_DEVICE_ADDRESS_BINDING_INTERNAL_OBJECT_BIT_EXT = 0x00000001,
+ VK_DEVICE_ADDRESS_BINDING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkDeviceAddressBindingFlagBitsEXT;
+typedef VkFlags VkDeviceAddressBindingFlagsEXT;
+typedef struct VkPhysicalDeviceAddressBindingReportFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 reportAddressBinding;
+} VkPhysicalDeviceAddressBindingReportFeaturesEXT;
+
+typedef struct VkDeviceAddressBindingCallbackDataEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkDeviceAddressBindingFlagsEXT flags;
+ VkDeviceAddress baseAddress;
+ VkDeviceSize size;
+ VkDeviceAddressBindingTypeEXT bindingType;
+} VkDeviceAddressBindingCallbackDataEXT;
+
+
+
+#define VK_EXT_depth_clip_control 1
+#define VK_EXT_DEPTH_CLIP_CONTROL_SPEC_VERSION 1
+#define VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME "VK_EXT_depth_clip_control"
+typedef struct VkPhysicalDeviceDepthClipControlFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 depthClipControl;
+} VkPhysicalDeviceDepthClipControlFeaturesEXT;
+
+typedef struct VkPipelineViewportDepthClipControlCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 negativeOneToOne;
+} VkPipelineViewportDepthClipControlCreateInfoEXT;
+
+
+
+#define VK_EXT_primitive_topology_list_restart 1
+#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION 1
+#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME "VK_EXT_primitive_topology_list_restart"
+typedef struct VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 primitiveTopologyListRestart;
+ VkBool32 primitiveTopologyPatchListRestart;
+} VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT;
+
+
+
+#define VK_HUAWEI_subpass_shading 1
+#define VK_HUAWEI_SUBPASS_SHADING_SPEC_VERSION 2
+#define VK_HUAWEI_SUBPASS_SHADING_EXTENSION_NAME "VK_HUAWEI_subpass_shading"
+typedef struct VkSubpassShadingPipelineCreateInfoHUAWEI {
+ VkStructureType sType;
+ void* pNext;
+ VkRenderPass renderPass;
+ uint32_t subpass;
+} VkSubpassShadingPipelineCreateInfoHUAWEI;
+
+typedef struct VkPhysicalDeviceSubpassShadingFeaturesHUAWEI {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 subpassShading;
+} VkPhysicalDeviceSubpassShadingFeaturesHUAWEI;
+
+typedef struct VkPhysicalDeviceSubpassShadingPropertiesHUAWEI {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxSubpassShadingWorkgroupSizeAspectRatio;
+} VkPhysicalDeviceSubpassShadingPropertiesHUAWEI;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)(VkDevice device, VkRenderPass renderpass, VkExtent2D* pMaxWorkgroupSize);
+typedef void (VKAPI_PTR *PFN_vkCmdSubpassShadingHUAWEI)(VkCommandBuffer commandBuffer);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI(
+ VkDevice device,
+ VkRenderPass renderpass,
+ VkExtent2D* pMaxWorkgroupSize);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSubpassShadingHUAWEI(
+ VkCommandBuffer commandBuffer);
+#endif
+
+
+#define VK_HUAWEI_invocation_mask 1
+#define VK_HUAWEI_INVOCATION_MASK_SPEC_VERSION 1
+#define VK_HUAWEI_INVOCATION_MASK_EXTENSION_NAME "VK_HUAWEI_invocation_mask"
+typedef struct VkPhysicalDeviceInvocationMaskFeaturesHUAWEI {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 invocationMask;
+} VkPhysicalDeviceInvocationMaskFeaturesHUAWEI;
+
+typedef void (VKAPI_PTR *PFN_vkCmdBindInvocationMaskHUAWEI)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdBindInvocationMaskHUAWEI(
+ VkCommandBuffer commandBuffer,
+ VkImageView imageView,
+ VkImageLayout imageLayout);
+#endif
+
+
+#define VK_NV_external_memory_rdma 1
+typedef void* VkRemoteAddressNV;
+#define VK_NV_EXTERNAL_MEMORY_RDMA_SPEC_VERSION 1
+#define VK_NV_EXTERNAL_MEMORY_RDMA_EXTENSION_NAME "VK_NV_external_memory_rdma"
+typedef struct VkMemoryGetRemoteAddressInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceMemory memory;
+ VkExternalMemoryHandleTypeFlagBits handleType;
+} VkMemoryGetRemoteAddressInfoNV;
+
+typedef struct VkPhysicalDeviceExternalMemoryRDMAFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 externalMemoryRDMA;
+} VkPhysicalDeviceExternalMemoryRDMAFeaturesNV;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryRemoteAddressNV)(VkDevice device, const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo, VkRemoteAddressNV* pAddress);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryRemoteAddressNV(
+ VkDevice device,
+ const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo,
+ VkRemoteAddressNV* pAddress);
+#endif
+
+
+#define VK_EXT_pipeline_properties 1
+#define VK_EXT_PIPELINE_PROPERTIES_SPEC_VERSION 1
+#define VK_EXT_PIPELINE_PROPERTIES_EXTENSION_NAME "VK_EXT_pipeline_properties"
+typedef VkPipelineInfoKHR VkPipelineInfoEXT;
+
+typedef struct VkPipelinePropertiesIdentifierEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint8_t pipelineIdentifier[VK_UUID_SIZE];
+} VkPipelinePropertiesIdentifierEXT;
+
+typedef struct VkPhysicalDevicePipelinePropertiesFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 pipelinePropertiesIdentifier;
+} VkPhysicalDevicePipelinePropertiesFeaturesEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPipelinePropertiesEXT)(VkDevice device, const VkPipelineInfoEXT* pPipelineInfo, VkBaseOutStructure* pPipelineProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelinePropertiesEXT(
+ VkDevice device,
+ const VkPipelineInfoEXT* pPipelineInfo,
+ VkBaseOutStructure* pPipelineProperties);
+#endif
+
+
+#define VK_EXT_multisampled_render_to_single_sampled 1
+#define VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_SPEC_VERSION 1
+#define VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME "VK_EXT_multisampled_render_to_single_sampled"
+typedef struct VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 multisampledRenderToSingleSampled;
+} VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT;
+
+typedef struct VkSubpassResolvePerformanceQueryEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 optimal;
+} VkSubpassResolvePerformanceQueryEXT;
+
+typedef struct VkMultisampledRenderToSingleSampledInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 multisampledRenderToSingleSampledEnable;
+ VkSampleCountFlagBits rasterizationSamples;
+} VkMultisampledRenderToSingleSampledInfoEXT;
+
+
+
+#define VK_EXT_extended_dynamic_state2 1
+#define VK_EXT_EXTENDED_DYNAMIC_STATE_2_SPEC_VERSION 1
+#define VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME "VK_EXT_extended_dynamic_state2"
+typedef struct VkPhysicalDeviceExtendedDynamicState2FeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 extendedDynamicState2;
+ VkBool32 extendedDynamicState2LogicOp;
+ VkBool32 extendedDynamicState2PatchControlPoints;
+} VkPhysicalDeviceExtendedDynamicState2FeaturesEXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetPatchControlPointsEXT)(VkCommandBuffer commandBuffer, uint32_t patchControlPoints);
+typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizerDiscardEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBiasEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetLogicOpEXT)(VkCommandBuffer commandBuffer, VkLogicOp logicOp);
+typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetPatchControlPointsEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t patchControlPoints);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 rasterizerDiscardEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 depthBiasEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetLogicOpEXT(
+ VkCommandBuffer commandBuffer,
+ VkLogicOp logicOp);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 primitiveRestartEnable);
+#endif
+
+
+#define VK_EXT_color_write_enable 1
+#define VK_EXT_COLOR_WRITE_ENABLE_SPEC_VERSION 1
+#define VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME "VK_EXT_color_write_enable"
+typedef struct VkPhysicalDeviceColorWriteEnableFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 colorWriteEnable;
+} VkPhysicalDeviceColorWriteEnableFeaturesEXT;
+
+typedef struct VkPipelineColorWriteCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t attachmentCount;
+ const VkBool32* pColorWriteEnables;
+} VkPipelineColorWriteCreateInfoEXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetColorWriteEnableEXT)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkBool32* pColorWriteEnables);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWriteEnableEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t attachmentCount,
+ const VkBool32* pColorWriteEnables);
+#endif
+
+
+#define VK_EXT_primitives_generated_query 1
+#define VK_EXT_PRIMITIVES_GENERATED_QUERY_SPEC_VERSION 1
+#define VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME "VK_EXT_primitives_generated_query"
+typedef struct VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 primitivesGeneratedQuery;
+ VkBool32 primitivesGeneratedQueryWithRasterizerDiscard;
+ VkBool32 primitivesGeneratedQueryWithNonZeroStreams;
+} VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT;
+
+
+
+#define VK_EXT_global_priority_query 1
+#define VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION 1
+#define VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME "VK_EXT_global_priority_query"
+#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT VK_MAX_GLOBAL_PRIORITY_SIZE_KHR
+typedef VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT;
+
+typedef VkQueueFamilyGlobalPriorityPropertiesKHR VkQueueFamilyGlobalPriorityPropertiesEXT;
+
+
+
+#define VK_EXT_image_view_min_lod 1
+#define VK_EXT_IMAGE_VIEW_MIN_LOD_SPEC_VERSION 1
+#define VK_EXT_IMAGE_VIEW_MIN_LOD_EXTENSION_NAME "VK_EXT_image_view_min_lod"
+typedef struct VkPhysicalDeviceImageViewMinLodFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 minLod;
+} VkPhysicalDeviceImageViewMinLodFeaturesEXT;
+
+typedef struct VkImageViewMinLodCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ float minLod;
+} VkImageViewMinLodCreateInfoEXT;
+
+
+
+#define VK_EXT_multi_draw 1
+#define VK_EXT_MULTI_DRAW_SPEC_VERSION 1
+#define VK_EXT_MULTI_DRAW_EXTENSION_NAME "VK_EXT_multi_draw"
+typedef struct VkPhysicalDeviceMultiDrawFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 multiDraw;
+} VkPhysicalDeviceMultiDrawFeaturesEXT;
+
+typedef struct VkPhysicalDeviceMultiDrawPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxMultiDrawCount;
+} VkPhysicalDeviceMultiDrawPropertiesEXT;
+
+typedef struct VkMultiDrawInfoEXT {
+ uint32_t firstVertex;
+ uint32_t vertexCount;
+} VkMultiDrawInfoEXT;
+
+typedef struct VkMultiDrawIndexedInfoEXT {
+ uint32_t firstIndex;
+ uint32_t indexCount;
+ int32_t vertexOffset;
+} VkMultiDrawIndexedInfoEXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdDrawMultiEXT)(VkCommandBuffer commandBuffer, uint32_t drawCount, const VkMultiDrawInfoEXT* pVertexInfo, uint32_t instanceCount, uint32_t firstInstance, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawMultiIndexedEXT)(VkCommandBuffer commandBuffer, uint32_t drawCount, const VkMultiDrawIndexedInfoEXT* pIndexInfo, uint32_t instanceCount, uint32_t firstInstance, uint32_t stride, const int32_t* pVertexOffset);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t drawCount,
+ const VkMultiDrawInfoEXT* pVertexInfo,
+ uint32_t instanceCount,
+ uint32_t firstInstance,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t drawCount,
+ const VkMultiDrawIndexedInfoEXT* pIndexInfo,
+ uint32_t instanceCount,
+ uint32_t firstInstance,
+ uint32_t stride,
+ const int32_t* pVertexOffset);
+#endif
+
+
+#define VK_EXT_image_2d_view_of_3d 1
+#define VK_EXT_IMAGE_2D_VIEW_OF_3D_SPEC_VERSION 1
+#define VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME "VK_EXT_image_2d_view_of_3d"
+typedef struct VkPhysicalDeviceImage2DViewOf3DFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 image2DViewOf3D;
+ VkBool32 sampler2DViewOf3D;
+} VkPhysicalDeviceImage2DViewOf3DFeaturesEXT;
+
+
+
+#define VK_EXT_opacity_micromap 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkMicromapEXT)
+#define VK_EXT_OPACITY_MICROMAP_SPEC_VERSION 2
+#define VK_EXT_OPACITY_MICROMAP_EXTENSION_NAME "VK_EXT_opacity_micromap"
+
+typedef enum VkMicromapTypeEXT {
+ VK_MICROMAP_TYPE_OPACITY_MICROMAP_EXT = 0,
+ VK_MICROMAP_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkMicromapTypeEXT;
+
+typedef enum VkBuildMicromapModeEXT {
+ VK_BUILD_MICROMAP_MODE_BUILD_EXT = 0,
+ VK_BUILD_MICROMAP_MODE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkBuildMicromapModeEXT;
+
+typedef enum VkCopyMicromapModeEXT {
+ VK_COPY_MICROMAP_MODE_CLONE_EXT = 0,
+ VK_COPY_MICROMAP_MODE_SERIALIZE_EXT = 1,
+ VK_COPY_MICROMAP_MODE_DESERIALIZE_EXT = 2,
+ VK_COPY_MICROMAP_MODE_COMPACT_EXT = 3,
+ VK_COPY_MICROMAP_MODE_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkCopyMicromapModeEXT;
+
+typedef enum VkOpacityMicromapFormatEXT {
+ VK_OPACITY_MICROMAP_FORMAT_2_STATE_EXT = 1,
+ VK_OPACITY_MICROMAP_FORMAT_4_STATE_EXT = 2,
+ VK_OPACITY_MICROMAP_FORMAT_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkOpacityMicromapFormatEXT;
+
+typedef enum VkOpacityMicromapSpecialIndexEXT {
+ VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_EXT = -1,
+ VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT = -2,
+ VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_TRANSPARENT_EXT = -3,
+ VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_EXT = -4,
+ VK_OPACITY_MICROMAP_SPECIAL_INDEX_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkOpacityMicromapSpecialIndexEXT;
+
+typedef enum VkAccelerationStructureCompatibilityKHR {
+ VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR = 0,
+ VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR = 1,
+ VK_ACCELERATION_STRUCTURE_COMPATIBILITY_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkAccelerationStructureCompatibilityKHR;
+
+typedef enum VkAccelerationStructureBuildTypeKHR {
+ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR = 0,
+ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR = 1,
+ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_OR_DEVICE_KHR = 2,
+ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkAccelerationStructureBuildTypeKHR;
+
+typedef enum VkBuildMicromapFlagBitsEXT {
+ VK_BUILD_MICROMAP_PREFER_FAST_TRACE_BIT_EXT = 0x00000001,
+ VK_BUILD_MICROMAP_PREFER_FAST_BUILD_BIT_EXT = 0x00000002,
+ VK_BUILD_MICROMAP_ALLOW_COMPACTION_BIT_EXT = 0x00000004,
+ VK_BUILD_MICROMAP_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkBuildMicromapFlagBitsEXT;
+typedef VkFlags VkBuildMicromapFlagsEXT;
+
+typedef enum VkMicromapCreateFlagBitsEXT {
+ VK_MICROMAP_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = 0x00000001,
+ VK_MICROMAP_CREATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkMicromapCreateFlagBitsEXT;
+typedef VkFlags VkMicromapCreateFlagsEXT;
+typedef struct VkMicromapUsageEXT {
+ uint32_t count;
+ uint32_t subdivisionLevel;
+ uint32_t format;
+} VkMicromapUsageEXT;
+
+typedef union VkDeviceOrHostAddressKHR {
+ VkDeviceAddress deviceAddress;
+ void* hostAddress;
+} VkDeviceOrHostAddressKHR;
+
+typedef struct VkMicromapBuildInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkMicromapTypeEXT type;
+ VkBuildMicromapFlagsEXT flags;
+ VkBuildMicromapModeEXT mode;
+ VkMicromapEXT dstMicromap;
+ uint32_t usageCountsCount;
+ const VkMicromapUsageEXT* pUsageCounts;
+ const VkMicromapUsageEXT* const* ppUsageCounts;
+ VkDeviceOrHostAddressConstKHR data;
+ VkDeviceOrHostAddressKHR scratchData;
+ VkDeviceOrHostAddressConstKHR triangleArray;
+ VkDeviceSize triangleArrayStride;
+} VkMicromapBuildInfoEXT;
+
+typedef struct VkMicromapCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkMicromapCreateFlagsEXT createFlags;
+ VkBuffer buffer;
+ VkDeviceSize offset;
+ VkDeviceSize size;
+ VkMicromapTypeEXT type;
+ VkDeviceAddress deviceAddress;
+} VkMicromapCreateInfoEXT;
+
+typedef struct VkPhysicalDeviceOpacityMicromapFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 micromap;
+ VkBool32 micromapCaptureReplay;
+ VkBool32 micromapHostCommands;
+} VkPhysicalDeviceOpacityMicromapFeaturesEXT;
+
+typedef struct VkPhysicalDeviceOpacityMicromapPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxOpacity2StateSubdivisionLevel;
+ uint32_t maxOpacity4StateSubdivisionLevel;
+} VkPhysicalDeviceOpacityMicromapPropertiesEXT;
+
+typedef struct VkMicromapVersionInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ const uint8_t* pVersionData;
+} VkMicromapVersionInfoEXT;
+
+typedef struct VkCopyMicromapToMemoryInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkMicromapEXT src;
+ VkDeviceOrHostAddressKHR dst;
+ VkCopyMicromapModeEXT mode;
+} VkCopyMicromapToMemoryInfoEXT;
+
+typedef struct VkCopyMemoryToMicromapInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceOrHostAddressConstKHR src;
+ VkMicromapEXT dst;
+ VkCopyMicromapModeEXT mode;
+} VkCopyMemoryToMicromapInfoEXT;
+
+typedef struct VkCopyMicromapInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkMicromapEXT src;
+ VkMicromapEXT dst;
+ VkCopyMicromapModeEXT mode;
+} VkCopyMicromapInfoEXT;
+
+typedef struct VkMicromapBuildSizesInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceSize micromapSize;
+ VkDeviceSize buildScratchSize;
+ VkBool32 discardable;
+} VkMicromapBuildSizesInfoEXT;
+
+typedef struct VkAccelerationStructureTrianglesOpacityMicromapEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkIndexType indexType;
+ VkDeviceOrHostAddressConstKHR indexBuffer;
+ VkDeviceSize indexStride;
+ uint32_t baseTriangle;
+ uint32_t usageCountsCount;
+ const VkMicromapUsageEXT* pUsageCounts;
+ const VkMicromapUsageEXT* const* ppUsageCounts;
+ VkMicromapEXT micromap;
+} VkAccelerationStructureTrianglesOpacityMicromapEXT;
+
+typedef struct VkMicromapTriangleEXT {
+ uint32_t dataOffset;
+ uint16_t subdivisionLevel;
+ uint16_t format;
+} VkMicromapTriangleEXT;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateMicromapEXT)(VkDevice device, const VkMicromapCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkMicromapEXT* pMicromap);
+typedef void (VKAPI_PTR *PFN_vkDestroyMicromapEXT)(VkDevice device, VkMicromapEXT micromap, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkCmdBuildMicromapsEXT)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkMicromapBuildInfoEXT* pInfos);
+typedef VkResult (VKAPI_PTR *PFN_vkBuildMicromapsEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount, const VkMicromapBuildInfoEXT* pInfos);
+typedef VkResult (VKAPI_PTR *PFN_vkCopyMicromapEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMicromapInfoEXT* pInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkCopyMicromapToMemoryEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMicromapToMemoryInfoEXT* pInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToMicromapEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMemoryToMicromapInfoEXT* pInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkWriteMicromapsPropertiesEXT)(VkDevice device, uint32_t micromapCount, const VkMicromapEXT* pMicromaps, VkQueryType queryType, size_t dataSize, void* pData, size_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyMicromapEXT)(VkCommandBuffer commandBuffer, const VkCopyMicromapInfoEXT* pInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyMicromapToMemoryEXT)(VkCommandBuffer commandBuffer, const VkCopyMicromapToMemoryInfoEXT* pInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToMicromapEXT)(VkCommandBuffer commandBuffer, const VkCopyMemoryToMicromapInfoEXT* pInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdWriteMicromapsPropertiesEXT)(VkCommandBuffer commandBuffer, uint32_t micromapCount, const VkMicromapEXT* pMicromaps, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceMicromapCompatibilityEXT)(VkDevice device, const VkMicromapVersionInfoEXT* pVersionInfo, VkAccelerationStructureCompatibilityKHR* pCompatibility);
+typedef void (VKAPI_PTR *PFN_vkGetMicromapBuildSizesEXT)(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType, const VkMicromapBuildInfoEXT* pBuildInfo, VkMicromapBuildSizesInfoEXT* pSizeInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateMicromapEXT(
+ VkDevice device,
+ const VkMicromapCreateInfoEXT* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkMicromapEXT* pMicromap);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyMicromapEXT(
+ VkDevice device,
+ VkMicromapEXT micromap,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBuildMicromapsEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t infoCount,
+ const VkMicromapBuildInfoEXT* pInfos);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBuildMicromapsEXT(
+ VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ uint32_t infoCount,
+ const VkMicromapBuildInfoEXT* pInfos);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCopyMicromapEXT(
+ VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ const VkCopyMicromapInfoEXT* pInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCopyMicromapToMemoryEXT(
+ VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ const VkCopyMicromapToMemoryInfoEXT* pInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToMicromapEXT(
+ VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ const VkCopyMemoryToMicromapInfoEXT* pInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkWriteMicromapsPropertiesEXT(
+ VkDevice device,
+ uint32_t micromapCount,
+ const VkMicromapEXT* pMicromaps,
+ VkQueryType queryType,
+ size_t dataSize,
+ void* pData,
+ size_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyMicromapEXT(
+ VkCommandBuffer commandBuffer,
+ const VkCopyMicromapInfoEXT* pInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyMicromapToMemoryEXT(
+ VkCommandBuffer commandBuffer,
+ const VkCopyMicromapToMemoryInfoEXT* pInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToMicromapEXT(
+ VkCommandBuffer commandBuffer,
+ const VkCopyMemoryToMicromapInfoEXT* pInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteMicromapsPropertiesEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t micromapCount,
+ const VkMicromapEXT* pMicromaps,
+ VkQueryType queryType,
+ VkQueryPool queryPool,
+ uint32_t firstQuery);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceMicromapCompatibilityEXT(
+ VkDevice device,
+ const VkMicromapVersionInfoEXT* pVersionInfo,
+ VkAccelerationStructureCompatibilityKHR* pCompatibility);
+
+VKAPI_ATTR void VKAPI_CALL vkGetMicromapBuildSizesEXT(
+ VkDevice device,
+ VkAccelerationStructureBuildTypeKHR buildType,
+ const VkMicromapBuildInfoEXT* pBuildInfo,
+ VkMicromapBuildSizesInfoEXT* pSizeInfo);
+#endif
+
+
+#define VK_EXT_load_store_op_none 1
+#define VK_EXT_LOAD_STORE_OP_NONE_SPEC_VERSION 1
+#define VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_EXT_load_store_op_none"
+
+
+#define VK_EXT_border_color_swizzle 1
+#define VK_EXT_BORDER_COLOR_SWIZZLE_SPEC_VERSION 1
+#define VK_EXT_BORDER_COLOR_SWIZZLE_EXTENSION_NAME "VK_EXT_border_color_swizzle"
+typedef struct VkPhysicalDeviceBorderColorSwizzleFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 borderColorSwizzle;
+ VkBool32 borderColorSwizzleFromImage;
+} VkPhysicalDeviceBorderColorSwizzleFeaturesEXT;
+
+typedef struct VkSamplerBorderColorComponentMappingCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkComponentMapping components;
+ VkBool32 srgb;
+} VkSamplerBorderColorComponentMappingCreateInfoEXT;
+
+
+
+#define VK_EXT_pageable_device_local_memory 1
+#define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_SPEC_VERSION 1
+#define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME "VK_EXT_pageable_device_local_memory"
+typedef struct VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 pageableDeviceLocalMemory;
+} VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT;
+
+typedef void (VKAPI_PTR *PFN_vkSetDeviceMemoryPriorityEXT)(VkDevice device, VkDeviceMemory memory, float priority);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkSetDeviceMemoryPriorityEXT(
+ VkDevice device,
+ VkDeviceMemory memory,
+ float priority);
+#endif
+
+
+#define VK_VALVE_descriptor_set_host_mapping 1
+#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_SPEC_VERSION 1
+#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_EXTENSION_NAME "VK_VALVE_descriptor_set_host_mapping"
+typedef struct VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 descriptorSetHostMapping;
+} VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE;
+
+typedef struct VkDescriptorSetBindingReferenceVALVE {
+ VkStructureType sType;
+ const void* pNext;
+ VkDescriptorSetLayout descriptorSetLayout;
+ uint32_t binding;
+} VkDescriptorSetBindingReferenceVALVE;
+
+typedef struct VkDescriptorSetLayoutHostMappingInfoVALVE {
+ VkStructureType sType;
+ void* pNext;
+ size_t descriptorOffset;
+ uint32_t descriptorSize;
+} VkDescriptorSetLayoutHostMappingInfoVALVE;
+
+typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE)(VkDevice device, const VkDescriptorSetBindingReferenceVALVE* pBindingReference, VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping);
+typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetHostMappingVALVE)(VkDevice device, VkDescriptorSet descriptorSet, void** ppData);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutHostMappingInfoVALVE(
+ VkDevice device,
+ const VkDescriptorSetBindingReferenceVALVE* pBindingReference,
+ VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetHostMappingVALVE(
+ VkDevice device,
+ VkDescriptorSet descriptorSet,
+ void** ppData);
+#endif
+
+
+#define VK_EXT_depth_clamp_zero_one 1
+#define VK_EXT_DEPTH_CLAMP_ZERO_ONE_SPEC_VERSION 1
+#define VK_EXT_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME "VK_EXT_depth_clamp_zero_one"
+typedef struct VkPhysicalDeviceDepthClampZeroOneFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 depthClampZeroOne;
+} VkPhysicalDeviceDepthClampZeroOneFeaturesEXT;
+
+
+
+#define VK_EXT_non_seamless_cube_map 1
+#define VK_EXT_NON_SEAMLESS_CUBE_MAP_SPEC_VERSION 1
+#define VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME "VK_EXT_non_seamless_cube_map"
+typedef struct VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 nonSeamlessCubeMap;
+} VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT;
+
+
+
+#define VK_QCOM_fragment_density_map_offset 1
+#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION 1
+#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME "VK_QCOM_fragment_density_map_offset"
+typedef struct VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 fragmentDensityMapOffset;
+} VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM;
+
+typedef struct VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM {
+ VkStructureType sType;
+ void* pNext;
+ VkExtent2D fragmentDensityOffsetGranularity;
+} VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM;
+
+typedef struct VkSubpassFragmentDensityMapOffsetEndInfoQCOM {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t fragmentDensityOffsetCount;
+ const VkOffset2D* pFragmentDensityOffsets;
+} VkSubpassFragmentDensityMapOffsetEndInfoQCOM;
+
+
+
+#define VK_NV_linear_color_attachment 1
+#define VK_NV_LINEAR_COLOR_ATTACHMENT_SPEC_VERSION 1
+#define VK_NV_LINEAR_COLOR_ATTACHMENT_EXTENSION_NAME "VK_NV_linear_color_attachment"
+typedef struct VkPhysicalDeviceLinearColorAttachmentFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 linearColorAttachment;
+} VkPhysicalDeviceLinearColorAttachmentFeaturesNV;
+
+
+
+#define VK_GOOGLE_surfaceless_query 1
+#define VK_GOOGLE_SURFACELESS_QUERY_SPEC_VERSION 2
+#define VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME "VK_GOOGLE_surfaceless_query"
+
+
+#define VK_EXT_image_compression_control_swapchain 1
+#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_SPEC_VERSION 1
+#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME "VK_EXT_image_compression_control_swapchain"
+typedef struct VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 imageCompressionControlSwapchain;
+} VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT;
+
+
+
+#define VK_QCOM_image_processing 1
+#define VK_QCOM_IMAGE_PROCESSING_SPEC_VERSION 1
+#define VK_QCOM_IMAGE_PROCESSING_EXTENSION_NAME "VK_QCOM_image_processing"
+typedef struct VkImageViewSampleWeightCreateInfoQCOM {
+ VkStructureType sType;
+ const void* pNext;
+ VkOffset2D filterCenter;
+ VkExtent2D filterSize;
+ uint32_t numPhases;
+} VkImageViewSampleWeightCreateInfoQCOM;
+
+typedef struct VkPhysicalDeviceImageProcessingFeaturesQCOM {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 textureSampleWeighted;
+ VkBool32 textureBoxFilter;
+ VkBool32 textureBlockMatch;
+} VkPhysicalDeviceImageProcessingFeaturesQCOM;
+
+typedef struct VkPhysicalDeviceImageProcessingPropertiesQCOM {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxWeightFilterPhases;
+ VkExtent2D maxWeightFilterDimension;
+ VkExtent2D maxBlockMatchRegion;
+ VkExtent2D maxBoxFilterBlockSize;
+} VkPhysicalDeviceImageProcessingPropertiesQCOM;
+
+
+
+#define VK_EXT_extended_dynamic_state3 1
+#define VK_EXT_EXTENDED_DYNAMIC_STATE_3_SPEC_VERSION 2
+#define VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME "VK_EXT_extended_dynamic_state3"
+typedef struct VkPhysicalDeviceExtendedDynamicState3FeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 extendedDynamicState3TessellationDomainOrigin;
+ VkBool32 extendedDynamicState3DepthClampEnable;
+ VkBool32 extendedDynamicState3PolygonMode;
+ VkBool32 extendedDynamicState3RasterizationSamples;
+ VkBool32 extendedDynamicState3SampleMask;
+ VkBool32 extendedDynamicState3AlphaToCoverageEnable;
+ VkBool32 extendedDynamicState3AlphaToOneEnable;
+ VkBool32 extendedDynamicState3LogicOpEnable;
+ VkBool32 extendedDynamicState3ColorBlendEnable;
+ VkBool32 extendedDynamicState3ColorBlendEquation;
+ VkBool32 extendedDynamicState3ColorWriteMask;
+ VkBool32 extendedDynamicState3RasterizationStream;
+ VkBool32 extendedDynamicState3ConservativeRasterizationMode;
+ VkBool32 extendedDynamicState3ExtraPrimitiveOverestimationSize;
+ VkBool32 extendedDynamicState3DepthClipEnable;
+ VkBool32 extendedDynamicState3SampleLocationsEnable;
+ VkBool32 extendedDynamicState3ColorBlendAdvanced;
+ VkBool32 extendedDynamicState3ProvokingVertexMode;
+ VkBool32 extendedDynamicState3LineRasterizationMode;
+ VkBool32 extendedDynamicState3LineStippleEnable;
+ VkBool32 extendedDynamicState3DepthClipNegativeOneToOne;
+ VkBool32 extendedDynamicState3ViewportWScalingEnable;
+ VkBool32 extendedDynamicState3ViewportSwizzle;
+ VkBool32 extendedDynamicState3CoverageToColorEnable;
+ VkBool32 extendedDynamicState3CoverageToColorLocation;
+ VkBool32 extendedDynamicState3CoverageModulationMode;
+ VkBool32 extendedDynamicState3CoverageModulationTableEnable;
+ VkBool32 extendedDynamicState3CoverageModulationTable;
+ VkBool32 extendedDynamicState3CoverageReductionMode;
+ VkBool32 extendedDynamicState3RepresentativeFragmentTestEnable;
+ VkBool32 extendedDynamicState3ShadingRateImageEnable;
+} VkPhysicalDeviceExtendedDynamicState3FeaturesEXT;
+
+typedef struct VkPhysicalDeviceExtendedDynamicState3PropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 dynamicPrimitiveTopologyUnrestricted;
+} VkPhysicalDeviceExtendedDynamicState3PropertiesEXT;
+
+typedef struct VkColorBlendEquationEXT {
+ VkBlendFactor srcColorBlendFactor;
+ VkBlendFactor dstColorBlendFactor;
+ VkBlendOp colorBlendOp;
+ VkBlendFactor srcAlphaBlendFactor;
+ VkBlendFactor dstAlphaBlendFactor;
+ VkBlendOp alphaBlendOp;
+} VkColorBlendEquationEXT;
+
+typedef struct VkColorBlendAdvancedEXT {
+ VkBlendOp advancedBlendOp;
+ VkBool32 srcPremultiplied;
+ VkBool32 dstPremultiplied;
+ VkBlendOverlapEXT blendOverlap;
+ VkBool32 clampResults;
+} VkColorBlendAdvancedEXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdSetTessellationDomainOriginEXT)(VkCommandBuffer commandBuffer, VkTessellationDomainOrigin domainOrigin);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthClampEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthClampEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetPolygonModeEXT)(VkCommandBuffer commandBuffer, VkPolygonMode polygonMode);
+typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizationSamplesEXT)(VkCommandBuffer commandBuffer, VkSampleCountFlagBits rasterizationSamples);
+typedef void (VKAPI_PTR *PFN_vkCmdSetSampleMaskEXT)(VkCommandBuffer commandBuffer, VkSampleCountFlagBits samples, const VkSampleMask* pSampleMask);
+typedef void (VKAPI_PTR *PFN_vkCmdSetAlphaToCoverageEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 alphaToCoverageEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetAlphaToOneEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 alphaToOneEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetLogicOpEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 logicOpEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetColorBlendEnableEXT)(VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkBool32* pColorBlendEnables);
+typedef void (VKAPI_PTR *PFN_vkCmdSetColorBlendEquationEXT)(VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkColorBlendEquationEXT* pColorBlendEquations);
+typedef void (VKAPI_PTR *PFN_vkCmdSetColorWriteMaskEXT)(VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkColorComponentFlags* pColorWriteMasks);
+typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizationStreamEXT)(VkCommandBuffer commandBuffer, uint32_t rasterizationStream);
+typedef void (VKAPI_PTR *PFN_vkCmdSetConservativeRasterizationModeEXT)(VkCommandBuffer commandBuffer, VkConservativeRasterizationModeEXT conservativeRasterizationMode);
+typedef void (VKAPI_PTR *PFN_vkCmdSetExtraPrimitiveOverestimationSizeEXT)(VkCommandBuffer commandBuffer, float extraPrimitiveOverestimationSize);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthClipEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthClipEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetSampleLocationsEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 sampleLocationsEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetColorBlendAdvancedEXT)(VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkColorBlendAdvancedEXT* pColorBlendAdvanced);
+typedef void (VKAPI_PTR *PFN_vkCmdSetProvokingVertexModeEXT)(VkCommandBuffer commandBuffer, VkProvokingVertexModeEXT provokingVertexMode);
+typedef void (VKAPI_PTR *PFN_vkCmdSetLineRasterizationModeEXT)(VkCommandBuffer commandBuffer, VkLineRasterizationModeEXT lineRasterizationMode);
+typedef void (VKAPI_PTR *PFN_vkCmdSetLineStippleEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 stippledLineEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetDepthClipNegativeOneToOneEXT)(VkCommandBuffer commandBuffer, VkBool32 negativeOneToOne);
+typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWScalingEnableNV)(VkCommandBuffer commandBuffer, VkBool32 viewportWScalingEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetViewportSwizzleNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportSwizzleNV* pViewportSwizzles);
+typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageToColorEnableNV)(VkCommandBuffer commandBuffer, VkBool32 coverageToColorEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageToColorLocationNV)(VkCommandBuffer commandBuffer, uint32_t coverageToColorLocation);
+typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageModulationModeNV)(VkCommandBuffer commandBuffer, VkCoverageModulationModeNV coverageModulationMode);
+typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageModulationTableEnableNV)(VkCommandBuffer commandBuffer, VkBool32 coverageModulationTableEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageModulationTableNV)(VkCommandBuffer commandBuffer, uint32_t coverageModulationTableCount, const float* pCoverageModulationTable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetShadingRateImageEnableNV)(VkCommandBuffer commandBuffer, VkBool32 shadingRateImageEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetRepresentativeFragmentTestEnableNV)(VkCommandBuffer commandBuffer, VkBool32 representativeFragmentTestEnable);
+typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageReductionModeNV)(VkCommandBuffer commandBuffer, VkCoverageReductionModeNV coverageReductionMode);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdSetTessellationDomainOriginEXT(
+ VkCommandBuffer commandBuffer,
+ VkTessellationDomainOrigin domainOrigin);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthClampEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 depthClampEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetPolygonModeEXT(
+ VkCommandBuffer commandBuffer,
+ VkPolygonMode polygonMode);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizationSamplesEXT(
+ VkCommandBuffer commandBuffer,
+ VkSampleCountFlagBits rasterizationSamples);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleMaskEXT(
+ VkCommandBuffer commandBuffer,
+ VkSampleCountFlagBits samples,
+ const VkSampleMask* pSampleMask);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetAlphaToCoverageEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 alphaToCoverageEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetAlphaToOneEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 alphaToOneEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetLogicOpEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 logicOpEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetColorBlendEnableEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstAttachment,
+ uint32_t attachmentCount,
+ const VkBool32* pColorBlendEnables);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetColorBlendEquationEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstAttachment,
+ uint32_t attachmentCount,
+ const VkColorBlendEquationEXT* pColorBlendEquations);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWriteMaskEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstAttachment,
+ uint32_t attachmentCount,
+ const VkColorComponentFlags* pColorWriteMasks);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizationStreamEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t rasterizationStream);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetConservativeRasterizationModeEXT(
+ VkCommandBuffer commandBuffer,
+ VkConservativeRasterizationModeEXT conservativeRasterizationMode);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetExtraPrimitiveOverestimationSizeEXT(
+ VkCommandBuffer commandBuffer,
+ float extraPrimitiveOverestimationSize);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthClipEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 depthClipEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleLocationsEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 sampleLocationsEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetColorBlendAdvancedEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstAttachment,
+ uint32_t attachmentCount,
+ const VkColorBlendAdvancedEXT* pColorBlendAdvanced);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetProvokingVertexModeEXT(
+ VkCommandBuffer commandBuffer,
+ VkProvokingVertexModeEXT provokingVertexMode);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetLineRasterizationModeEXT(
+ VkCommandBuffer commandBuffer,
+ VkLineRasterizationModeEXT lineRasterizationMode);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStippleEnableEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 stippledLineEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthClipNegativeOneToOneEXT(
+ VkCommandBuffer commandBuffer,
+ VkBool32 negativeOneToOne);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWScalingEnableNV(
+ VkCommandBuffer commandBuffer,
+ VkBool32 viewportWScalingEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportSwizzleNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkViewportSwizzleNV* pViewportSwizzles);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageToColorEnableNV(
+ VkCommandBuffer commandBuffer,
+ VkBool32 coverageToColorEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageToColorLocationNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t coverageToColorLocation);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageModulationModeNV(
+ VkCommandBuffer commandBuffer,
+ VkCoverageModulationModeNV coverageModulationMode);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageModulationTableEnableNV(
+ VkCommandBuffer commandBuffer,
+ VkBool32 coverageModulationTableEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageModulationTableNV(
+ VkCommandBuffer commandBuffer,
+ uint32_t coverageModulationTableCount,
+ const float* pCoverageModulationTable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetShadingRateImageEnableNV(
+ VkCommandBuffer commandBuffer,
+ VkBool32 shadingRateImageEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetRepresentativeFragmentTestEnableNV(
+ VkCommandBuffer commandBuffer,
+ VkBool32 representativeFragmentTestEnable);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageReductionModeNV(
+ VkCommandBuffer commandBuffer,
+ VkCoverageReductionModeNV coverageReductionMode);
+#endif
+
+
+#define VK_EXT_subpass_merge_feedback 1
+#define VK_EXT_SUBPASS_MERGE_FEEDBACK_SPEC_VERSION 2
+#define VK_EXT_SUBPASS_MERGE_FEEDBACK_EXTENSION_NAME "VK_EXT_subpass_merge_feedback"
+
+typedef enum VkSubpassMergeStatusEXT {
+ VK_SUBPASS_MERGE_STATUS_MERGED_EXT = 0,
+ VK_SUBPASS_MERGE_STATUS_DISALLOWED_EXT = 1,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SIDE_EFFECTS_EXT = 2,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SAMPLES_MISMATCH_EXT = 3,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_VIEWS_MISMATCH_EXT = 4,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_ALIASING_EXT = 5,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPENDENCIES_EXT = 6,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INCOMPATIBLE_INPUT_ATTACHMENT_EXT = 7,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_TOO_MANY_ATTACHMENTS_EXT = 8,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INSUFFICIENT_STORAGE_EXT = 9,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPTH_STENCIL_COUNT_EXT = 10,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_RESOLVE_ATTACHMENT_REUSE_EXT = 11,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SINGLE_SUBPASS_EXT = 12,
+ VK_SUBPASS_MERGE_STATUS_NOT_MERGED_UNSPECIFIED_EXT = 13,
+ VK_SUBPASS_MERGE_STATUS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkSubpassMergeStatusEXT;
+typedef struct VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 subpassMergeFeedback;
+} VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT;
+
+typedef struct VkRenderPassCreationControlEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 disallowMerging;
+} VkRenderPassCreationControlEXT;
+
+typedef struct VkRenderPassCreationFeedbackInfoEXT {
+ uint32_t postMergeSubpassCount;
+} VkRenderPassCreationFeedbackInfoEXT;
+
+typedef struct VkRenderPassCreationFeedbackCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkRenderPassCreationFeedbackInfoEXT* pRenderPassFeedback;
+} VkRenderPassCreationFeedbackCreateInfoEXT;
+
+typedef struct VkRenderPassSubpassFeedbackInfoEXT {
+ VkSubpassMergeStatusEXT subpassMergeStatus;
+ char description[VK_MAX_DESCRIPTION_SIZE];
+ uint32_t postMergeIndex;
+} VkRenderPassSubpassFeedbackInfoEXT;
+
+typedef struct VkRenderPassSubpassFeedbackCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkRenderPassSubpassFeedbackInfoEXT* pSubpassFeedback;
+} VkRenderPassSubpassFeedbackCreateInfoEXT;
+
+
+
+#define VK_EXT_shader_module_identifier 1
+#define VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT 32U
+#define VK_EXT_SHADER_MODULE_IDENTIFIER_SPEC_VERSION 1
+#define VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME "VK_EXT_shader_module_identifier"
+typedef struct VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderModuleIdentifier;
+} VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT;
+
+typedef struct VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint8_t shaderModuleIdentifierAlgorithmUUID[VK_UUID_SIZE];
+} VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT;
+
+typedef struct VkPipelineShaderStageModuleIdentifierCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t identifierSize;
+ const uint8_t* pIdentifier;
+} VkPipelineShaderStageModuleIdentifierCreateInfoEXT;
+
+typedef struct VkShaderModuleIdentifierEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t identifierSize;
+ uint8_t identifier[VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT];
+} VkShaderModuleIdentifierEXT;
+
+typedef void (VKAPI_PTR *PFN_vkGetShaderModuleIdentifierEXT)(VkDevice device, VkShaderModule shaderModule, VkShaderModuleIdentifierEXT* pIdentifier);
+typedef void (VKAPI_PTR *PFN_vkGetShaderModuleCreateInfoIdentifierEXT)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, VkShaderModuleIdentifierEXT* pIdentifier);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkGetShaderModuleIdentifierEXT(
+ VkDevice device,
+ VkShaderModule shaderModule,
+ VkShaderModuleIdentifierEXT* pIdentifier);
+
+VKAPI_ATTR void VKAPI_CALL vkGetShaderModuleCreateInfoIdentifierEXT(
+ VkDevice device,
+ const VkShaderModuleCreateInfo* pCreateInfo,
+ VkShaderModuleIdentifierEXT* pIdentifier);
+#endif
+
+
+#define VK_EXT_rasterization_order_attachment_access 1
+#define VK_EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_SPEC_VERSION 1
+#define VK_EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME "VK_EXT_rasterization_order_attachment_access"
+
+
+#define VK_NV_optical_flow 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkOpticalFlowSessionNV)
+#define VK_NV_OPTICAL_FLOW_SPEC_VERSION 1
+#define VK_NV_OPTICAL_FLOW_EXTENSION_NAME "VK_NV_optical_flow"
+
+typedef enum VkOpticalFlowPerformanceLevelNV {
+ VK_OPTICAL_FLOW_PERFORMANCE_LEVEL_UNKNOWN_NV = 0,
+ VK_OPTICAL_FLOW_PERFORMANCE_LEVEL_SLOW_NV = 1,
+ VK_OPTICAL_FLOW_PERFORMANCE_LEVEL_MEDIUM_NV = 2,
+ VK_OPTICAL_FLOW_PERFORMANCE_LEVEL_FAST_NV = 3,
+ VK_OPTICAL_FLOW_PERFORMANCE_LEVEL_MAX_ENUM_NV = 0x7FFFFFFF
+} VkOpticalFlowPerformanceLevelNV;
+
+typedef enum VkOpticalFlowSessionBindingPointNV {
+ VK_OPTICAL_FLOW_SESSION_BINDING_POINT_UNKNOWN_NV = 0,
+ VK_OPTICAL_FLOW_SESSION_BINDING_POINT_INPUT_NV = 1,
+ VK_OPTICAL_FLOW_SESSION_BINDING_POINT_REFERENCE_NV = 2,
+ VK_OPTICAL_FLOW_SESSION_BINDING_POINT_HINT_NV = 3,
+ VK_OPTICAL_FLOW_SESSION_BINDING_POINT_FLOW_VECTOR_NV = 4,
+ VK_OPTICAL_FLOW_SESSION_BINDING_POINT_BACKWARD_FLOW_VECTOR_NV = 5,
+ VK_OPTICAL_FLOW_SESSION_BINDING_POINT_COST_NV = 6,
+ VK_OPTICAL_FLOW_SESSION_BINDING_POINT_BACKWARD_COST_NV = 7,
+ VK_OPTICAL_FLOW_SESSION_BINDING_POINT_GLOBAL_FLOW_NV = 8,
+ VK_OPTICAL_FLOW_SESSION_BINDING_POINT_MAX_ENUM_NV = 0x7FFFFFFF
+} VkOpticalFlowSessionBindingPointNV;
+
+typedef enum VkOpticalFlowGridSizeFlagBitsNV {
+ VK_OPTICAL_FLOW_GRID_SIZE_UNKNOWN_NV = 0,
+ VK_OPTICAL_FLOW_GRID_SIZE_1X1_BIT_NV = 0x00000001,
+ VK_OPTICAL_FLOW_GRID_SIZE_2X2_BIT_NV = 0x00000002,
+ VK_OPTICAL_FLOW_GRID_SIZE_4X4_BIT_NV = 0x00000004,
+ VK_OPTICAL_FLOW_GRID_SIZE_8X8_BIT_NV = 0x00000008,
+ VK_OPTICAL_FLOW_GRID_SIZE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF
+} VkOpticalFlowGridSizeFlagBitsNV;
+typedef VkFlags VkOpticalFlowGridSizeFlagsNV;
+
+typedef enum VkOpticalFlowUsageFlagBitsNV {
+ VK_OPTICAL_FLOW_USAGE_UNKNOWN_NV = 0,
+ VK_OPTICAL_FLOW_USAGE_INPUT_BIT_NV = 0x00000001,
+ VK_OPTICAL_FLOW_USAGE_OUTPUT_BIT_NV = 0x00000002,
+ VK_OPTICAL_FLOW_USAGE_HINT_BIT_NV = 0x00000004,
+ VK_OPTICAL_FLOW_USAGE_COST_BIT_NV = 0x00000008,
+ VK_OPTICAL_FLOW_USAGE_GLOBAL_FLOW_BIT_NV = 0x00000010,
+ VK_OPTICAL_FLOW_USAGE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF
+} VkOpticalFlowUsageFlagBitsNV;
+typedef VkFlags VkOpticalFlowUsageFlagsNV;
+
+typedef enum VkOpticalFlowSessionCreateFlagBitsNV {
+ VK_OPTICAL_FLOW_SESSION_CREATE_ENABLE_HINT_BIT_NV = 0x00000001,
+ VK_OPTICAL_FLOW_SESSION_CREATE_ENABLE_COST_BIT_NV = 0x00000002,
+ VK_OPTICAL_FLOW_SESSION_CREATE_ENABLE_GLOBAL_FLOW_BIT_NV = 0x00000004,
+ VK_OPTICAL_FLOW_SESSION_CREATE_ALLOW_REGIONS_BIT_NV = 0x00000008,
+ VK_OPTICAL_FLOW_SESSION_CREATE_BOTH_DIRECTIONS_BIT_NV = 0x00000010,
+ VK_OPTICAL_FLOW_SESSION_CREATE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF
+} VkOpticalFlowSessionCreateFlagBitsNV;
+typedef VkFlags VkOpticalFlowSessionCreateFlagsNV;
+
+typedef enum VkOpticalFlowExecuteFlagBitsNV {
+ VK_OPTICAL_FLOW_EXECUTE_DISABLE_TEMPORAL_HINTS_BIT_NV = 0x00000001,
+ VK_OPTICAL_FLOW_EXECUTE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF
+} VkOpticalFlowExecuteFlagBitsNV;
+typedef VkFlags VkOpticalFlowExecuteFlagsNV;
+typedef struct VkPhysicalDeviceOpticalFlowFeaturesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 opticalFlow;
+} VkPhysicalDeviceOpticalFlowFeaturesNV;
+
+typedef struct VkPhysicalDeviceOpticalFlowPropertiesNV {
+ VkStructureType sType;
+ void* pNext;
+ VkOpticalFlowGridSizeFlagsNV supportedOutputGridSizes;
+ VkOpticalFlowGridSizeFlagsNV supportedHintGridSizes;
+ VkBool32 hintSupported;
+ VkBool32 costSupported;
+ VkBool32 bidirectionalFlowSupported;
+ VkBool32 globalFlowSupported;
+ uint32_t minWidth;
+ uint32_t minHeight;
+ uint32_t maxWidth;
+ uint32_t maxHeight;
+ uint32_t maxNumRegionsOfInterest;
+} VkPhysicalDeviceOpticalFlowPropertiesNV;
+
+typedef struct VkOpticalFlowImageFormatInfoNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkOpticalFlowUsageFlagsNV usage;
+} VkOpticalFlowImageFormatInfoNV;
+
+typedef struct VkOpticalFlowImageFormatPropertiesNV {
+ VkStructureType sType;
+ const void* pNext;
+ VkFormat format;
+} VkOpticalFlowImageFormatPropertiesNV;
+
+typedef struct VkOpticalFlowSessionCreateInfoNV {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t width;
+ uint32_t height;
+ VkFormat imageFormat;
+ VkFormat flowVectorFormat;
+ VkFormat costFormat;
+ VkOpticalFlowGridSizeFlagsNV outputGridSize;
+ VkOpticalFlowGridSizeFlagsNV hintGridSize;
+ VkOpticalFlowPerformanceLevelNV performanceLevel;
+ VkOpticalFlowSessionCreateFlagsNV flags;
+} VkOpticalFlowSessionCreateInfoNV;
+
+typedef struct VkOpticalFlowSessionCreatePrivateDataInfoNV {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t id;
+ uint32_t size;
+ const void* pPrivateData;
+} VkOpticalFlowSessionCreatePrivateDataInfoNV;
+
+typedef struct VkOpticalFlowExecuteInfoNV {
+ VkStructureType sType;
+ void* pNext;
+ VkOpticalFlowExecuteFlagsNV flags;
+ uint32_t regionCount;
+ const VkRect2D* pRegions;
+} VkOpticalFlowExecuteInfoNV;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceOpticalFlowImageFormatsNV)(VkPhysicalDevice physicalDevice, const VkOpticalFlowImageFormatInfoNV* pOpticalFlowImageFormatInfo, uint32_t* pFormatCount, VkOpticalFlowImageFormatPropertiesNV* pImageFormatProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateOpticalFlowSessionNV)(VkDevice device, const VkOpticalFlowSessionCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkOpticalFlowSessionNV* pSession);
+typedef void (VKAPI_PTR *PFN_vkDestroyOpticalFlowSessionNV)(VkDevice device, VkOpticalFlowSessionNV session, const VkAllocationCallbacks* pAllocator);
+typedef VkResult (VKAPI_PTR *PFN_vkBindOpticalFlowSessionImageNV)(VkDevice device, VkOpticalFlowSessionNV session, VkOpticalFlowSessionBindingPointNV bindingPoint, VkImageView view, VkImageLayout layout);
+typedef void (VKAPI_PTR *PFN_vkCmdOpticalFlowExecuteNV)(VkCommandBuffer commandBuffer, VkOpticalFlowSessionNV session, const VkOpticalFlowExecuteInfoNV* pExecuteInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceOpticalFlowImageFormatsNV(
+ VkPhysicalDevice physicalDevice,
+ const VkOpticalFlowImageFormatInfoNV* pOpticalFlowImageFormatInfo,
+ uint32_t* pFormatCount,
+ VkOpticalFlowImageFormatPropertiesNV* pImageFormatProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateOpticalFlowSessionNV(
+ VkDevice device,
+ const VkOpticalFlowSessionCreateInfoNV* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkOpticalFlowSessionNV* pSession);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyOpticalFlowSessionNV(
+ VkDevice device,
+ VkOpticalFlowSessionNV session,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBindOpticalFlowSessionImageNV(
+ VkDevice device,
+ VkOpticalFlowSessionNV session,
+ VkOpticalFlowSessionBindingPointNV bindingPoint,
+ VkImageView view,
+ VkImageLayout layout);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdOpticalFlowExecuteNV(
+ VkCommandBuffer commandBuffer,
+ VkOpticalFlowSessionNV session,
+ const VkOpticalFlowExecuteInfoNV* pExecuteInfo);
+#endif
+
+
+#define VK_EXT_legacy_dithering 1
+#define VK_EXT_LEGACY_DITHERING_SPEC_VERSION 1
+#define VK_EXT_LEGACY_DITHERING_EXTENSION_NAME "VK_EXT_legacy_dithering"
+typedef struct VkPhysicalDeviceLegacyDitheringFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 legacyDithering;
+} VkPhysicalDeviceLegacyDitheringFeaturesEXT;
+
+
+
+#define VK_EXT_pipeline_protected_access 1
+#define VK_EXT_PIPELINE_PROTECTED_ACCESS_SPEC_VERSION 1
+#define VK_EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME "VK_EXT_pipeline_protected_access"
+typedef struct VkPhysicalDevicePipelineProtectedAccessFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 pipelineProtectedAccess;
+} VkPhysicalDevicePipelineProtectedAccessFeaturesEXT;
+
+
+
+#define VK_QCOM_tile_properties 1
+#define VK_QCOM_TILE_PROPERTIES_SPEC_VERSION 1
+#define VK_QCOM_TILE_PROPERTIES_EXTENSION_NAME "VK_QCOM_tile_properties"
+typedef struct VkPhysicalDeviceTilePropertiesFeaturesQCOM {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 tileProperties;
+} VkPhysicalDeviceTilePropertiesFeaturesQCOM;
+
+typedef struct VkTilePropertiesQCOM {
+ VkStructureType sType;
+ void* pNext;
+ VkExtent3D tileSize;
+ VkExtent2D apronSize;
+ VkOffset2D origin;
+} VkTilePropertiesQCOM;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetFramebufferTilePropertiesQCOM)(VkDevice device, VkFramebuffer framebuffer, uint32_t* pPropertiesCount, VkTilePropertiesQCOM* pProperties);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDynamicRenderingTilePropertiesQCOM)(VkDevice device, const VkRenderingInfo* pRenderingInfo, VkTilePropertiesQCOM* pProperties);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetFramebufferTilePropertiesQCOM(
+ VkDevice device,
+ VkFramebuffer framebuffer,
+ uint32_t* pPropertiesCount,
+ VkTilePropertiesQCOM* pProperties);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDynamicRenderingTilePropertiesQCOM(
+ VkDevice device,
+ const VkRenderingInfo* pRenderingInfo,
+ VkTilePropertiesQCOM* pProperties);
+#endif
+
+
+#define VK_SEC_amigo_profiling 1
+#define VK_SEC_AMIGO_PROFILING_SPEC_VERSION 1
+#define VK_SEC_AMIGO_PROFILING_EXTENSION_NAME "VK_SEC_amigo_profiling"
+typedef struct VkPhysicalDeviceAmigoProfilingFeaturesSEC {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 amigoProfiling;
+} VkPhysicalDeviceAmigoProfilingFeaturesSEC;
+
+typedef struct VkAmigoProfilingSubmitInfoSEC {
+ VkStructureType sType;
+ const void* pNext;
+ uint64_t firstDrawTimestamp;
+ uint64_t swapBufferTimestamp;
+} VkAmigoProfilingSubmitInfoSEC;
+
+
+
+#define VK_EXT_mutable_descriptor_type 1
+#define VK_EXT_MUTABLE_DESCRIPTOR_TYPE_SPEC_VERSION 1
+#define VK_EXT_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME "VK_EXT_mutable_descriptor_type"
+
+
+#define VK_ARM_shader_core_builtins 1
+#define VK_ARM_SHADER_CORE_BUILTINS_SPEC_VERSION 1
+#define VK_ARM_SHADER_CORE_BUILTINS_EXTENSION_NAME "VK_ARM_shader_core_builtins"
+typedef struct VkPhysicalDeviceShaderCoreBuiltinsFeaturesARM {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderCoreBuiltins;
+} VkPhysicalDeviceShaderCoreBuiltinsFeaturesARM;
+
+typedef struct VkPhysicalDeviceShaderCoreBuiltinsPropertiesARM {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t shaderCoreCount;
+ uint32_t shaderWarpsPerCore;
+} VkPhysicalDeviceShaderCoreBuiltinsPropertiesARM;
+
+
+
+#define VK_KHR_acceleration_structure 1
+VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR)
+#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13
+#define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure"
+
+typedef enum VkBuildAccelerationStructureModeKHR {
+ VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR = 0,
+ VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR = 1,
+ VK_BUILD_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkBuildAccelerationStructureModeKHR;
+
+typedef enum VkAccelerationStructureCreateFlagBitsKHR {
+ VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 0x00000001,
+ VK_ACCELERATION_STRUCTURE_CREATE_MOTION_BIT_NV = 0x00000004,
+ VK_ACCELERATION_STRUCTURE_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkAccelerationStructureCreateFlagBitsKHR;
+typedef VkFlags VkAccelerationStructureCreateFlagsKHR;
+typedef struct VkAccelerationStructureBuildRangeInfoKHR {
+ uint32_t primitiveCount;
+ uint32_t primitiveOffset;
+ uint32_t firstVertex;
+ uint32_t transformOffset;
+} VkAccelerationStructureBuildRangeInfoKHR;
+
+typedef struct VkAccelerationStructureGeometryTrianglesDataKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkFormat vertexFormat;
+ VkDeviceOrHostAddressConstKHR vertexData;
+ VkDeviceSize vertexStride;
+ uint32_t maxVertex;
+ VkIndexType indexType;
+ VkDeviceOrHostAddressConstKHR indexData;
+ VkDeviceOrHostAddressConstKHR transformData;
+} VkAccelerationStructureGeometryTrianglesDataKHR;
+
+typedef struct VkAccelerationStructureGeometryAabbsDataKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceOrHostAddressConstKHR data;
+ VkDeviceSize stride;
+} VkAccelerationStructureGeometryAabbsDataKHR;
+
+typedef struct VkAccelerationStructureGeometryInstancesDataKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkBool32 arrayOfPointers;
+ VkDeviceOrHostAddressConstKHR data;
+} VkAccelerationStructureGeometryInstancesDataKHR;
+
+typedef union VkAccelerationStructureGeometryDataKHR {
+ VkAccelerationStructureGeometryTrianglesDataKHR triangles;
+ VkAccelerationStructureGeometryAabbsDataKHR aabbs;
+ VkAccelerationStructureGeometryInstancesDataKHR instances;
+} VkAccelerationStructureGeometryDataKHR;
+
+typedef struct VkAccelerationStructureGeometryKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkGeometryTypeKHR geometryType;
+ VkAccelerationStructureGeometryDataKHR geometry;
+ VkGeometryFlagsKHR flags;
+} VkAccelerationStructureGeometryKHR;
+
+typedef struct VkAccelerationStructureBuildGeometryInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccelerationStructureTypeKHR type;
+ VkBuildAccelerationStructureFlagsKHR flags;
+ VkBuildAccelerationStructureModeKHR mode;
+ VkAccelerationStructureKHR srcAccelerationStructure;
+ VkAccelerationStructureKHR dstAccelerationStructure;
+ uint32_t geometryCount;
+ const VkAccelerationStructureGeometryKHR* pGeometries;
+ const VkAccelerationStructureGeometryKHR* const* ppGeometries;
+ VkDeviceOrHostAddressKHR scratchData;
+} VkAccelerationStructureBuildGeometryInfoKHR;
+
+typedef struct VkAccelerationStructureCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccelerationStructureCreateFlagsKHR createFlags;
+ VkBuffer buffer;
+ VkDeviceSize offset;
+ VkDeviceSize size;
+ VkAccelerationStructureTypeKHR type;
+ VkDeviceAddress deviceAddress;
+} VkAccelerationStructureCreateInfoKHR;
+
+typedef struct VkWriteDescriptorSetAccelerationStructureKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t accelerationStructureCount;
+ const VkAccelerationStructureKHR* pAccelerationStructures;
+} VkWriteDescriptorSetAccelerationStructureKHR;
+
+typedef struct VkPhysicalDeviceAccelerationStructureFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 accelerationStructure;
+ VkBool32 accelerationStructureCaptureReplay;
+ VkBool32 accelerationStructureIndirectBuild;
+ VkBool32 accelerationStructureHostCommands;
+ VkBool32 descriptorBindingAccelerationStructureUpdateAfterBind;
+} VkPhysicalDeviceAccelerationStructureFeaturesKHR;
+
+typedef struct VkPhysicalDeviceAccelerationStructurePropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ uint64_t maxGeometryCount;
+ uint64_t maxInstanceCount;
+ uint64_t maxPrimitiveCount;
+ uint32_t maxPerStageDescriptorAccelerationStructures;
+ uint32_t maxPerStageDescriptorUpdateAfterBindAccelerationStructures;
+ uint32_t maxDescriptorSetAccelerationStructures;
+ uint32_t maxDescriptorSetUpdateAfterBindAccelerationStructures;
+ uint32_t minAccelerationStructureScratchOffsetAlignment;
+} VkPhysicalDeviceAccelerationStructurePropertiesKHR;
+
+typedef struct VkAccelerationStructureDeviceAddressInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccelerationStructureKHR accelerationStructure;
+} VkAccelerationStructureDeviceAddressInfoKHR;
+
+typedef struct VkAccelerationStructureVersionInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ const uint8_t* pVersionData;
+} VkAccelerationStructureVersionInfoKHR;
+
+typedef struct VkCopyAccelerationStructureToMemoryInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccelerationStructureKHR src;
+ VkDeviceOrHostAddressKHR dst;
+ VkCopyAccelerationStructureModeKHR mode;
+} VkCopyAccelerationStructureToMemoryInfoKHR;
+
+typedef struct VkCopyMemoryToAccelerationStructureInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceOrHostAddressConstKHR src;
+ VkAccelerationStructureKHR dst;
+ VkCopyAccelerationStructureModeKHR mode;
+} VkCopyMemoryToAccelerationStructureInfoKHR;
+
+typedef struct VkCopyAccelerationStructureInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkAccelerationStructureKHR src;
+ VkAccelerationStructureKHR dst;
+ VkCopyAccelerationStructureModeKHR mode;
+} VkCopyAccelerationStructureInfoKHR;
+
+typedef struct VkAccelerationStructureBuildSizesInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkDeviceSize accelerationStructureSize;
+ VkDeviceSize updateScratchSize;
+ VkDeviceSize buildScratchSize;
+} VkAccelerationStructureBuildSizesInfoKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureKHR)(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure);
+typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureKHR)(VkDevice device, VkAccelerationStructureKHR accelerationStructure, const VkAllocationCallbacks* pAllocator);
+typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructuresKHR)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos);
+typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructuresIndirectKHR)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkDeviceAddress* pIndirectDeviceAddresses, const uint32_t* pIndirectStrides, const uint32_t* const* ppMaxPrimitiveCounts);
+typedef VkResult (VKAPI_PTR *PFN_vkBuildAccelerationStructuresKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos);
+typedef VkResult (VKAPI_PTR *PFN_vkCopyAccelerationStructureKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyAccelerationStructureInfoKHR* pInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkCopyAccelerationStructureToMemoryKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToAccelerationStructureKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo);
+typedef VkResult (VKAPI_PTR *PFN_vkWriteAccelerationStructuresPropertiesKHR)(VkDevice device, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, size_t dataSize, void* pData, size_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureKHR)(VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureInfoKHR* pInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureToMemoryKHR)(VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToAccelerationStructureKHR)(VkCommandBuffer commandBuffer, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo);
+typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetAccelerationStructureDeviceAddressKHR)(VkDevice device, const VkAccelerationStructureDeviceAddressInfoKHR* pInfo);
+typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesKHR)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery);
+typedef void (VKAPI_PTR *PFN_vkGetDeviceAccelerationStructureCompatibilityKHR)(VkDevice device, const VkAccelerationStructureVersionInfoKHR* pVersionInfo, VkAccelerationStructureCompatibilityKHR* pCompatibility);
+typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureBuildSizesKHR)(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType, const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo, const uint32_t* pMaxPrimitiveCounts, VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureKHR(
+ VkDevice device,
+ const VkAccelerationStructureCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkAccelerationStructureKHR* pAccelerationStructure);
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureKHR(
+ VkDevice device,
+ VkAccelerationStructureKHR accelerationStructure,
+ const VkAllocationCallbacks* pAllocator);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructuresKHR(
+ VkCommandBuffer commandBuffer,
+ uint32_t infoCount,
+ const VkAccelerationStructureBuildGeometryInfoKHR* pInfos,
+ const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructuresIndirectKHR(
+ VkCommandBuffer commandBuffer,
+ uint32_t infoCount,
+ const VkAccelerationStructureBuildGeometryInfoKHR* pInfos,
+ const VkDeviceAddress* pIndirectDeviceAddresses,
+ const uint32_t* pIndirectStrides,
+ const uint32_t* const* ppMaxPrimitiveCounts);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkBuildAccelerationStructuresKHR(
+ VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ uint32_t infoCount,
+ const VkAccelerationStructureBuildGeometryInfoKHR* pInfos,
+ const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureKHR(
+ VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ const VkCopyAccelerationStructureInfoKHR* pInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureToMemoryKHR(
+ VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToAccelerationStructureKHR(
+ VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkWriteAccelerationStructuresPropertiesKHR(
+ VkDevice device,
+ uint32_t accelerationStructureCount,
+ const VkAccelerationStructureKHR* pAccelerationStructures,
+ VkQueryType queryType,
+ size_t dataSize,
+ void* pData,
+ size_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureKHR(
+ VkCommandBuffer commandBuffer,
+ const VkCopyAccelerationStructureInfoKHR* pInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureToMemoryKHR(
+ VkCommandBuffer commandBuffer,
+ const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToAccelerationStructureKHR(
+ VkCommandBuffer commandBuffer,
+ const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo);
+
+VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetAccelerationStructureDeviceAddressKHR(
+ VkDevice device,
+ const VkAccelerationStructureDeviceAddressInfoKHR* pInfo);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesKHR(
+ VkCommandBuffer commandBuffer,
+ uint32_t accelerationStructureCount,
+ const VkAccelerationStructureKHR* pAccelerationStructures,
+ VkQueryType queryType,
+ VkQueryPool queryPool,
+ uint32_t firstQuery);
+
+VKAPI_ATTR void VKAPI_CALL vkGetDeviceAccelerationStructureCompatibilityKHR(
+ VkDevice device,
+ const VkAccelerationStructureVersionInfoKHR* pVersionInfo,
+ VkAccelerationStructureCompatibilityKHR* pCompatibility);
+
+VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureBuildSizesKHR(
+ VkDevice device,
+ VkAccelerationStructureBuildTypeKHR buildType,
+ const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo,
+ const uint32_t* pMaxPrimitiveCounts,
+ VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo);
+#endif
+
+
+#define VK_KHR_ray_tracing_pipeline 1
+#define VK_KHR_RAY_TRACING_PIPELINE_SPEC_VERSION 1
+#define VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME "VK_KHR_ray_tracing_pipeline"
+
+typedef enum VkShaderGroupShaderKHR {
+ VK_SHADER_GROUP_SHADER_GENERAL_KHR = 0,
+ VK_SHADER_GROUP_SHADER_CLOSEST_HIT_KHR = 1,
+ VK_SHADER_GROUP_SHADER_ANY_HIT_KHR = 2,
+ VK_SHADER_GROUP_SHADER_INTERSECTION_KHR = 3,
+ VK_SHADER_GROUP_SHADER_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkShaderGroupShaderKHR;
+typedef struct VkRayTracingShaderGroupCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkRayTracingShaderGroupTypeKHR type;
+ uint32_t generalShader;
+ uint32_t closestHitShader;
+ uint32_t anyHitShader;
+ uint32_t intersectionShader;
+ const void* pShaderGroupCaptureReplayHandle;
+} VkRayTracingShaderGroupCreateInfoKHR;
+
+typedef struct VkRayTracingPipelineInterfaceCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t maxPipelineRayPayloadSize;
+ uint32_t maxPipelineRayHitAttributeSize;
+} VkRayTracingPipelineInterfaceCreateInfoKHR;
+
+typedef struct VkRayTracingPipelineCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkPipelineCreateFlags flags;
+ uint32_t stageCount;
+ const VkPipelineShaderStageCreateInfo* pStages;
+ uint32_t groupCount;
+ const VkRayTracingShaderGroupCreateInfoKHR* pGroups;
+ uint32_t maxPipelineRayRecursionDepth;
+ const VkPipelineLibraryCreateInfoKHR* pLibraryInfo;
+ const VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface;
+ const VkPipelineDynamicStateCreateInfo* pDynamicState;
+ VkPipelineLayout layout;
+ VkPipeline basePipelineHandle;
+ int32_t basePipelineIndex;
+} VkRayTracingPipelineCreateInfoKHR;
+
+typedef struct VkPhysicalDeviceRayTracingPipelineFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 rayTracingPipeline;
+ VkBool32 rayTracingPipelineShaderGroupHandleCaptureReplay;
+ VkBool32 rayTracingPipelineShaderGroupHandleCaptureReplayMixed;
+ VkBool32 rayTracingPipelineTraceRaysIndirect;
+ VkBool32 rayTraversalPrimitiveCulling;
+} VkPhysicalDeviceRayTracingPipelineFeaturesKHR;
+
+typedef struct VkPhysicalDeviceRayTracingPipelinePropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t shaderGroupHandleSize;
+ uint32_t maxRayRecursionDepth;
+ uint32_t maxShaderGroupStride;
+ uint32_t shaderGroupBaseAlignment;
+ uint32_t shaderGroupHandleCaptureReplaySize;
+ uint32_t maxRayDispatchInvocationCount;
+ uint32_t shaderGroupHandleAlignment;
+ uint32_t maxRayHitAttributeSize;
+} VkPhysicalDeviceRayTracingPipelinePropertiesKHR;
+
+typedef struct VkStridedDeviceAddressRegionKHR {
+ VkDeviceAddress deviceAddress;
+ VkDeviceSize stride;
+ VkDeviceSize size;
+} VkStridedDeviceAddressRegionKHR;
+
+typedef struct VkTraceRaysIndirectCommandKHR {
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth;
+} VkTraceRaysIndirectCommandKHR;
+
+typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysKHR)(VkCommandBuffer commandBuffer, const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, uint32_t width, uint32_t height, uint32_t depth);
+typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines);
+typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData);
+typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysIndirectKHR)(VkCommandBuffer commandBuffer, const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, VkDeviceAddress indirectDeviceAddress);
+typedef VkDeviceSize (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupStackSizeKHR)(VkDevice device, VkPipeline pipeline, uint32_t group, VkShaderGroupShaderKHR groupShader);
+typedef void (VKAPI_PTR *PFN_vkCmdSetRayTracingPipelineStackSizeKHR)(VkCommandBuffer commandBuffer, uint32_t pipelineStackSize);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysKHR(
+ VkCommandBuffer commandBuffer,
+ const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesKHR(
+ VkDevice device,
+ VkDeferredOperationKHR deferredOperation,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkRayTracingPipelineCreateInfoKHR* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipeline* pPipelines);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingCaptureReplayShaderGroupHandlesKHR(
+ VkDevice device,
+ VkPipeline pipeline,
+ uint32_t firstGroup,
+ uint32_t groupCount,
+ size_t dataSize,
+ void* pData);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirectKHR(
+ VkCommandBuffer commandBuffer,
+ const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable,
+ const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable,
+ VkDeviceAddress indirectDeviceAddress);
+
+VKAPI_ATTR VkDeviceSize VKAPI_CALL vkGetRayTracingShaderGroupStackSizeKHR(
+ VkDevice device,
+ VkPipeline pipeline,
+ uint32_t group,
+ VkShaderGroupShaderKHR groupShader);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdSetRayTracingPipelineStackSizeKHR(
+ VkCommandBuffer commandBuffer,
+ uint32_t pipelineStackSize);
+#endif
+
+
+#define VK_KHR_ray_query 1
+#define VK_KHR_RAY_QUERY_SPEC_VERSION 1
+#define VK_KHR_RAY_QUERY_EXTENSION_NAME "VK_KHR_ray_query"
+typedef struct VkPhysicalDeviceRayQueryFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 rayQuery;
+} VkPhysicalDeviceRayQueryFeaturesKHR;
+
+
+
+#define VK_EXT_mesh_shader 1
+#define VK_EXT_MESH_SHADER_SPEC_VERSION 1
+#define VK_EXT_MESH_SHADER_EXTENSION_NAME "VK_EXT_mesh_shader"
+typedef struct VkPhysicalDeviceMeshShaderFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 taskShader;
+ VkBool32 meshShader;
+ VkBool32 multiviewMeshShader;
+ VkBool32 primitiveFragmentShadingRateMeshShader;
+ VkBool32 meshShaderQueries;
+} VkPhysicalDeviceMeshShaderFeaturesEXT;
+
+typedef struct VkPhysicalDeviceMeshShaderPropertiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxTaskWorkGroupTotalCount;
+ uint32_t maxTaskWorkGroupCount[3];
+ uint32_t maxTaskWorkGroupInvocations;
+ uint32_t maxTaskWorkGroupSize[3];
+ uint32_t maxTaskPayloadSize;
+ uint32_t maxTaskSharedMemorySize;
+ uint32_t maxTaskPayloadAndSharedMemorySize;
+ uint32_t maxMeshWorkGroupTotalCount;
+ uint32_t maxMeshWorkGroupCount[3];
+ uint32_t maxMeshWorkGroupInvocations;
+ uint32_t maxMeshWorkGroupSize[3];
+ uint32_t maxMeshSharedMemorySize;
+ uint32_t maxMeshPayloadAndSharedMemorySize;
+ uint32_t maxMeshOutputMemorySize;
+ uint32_t maxMeshPayloadAndOutputMemorySize;
+ uint32_t maxMeshOutputComponents;
+ uint32_t maxMeshOutputVertices;
+ uint32_t maxMeshOutputPrimitives;
+ uint32_t maxMeshOutputLayers;
+ uint32_t maxMeshMultiviewViewCount;
+ uint32_t meshOutputPerVertexGranularity;
+ uint32_t meshOutputPerPrimitiveGranularity;
+ uint32_t maxPreferredTaskWorkGroupInvocations;
+ uint32_t maxPreferredMeshWorkGroupInvocations;
+ VkBool32 prefersLocalInvocationVertexOutput;
+ VkBool32 prefersLocalInvocationPrimitiveOutput;
+ VkBool32 prefersCompactVertexOutput;
+ VkBool32 prefersCompactPrimitiveOutput;
+} VkPhysicalDeviceMeshShaderPropertiesEXT;
+
+typedef struct VkDrawMeshTasksIndirectCommandEXT {
+ uint32_t groupCountX;
+ uint32_t groupCountY;
+ uint32_t groupCountZ;
+} VkDrawMeshTasksIndirectCommandEXT;
+
+typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksEXT)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectEXT)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride);
+typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCountEXT)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksEXT(
+ VkCommandBuffer commandBuffer,
+ uint32_t groupCountX,
+ uint32_t groupCountY,
+ uint32_t groupCountZ);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectEXT(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ uint32_t drawCount,
+ uint32_t stride);
+
+VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountEXT(
+ VkCommandBuffer commandBuffer,
+ VkBuffer buffer,
+ VkDeviceSize offset,
+ VkBuffer countBuffer,
+ VkDeviceSize countBufferOffset,
+ uint32_t maxDrawCount,
+ uint32_t stride);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan_screen.h b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan_screen.h
new file mode 100644
index 0000000000..f0ef40a6ca
--- /dev/null
+++ b/gfx/angle/checkout/third_party/vulkan-deps/vulkan-headers/src/include/vulkan/vulkan_screen.h
@@ -0,0 +1,54 @@
+#ifndef VULKAN_SCREEN_H_
+#define VULKAN_SCREEN_H_ 1
+
+/*
+** Copyright 2015-2022 The Khronos Group Inc.
+**
+** SPDX-License-Identifier: Apache-2.0
+*/
+
+/*
+** This header is generated from the Khronos Vulkan XML API Registry.
+**
+*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#define VK_QNX_screen_surface 1
+#define VK_QNX_SCREEN_SURFACE_SPEC_VERSION 1
+#define VK_QNX_SCREEN_SURFACE_EXTENSION_NAME "VK_QNX_screen_surface"
+typedef VkFlags VkScreenSurfaceCreateFlagsQNX;
+typedef struct VkScreenSurfaceCreateInfoQNX {
+ VkStructureType sType;
+ const void* pNext;
+ VkScreenSurfaceCreateFlagsQNX flags;
+ struct _screen_context* context;
+ struct _screen_window* window;
+} VkScreenSurfaceCreateInfoQNX;
+
+typedef VkResult (VKAPI_PTR *PFN_vkCreateScreenSurfaceQNX)(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
+typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window* window);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX(
+ VkInstance instance,
+ const VkScreenSurfaceCreateInfoQNX* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface);
+
+VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ struct _screen_window* window);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.cc b/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.cc
new file mode 100644
index 0000000000..49d6bfe9ea
--- /dev/null
+++ b/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.cc
@@ -0,0 +1,205 @@
+/* compression_utils_portable.cc
+ *
+ * Copyright 2019 The Chromium Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the Chromium source repository LICENSE file.
+ */
+
+#include "compression_utils_portable.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+namespace zlib_internal {
+
+// The difference in bytes between a zlib header and a gzip header.
+const size_t kGzipZlibHeaderDifferenceBytes = 16;
+
+// Pass an integer greater than the following get a gzip header instead of a
+// zlib header when calling deflateInit2() and inflateInit2().
+const int kWindowBitsToGetGzipHeader = 16;
+
+// This describes the amount of memory zlib uses to compress data. It can go
+// from 1 to 9, with 8 being the default. For details, see:
+// http://www.zlib.net/manual.html (search for memLevel).
+const int kZlibMemoryLevel = 8;
+
+// The expected compressed size is based on the input size factored by
+// internal Zlib constants (e.g. window size, etc) plus the wrapper
+// header size.
+uLongf GzipExpectedCompressedSize(uLongf input_size) {
+ return kGzipZlibHeaderDifferenceBytes + compressBound(input_size);
+}
+
+// The expected decompressed size is stored in the last
+// 4 bytes of |input| in LE. See https://tools.ietf.org/html/rfc1952#page-5
+uint32_t GetGzipUncompressedSize(const Bytef* compressed_data, size_t length) {
+ uint32_t size;
+ if (length < sizeof(size))
+ return 0;
+
+ memcpy(&size, &compressed_data[length - sizeof(size)], sizeof(size));
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ return size;
+#else
+ return __builtin_bswap32(size);
+#endif
+}
+
+// The number of window bits determines the type of wrapper to use - see
+// https://cs.chromium.org/chromium/src/third_party/zlib/zlib.h?l=566
+inline int ZlibStreamWrapperType(WrapperType type) {
+ if (type == ZLIB) // zlib DEFLATE stream wrapper
+ return MAX_WBITS;
+ if (type == GZIP) // gzip DEFLATE stream wrapper
+ return MAX_WBITS + kWindowBitsToGetGzipHeader;
+ if (type == ZRAW) // no wrapper, use raw DEFLATE
+ return -MAX_WBITS;
+ return 0;
+}
+
+int GzipCompressHelper(Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length,
+ void* (*malloc_fn)(size_t),
+ void (*free_fn)(void*)) {
+ return CompressHelper(GZIP, dest, dest_length, source, source_length,
+ Z_DEFAULT_COMPRESSION, malloc_fn, free_fn);
+}
+
+// This code is taken almost verbatim from third_party/zlib/compress.c. The only
+// difference is deflateInit2() is called which allows different window bits to
+// be set. > 16 causes a gzip header to be emitted rather than a zlib header,
+// and negative causes no header to emitted.
+//
+// Compression level can be a number from 1-9, with 1 being the fastest, 9 being
+// the best compression. The default, which the GZIP helper uses, is 6.
+int CompressHelper(WrapperType wrapper_type,
+ Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length,
+ int compression_level,
+ void* (*malloc_fn)(size_t),
+ void (*free_fn)(void*)) {
+ if (compression_level < 0 || compression_level > 9) {
+ compression_level = Z_DEFAULT_COMPRESSION;
+ }
+
+ z_stream stream;
+
+ // FIXME(cavalcantii): z_const is not defined as 'const'.
+ stream.next_in = static_cast<z_const Bytef*>(const_cast<Bytef*>(source));
+ stream.avail_in = static_cast<uInt>(source_length);
+ stream.next_out = dest;
+ stream.avail_out = static_cast<uInt>(*dest_length);
+ if (static_cast<uLong>(stream.avail_out) != *dest_length)
+ return Z_BUF_ERROR;
+
+ // Cannot convert capturing lambdas to function pointers directly, hence the
+ // structure.
+ struct MallocFreeFunctions {
+ void* (*malloc_fn)(size_t);
+ void (*free_fn)(void*);
+ } malloc_free = {malloc_fn, free_fn};
+
+ if (malloc_fn) {
+ if (!free_fn)
+ return Z_BUF_ERROR;
+
+ auto zalloc = [](void* opaque, uInt items, uInt size) {
+ return reinterpret_cast<MallocFreeFunctions*>(opaque)->malloc_fn(items *
+ size);
+ };
+ auto zfree = [](void* opaque, void* address) {
+ return reinterpret_cast<MallocFreeFunctions*>(opaque)->free_fn(address);
+ };
+
+ stream.zalloc = static_cast<alloc_func>(zalloc);
+ stream.zfree = static_cast<free_func>(zfree);
+ stream.opaque = static_cast<voidpf>(&malloc_free);
+ } else {
+ stream.zalloc = static_cast<alloc_func>(0);
+ stream.zfree = static_cast<free_func>(0);
+ stream.opaque = static_cast<voidpf>(0);
+ }
+
+ int err = deflateInit2(&stream, compression_level, Z_DEFLATED,
+ ZlibStreamWrapperType(wrapper_type), kZlibMemoryLevel,
+ Z_DEFAULT_STRATEGY);
+ if (err != Z_OK)
+ return err;
+
+ // This has to exist outside of the if statement to prevent it going off the
+ // stack before deflate(), which will use this object.
+ gz_header gzip_header;
+ if (wrapper_type == GZIP) {
+ memset(&gzip_header, 0, sizeof(gzip_header));
+ err = deflateSetHeader(&stream, &gzip_header);
+ if (err != Z_OK)
+ return err;
+ }
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *dest_length = stream.total_out;
+
+ err = deflateEnd(&stream);
+ return err;
+}
+
+int GzipUncompressHelper(Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length) {
+ return UncompressHelper(GZIP, dest, dest_length, source, source_length);
+}
+
+// This code is taken almost verbatim from third_party/zlib/uncompr.c. The only
+// difference is inflateInit2() is called which allows different window bits to
+// be set. > 16 causes a gzip header to be emitted rather than a zlib header,
+// and negative causes no header to emitted.
+int UncompressHelper(WrapperType wrapper_type,
+ Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length) {
+ z_stream stream;
+
+ // FIXME(cavalcantii): z_const is not defined as 'const'.
+ stream.next_in = static_cast<z_const Bytef*>(const_cast<Bytef*>(source));
+ stream.avail_in = static_cast<uInt>(source_length);
+ if (static_cast<uLong>(stream.avail_in) != source_length)
+ return Z_BUF_ERROR;
+
+ stream.next_out = dest;
+ stream.avail_out = static_cast<uInt>(*dest_length);
+ if (static_cast<uLong>(stream.avail_out) != *dest_length)
+ return Z_BUF_ERROR;
+
+ stream.zalloc = static_cast<alloc_func>(0);
+ stream.zfree = static_cast<free_func>(0);
+
+ int err = inflateInit2(&stream, ZlibStreamWrapperType(wrapper_type));
+ if (err != Z_OK)
+ return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+ return Z_DATA_ERROR;
+ return err;
+ }
+ *dest_length = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
+}
+
+} // namespace zlib_internal
diff --git a/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.h b/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.h
new file mode 100644
index 0000000000..92b033e889
--- /dev/null
+++ b/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.h
@@ -0,0 +1,63 @@
+/* compression_utils_portable.h
+ *
+ * Copyright 2019 The Chromium Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the Chromium source repository LICENSE file.
+ */
+#ifndef THIRD_PARTY_ZLIB_GOOGLE_COMPRESSION_UTILS_PORTABLE_H_
+#define THIRD_PARTY_ZLIB_GOOGLE_COMPRESSION_UTILS_PORTABLE_H_
+
+#include <stdint.h>
+
+/* TODO(cavalcantii): remove support for Chromium ever building with a system
+ * zlib.
+ */
+#if defined(USE_SYSTEM_ZLIB)
+#include <zlib.h>
+/* AOSP build requires relative paths. */
+#else
+#include "zlib.h"
+#endif
+
+namespace zlib_internal {
+
+enum WrapperType {
+ ZLIB,
+ GZIP,
+ ZRAW,
+};
+
+uLongf GzipExpectedCompressedSize(uLongf input_size);
+
+uint32_t GetGzipUncompressedSize(const Bytef* compressed_data, size_t length);
+
+int GzipCompressHelper(Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length,
+ void* (*malloc_fn)(size_t),
+ void (*free_fn)(void*));
+
+int CompressHelper(WrapperType wrapper_type,
+ Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length,
+ int compression_level,
+ void* (*malloc_fn)(size_t),
+ void (*free_fn)(void*));
+
+int GzipUncompressHelper(Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length);
+
+int UncompressHelper(WrapperType wrapper_type,
+ Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length);
+
+} // namespace zlib_internal
+
+#endif // THIRD_PARTY_ZLIB_GOOGLE_COMPRESSION_UTILS_PORTABLE_H_