summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Knight <andrew.knight@intopalo.com>2015-04-08 17:04:36 +0300
committerAndrew Knight <qt@panimo.net>2015-04-09 10:31:12 +0000
commita218a252c4200cfe7048de81a46f7e48349084d5 (patch)
treec1a82865d97e610cd0abb3a1360408363b38205b
parent331ddacfca90c91c5b44484bf3c78e2aa5b85947 (diff)
Upgrade ANGLE to 2.1~99f075dade7c
This aligns with Chromium branch 2356. This version brings more complete OpenGL ES 3 support as well as various bug fixes and performance improvements. The following changes were made to earlier patches: -0000-General-fixes-for-ANGLE-2.1 Removed. All changes are now handled elsewhere. +0001-ANGLE-Improve-Windows-Phone-support Consolidated remaining parts from 0009/0010. +0002-ANGLE-Fix-compilation-with-MinGW Remaining issues from patch 0016. +0003-ANGLE-Fix-compilation-with-MSVC2010 Remaining issues from patch 0015. +0004-ANGLE-Dynamically-load-D3D-compiler-from-list Renamed from patch 0008. +0005-ANGLE-Add-support-for-querying-platform-device Renamed from patch 0013. -0004-Make-it-possible-to-link-ANGLE-statically-for-single Removed. Fixed by adding defines to project files. -0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t Renamed to patch 0005. -0009-ANGLE-Support-WinRT Removed. Mostly fixed upstream; remaining parts in patch 0001. -0010-ANGLE-Enable-D3D11-for-feature-level-9-cards Removed. Mostly fixed upstream; remaining parts in patch 0001. -0012-ANGLE-fix-semantic-index-lookup Removed. Fixed upstream. -0013-ANGLE-Add-support-for-querying-platform-device Renamed to patch 0005. -0014-Let-ANGLE-use-multithreaded-devices-if-necessary Removed. No longer needed. -0015-ANGLE-Fix-angle-d3d11-on-MSVC2010 Moved remaining parts to patch 0003. -0016-ANGLE-Fix-compilation-with-MinGW-D3D11 Moved remaining parts to patch 0002. -0017-ANGLE-Fix-compilation-with-D3D9 Removed. Fixed upstream. -0018-ANGLE-Fix-releasing-textures-after-we-kill-D3D11 Removed. Fixed upstream. -0019-ANGLE-Fix-handling-of-shader-source-with-fixed-lengt Removed. Fixed upstream. -0020-ANGLE-Do-not-use-std-strlen Removed. Fixed upstream. -0020-ANGLE-Fix-compilation-with-MSVC2013-Update4 Removed. Fixed upstream. [ChangeLog][Third-party libraries] ANGLE was updated to Chromium branch 2356 (2.1~99f075dade7c). Change-Id: I32ccbfe95e10986bd94be7191dfd53445ea09158 Task-number: QTBUG-44815 Task-number: QTBUG-37660 Task-number: QTBUG-44694 Task-number: QTBUG-42443 Reviewed-by: Andrew Knight <qt@panimo.net> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
-rw-r--r--mkspecs/features/win32/opengl.prf2
-rw-r--r--src/3rdparty/angle/.gitignore15
-rw-r--r--src/3rdparty/angle/AUTHORS6
-rw-r--r--src/3rdparty/angle/CONTRIBUTORS21
-rw-r--r--src/3rdparty/angle/include/EGL/egl.h9
-rw-r--r--src/3rdparty/angle/include/EGL/eglext.h24
-rw-r--r--src/3rdparty/angle/include/EGL/eglplatform.h17
-rw-r--r--src/3rdparty/angle/include/GLSLANG/ShaderLang.h30
-rw-r--r--src/3rdparty/angle/include/GLSLANG/ShaderVars.h9
-rwxr-xr-x[-rw-r--r--]src/3rdparty/angle/include/KHR/khrplatform.h2
-rw-r--r--src/3rdparty/angle/include/angle_gl.h6
-rw-r--r--src/3rdparty/angle/include/export.h28
-rw-r--r--src/3rdparty/angle/include/platform/Platform.h112
-rw-r--r--src/3rdparty/angle/src/commit.h12
-rw-r--r--src/3rdparty/angle/src/common/MemoryBuffer.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp)42
-rw-r--r--src/3rdparty/angle/src/common/MemoryBuffer.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.h)12
-rw-r--r--src/3rdparty/angle/src/common/Optional.h61
-rw-r--r--src/3rdparty/angle/src/common/RefCountObject.h95
-rw-r--r--src/3rdparty/angle/src/common/angleutils.cpp3
-rw-r--r--src/3rdparty/angle/src/common/angleutils.h35
-rw-r--r--src/3rdparty/angle/src/common/debug.cpp263
-rw-r--r--src/3rdparty/angle/src/common/debug.h82
-rw-r--r--src/3rdparty/angle/src/common/event_tracer.cpp38
-rw-r--r--src/3rdparty/angle/src/common/event_tracer.h34
-rw-r--r--src/3rdparty/angle/src/common/mathutil.h61
-rw-r--r--src/3rdparty/angle/src/common/platform.h109
-rw-r--r--src/3rdparty/angle/src/common/tls.h4
-rw-r--r--src/3rdparty/angle/src/common/utilities.cpp40
-rw-r--r--src/3rdparty/angle/src/common/utilities.h18
-rw-r--r--src/3rdparty/angle/src/common/version.h13
-rw-r--r--src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h39
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h7
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h7
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h6
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h7
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y4
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Input.h2
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Lexer.h2
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Macro.h1
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h6
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h2
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h7
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Token.h1
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h2
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l4
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h7
-rw-r--r--src/3rdparty/angle/src/compiler/translator/BaseTypes.h49
-rw-r--r--src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp415
-rw-r--r--src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.h112
-rw-r--r--src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp37
-rw-r--r--src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h19
-rw-r--r--src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp410
-rw-r--r--src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h16
-rw-r--r--src/3rdparty/angle/src/compiler/translator/CodeGen.cpp22
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Common.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Compiler.cpp107
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Compiler.h29
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ConstantUnion.h13
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DetectCallDepth.cpp6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DetectCallDepth.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Diagnostics.h9
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp13
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h13
-rw-r--r--src/3rdparty/angle/src/compiler/translator/EmulatePrecision.cpp528
-rw-r--r--src/3rdparty/angle/src/compiler/translator/EmulatePrecision.h74
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/HashNames.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/InfoSink.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Initialize.cpp703
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Initialize.h12
-rw-r--r--src/3rdparty/angle/src/compiler/translator/InitializeDll.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/InitializeGlobals.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/InitializeParseContext.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/InitializeVariables.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/IntermNode.cpp311
-rw-r--r--src/3rdparty/angle/src/compiler/translator/IntermNode.h287
-rw-r--r--src/3rdparty/angle/src/compiler/translator/IntermTraverse.cpp54
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Intermediate.cpp114
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Intermediate.h (renamed from src/3rdparty/angle/src/compiler/translator/intermediate.h)16
-rw-r--r--src/3rdparty/angle/src/compiler/translator/LoopInfo.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/MMap.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/NodeSearch.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Operator.cpp195
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Operator.h226
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputESSL.cpp23
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputESSL.h11
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputGLSL.cpp52
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputGLSL.h13
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp216
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.h18
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp991
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputHLSL.h113
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ParseContext.cpp626
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ParseContext.h61
-rw-r--r--src/3rdparty/angle/src/compiler/translator/PoolAlloc.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Pragma.h13
-rw-r--r--src/3rdparty/angle/src/compiler/translator/QualifierAlive.cpp2
-rw-r--r--src/3rdparty/angle/src/compiler/translator/QualifierAlive.h5
-rw-r--r--src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp157
-rw-r--r--src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.h43
-rw-r--r--src/3rdparty/angle/src/compiler/translator/RemoveTree.cpp29
-rw-r--r--src/3rdparty/angle/src/compiler/translator/RemoveTree.h7
-rw-r--r--src/3rdparty/angle/src/compiler/translator/RenameFunction.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/SearchSymbol.cpp1
-rw-r--r--src/3rdparty/angle/src/compiler/translator/SearchSymbol.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp16
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp18
-rw-r--r--src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.cpp38
-rw-r--r--src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.h25
-rw-r--r--src/3rdparty/angle/src/compiler/translator/StructureHLSL.cpp22
-rw-r--r--src/3rdparty/angle/src/compiler/translator/StructureHLSL.h14
-rw-r--r--src/3rdparty/angle/src/compiler/translator/SymbolTable.cpp218
-rw-r--r--src/3rdparty/angle/src/compiler/translator/SymbolTable.h70
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp69
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorESSL.h19
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp114
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h12
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.cpp16
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.h8
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Types.cpp18
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Types.h38
-rw-r--r--src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.cpp6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.h9
-rw-r--r--src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp28
-rw-r--r--src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.h29
-rw-r--r--src/3rdparty/angle/src/compiler/translator/UniformHLSL.cpp17
-rw-r--r--src/3rdparty/angle/src/compiler/translator/UniformHLSL.h12
-rw-r--r--src/3rdparty/angle/src/compiler/translator/UtilsHLSL.cpp7
-rw-r--r--src/3rdparty/angle/src/compiler/translator/UtilsHLSL.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp87
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ValidateLimitations.h4
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ValidateOutputs.h5
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ValidateSwitch.cpp200
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ValidateSwitch.h52
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp36
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VariableInfo.h8
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VariablePacker.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp19
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VersionGLSL.h18
-rw-r--r--src/3rdparty/angle/src/compiler/translator/blocklayout.cpp123
-rw-r--r--src/3rdparty/angle/src/compiler/translator/blocklayout.h (renamed from src/3rdparty/angle/src/common/blocklayout.h)45
-rw-r--r--src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.cpp (renamed from src/3rdparty/angle/src/common/blocklayout.cpp)110
-rw-r--r--src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.h62
-rw-r--r--src/3rdparty/angle/src/compiler/translator/compilerdebug.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.h8
-rw-r--r--src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h12
-rw-r--r--src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h25
-rw-r--r--src/3rdparty/angle/src/compiler/translator/glslang.h4
-rw-r--r--src/3rdparty/angle/src/compiler/translator/glslang.l19
-rw-r--r--src/3rdparty/angle/src/compiler/translator/glslang.y427
-rw-r--r--src/3rdparty/angle/src/compiler/translator/intermOut.cpp110
-rw-r--r--src/3rdparty/angle/src/compiler/translator/length_limits.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h33
-rw-r--r--src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/util.cpp2
-rw-r--r--src/3rdparty/angle/src/compiler/translator/util.h10
-rw-r--r--src/3rdparty/angle/src/id/commit.h3
-rw-r--r--src/3rdparty/angle/src/libANGLE/AttributeMap.cpp (renamed from src/3rdparty/angle/src/libEGL/AttributeMap.cpp)19
-rw-r--r--src/3rdparty/angle/src/libANGLE/AttributeMap.h (renamed from src/3rdparty/angle/src/libEGL/AttributeMap.h)12
-rw-r--r--src/3rdparty/angle/src/libANGLE/BinaryStream.h (renamed from src/3rdparty/angle/src/libGLESv2/BinaryStream.h)28
-rw-r--r--src/3rdparty/angle/src/libANGLE/Buffer.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Buffer.cpp)13
-rw-r--r--src/3rdparty/angle/src/libANGLE/Buffer.h (renamed from src/3rdparty/angle/src/libGLESv2/Buffer.h)16
-rw-r--r--src/3rdparty/angle/src/libANGLE/Caps.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Caps.cpp)120
-rw-r--r--src/3rdparty/angle/src/libANGLE/Caps.h (renamed from src/3rdparty/angle/src/libGLESv2/Caps.h)117
-rw-r--r--src/3rdparty/angle/src/libANGLE/Compiler.cpp38
-rw-r--r--src/3rdparty/angle/src/libANGLE/Compiler.h39
-rw-r--r--src/3rdparty/angle/src/libANGLE/Config.cpp275
-rw-r--r--src/3rdparty/angle/src/libANGLE/Config.h91
-rw-r--r--src/3rdparty/angle/src/libANGLE/Constants.h (renamed from src/3rdparty/angle/src/libGLESv2/constants.h)6
-rw-r--r--src/3rdparty/angle/src/libANGLE/Context.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Context.cpp)356
-rw-r--r--src/3rdparty/angle/src/libANGLE/Context.h (renamed from src/3rdparty/angle/src/libGLESv2/Context.h)84
-rw-r--r--src/3rdparty/angle/src/libANGLE/Data.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Data.cpp)4
-rw-r--r--src/3rdparty/angle/src/libANGLE/Data.h (renamed from src/3rdparty/angle/src/libGLESv2/Data.h)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/Display.cpp675
-rw-r--r--src/3rdparty/angle/src/libANGLE/Display.h124
-rw-r--r--src/3rdparty/angle/src/libANGLE/Error.cpp86
-rw-r--r--src/3rdparty/angle/src/libANGLE/Error.h83
-rw-r--r--src/3rdparty/angle/src/libANGLE/Error.inl163
-rw-r--r--src/3rdparty/angle/src/libANGLE/Fence.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Fence.cpp)9
-rw-r--r--src/3rdparty/angle/src/libANGLE/Fence.h (renamed from src/3rdparty/angle/src/libGLESv2/Fence.h)22
-rw-r--r--src/3rdparty/angle/src/libANGLE/Float16ToFloat32.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp)0
-rw-r--r--src/3rdparty/angle/src/libANGLE/Framebuffer.cpp658
-rw-r--r--src/3rdparty/angle/src/libANGLE/Framebuffer.h144
-rw-r--r--src/3rdparty/angle/src/libANGLE/FramebufferAttachment.cpp (renamed from src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp)148
-rw-r--r--src/3rdparty/angle/src/libANGLE/FramebufferAttachment.h (renamed from src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h)70
-rw-r--r--src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp133
-rw-r--r--src/3rdparty/angle/src/libANGLE/HandleAllocator.h63
-rw-r--r--src/3rdparty/angle/src/libANGLE/ImageIndex.cpp (renamed from src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp)32
-rw-r--r--src/3rdparty/angle/src/libANGLE/ImageIndex.h (renamed from src/3rdparty/angle/src/libGLESv2/ImageIndex.h)21
-rw-r--r--src/3rdparty/angle/src/libANGLE/Platform.cpp35
-rw-r--r--src/3rdparty/angle/src/libANGLE/Program.cpp (renamed from src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp)1764
-rw-r--r--src/3rdparty/angle/src/libANGLE/Program.h (renamed from src/3rdparty/angle/src/libGLESv2/ProgramBinary.h)225
-rw-r--r--src/3rdparty/angle/src/libANGLE/Query.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Query.cpp)4
-rw-r--r--src/3rdparty/angle/src/libANGLE/Query.h (renamed from src/3rdparty/angle/src/libGLESv2/Query.h)13
-rw-r--r--src/3rdparty/angle/src/libANGLE/RefCountObject.cpp (renamed from src/3rdparty/angle/src/common/RefCountObject.cpp)12
-rw-r--r--src/3rdparty/angle/src/libANGLE/RefCountObject.h110
-rw-r--r--src/3rdparty/angle/src/libANGLE/Renderbuffer.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp)69
-rw-r--r--src/3rdparty/angle/src/libANGLE/Renderbuffer.h (renamed from src/3rdparty/angle/src/libGLESv2/Renderbuffer.h)18
-rw-r--r--src/3rdparty/angle/src/libANGLE/ResourceManager.cpp (renamed from src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp)117
-rw-r--r--src/3rdparty/angle/src/libANGLE/ResourceManager.h (renamed from src/3rdparty/angle/src/libGLESv2/ResourceManager.h)45
-rw-r--r--src/3rdparty/angle/src/libANGLE/Sampler.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Sampler.cpp)4
-rw-r--r--src/3rdparty/angle/src/libANGLE/Sampler.h (renamed from src/3rdparty/angle/src/libGLESv2/Sampler.h)8
-rw-r--r--src/3rdparty/angle/src/libANGLE/Shader.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Shader.cpp)38
-rw-r--r--src/3rdparty/angle/src/libANGLE/Shader.h (renamed from src/3rdparty/angle/src/libGLESv2/Shader.h)18
-rw-r--r--src/3rdparty/angle/src/libANGLE/State.cpp (renamed from src/3rdparty/angle/src/libGLESv2/State.cpp)236
-rw-r--r--src/3rdparty/angle/src/libANGLE/State.h (renamed from src/3rdparty/angle/src/libGLESv2/State.h)60
-rw-r--r--src/3rdparty/angle/src/libANGLE/Surface.cpp166
-rw-r--r--src/3rdparty/angle/src/libANGLE/Surface.h98
-rw-r--r--src/3rdparty/angle/src/libANGLE/Texture.cpp573
-rw-r--r--src/3rdparty/angle/src/libANGLE/Texture.h156
-rw-r--r--src/3rdparty/angle/src/libANGLE/TransformFeedback.cpp (renamed from src/3rdparty/angle/src/libGLESv2/TransformFeedback.cpp)4
-rw-r--r--src/3rdparty/angle/src/libANGLE/TransformFeedback.h (renamed from src/3rdparty/angle/src/libGLESv2/TransformFeedback.h)11
-rw-r--r--src/3rdparty/angle/src/libANGLE/Uniform.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Uniform.cpp)6
-rw-r--r--src/3rdparty/angle/src/libANGLE/Uniform.h (renamed from src/3rdparty/angle/src/libGLESv2/Uniform.h)22
-rw-r--r--src/3rdparty/angle/src/libANGLE/VertexArray.cpp (renamed from src/3rdparty/angle/src/libGLESv2/VertexArray.cpp)13
-rw-r--r--src/3rdparty/angle/src/libANGLE/VertexArray.h (renamed from src/3rdparty/angle/src/libGLESv2/VertexArray.h)18
-rw-r--r--src/3rdparty/angle/src/libANGLE/VertexAttribute.cpp (renamed from src/3rdparty/angle/src/libGLESv2/VertexAttribute.cpp)22
-rw-r--r--src/3rdparty/angle/src/libANGLE/VertexAttribute.h (renamed from src/3rdparty/angle/src/libGLESv2/VertexAttribute.h)11
-rw-r--r--src/3rdparty/angle/src/libANGLE/angletypes.cpp (renamed from src/3rdparty/angle/src/libGLESv2/angletypes.cpp)62
-rw-r--r--src/3rdparty/angle/src/libANGLE/angletypes.h (renamed from src/3rdparty/angle/src/libGLESv2/angletypes.h)160
-rw-r--r--src/3rdparty/angle/src/libANGLE/features.h (renamed from src/3rdparty/angle/src/common/features.h)5
-rw-r--r--src/3rdparty/angle/src/libANGLE/formatutils.cpp (renamed from src/3rdparty/angle/src/libGLESv2/formatutils.cpp)383
-rw-r--r--src/3rdparty/angle/src/libANGLE/formatutils.h81
-rw-r--r--src/3rdparty/angle/src/libANGLE/queryconversions.cpp (renamed from src/3rdparty/angle/src/libGLESv2/queryconversions.cpp)2
-rw-r--r--src/3rdparty/angle/src/libANGLE/queryconversions.h (renamed from src/3rdparty/angle/src/libGLESv2/queryconversions.h)0
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/BufferImpl.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h)17
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/CompilerImpl.h30
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.cpp58
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.h99
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/FenceNVImpl.h34
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/FenceSyncImpl.h35
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl.h68
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/Image.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/Image.h)26
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ImplFactory.h68
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/IndexRangeCache.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp)38
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/IndexRangeCache.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h)23
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h)96
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/QueryImpl.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h)12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp)2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.h33
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/Renderer.cpp72
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/Renderer.h91
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/ShaderImpl.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h)20
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.cpp22
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.h48
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.h72
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/TransformFeedbackImpl.h)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/VertexArrayImpl.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/VertexArrayImpl.h)12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/Workarounds.h74
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp)36
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h)29
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp128
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.h48
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp357
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.h61
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp)287
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h)16
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp463
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h111
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp)35
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h)12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp47
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.h84
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp)21
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h)39
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp)60
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h)25
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp)384
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h)105
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp36
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h42
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp)57
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h43
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp628
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h)182
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp)229
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h)47
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp61
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h54
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp396
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h92
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h)29
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp)897
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h)183
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp)14
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h)29
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp)2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.h)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp)26
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h)29
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp)104
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h)23
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp)2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/copyimage.h)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.inl (renamed from src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl)0
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp)208
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h)14
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp)491
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h)38
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp)320
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h)53
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp119
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h39
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp)11
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h)13
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp270
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h45
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp)198
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h)31
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp)4
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp430
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h)22
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h (renamed from src/3rdparty/angle/src/common/NativeWindow.h)28
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp)52
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h)13
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp)19
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp)27
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h)14
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp)52
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h)34
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp)1729
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h)214
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp)16
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h)18
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp)174
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h)25
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp)716
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h)82
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp95
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h43
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h)12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp)66
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h)16
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.h40
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl (renamed from src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.inl)123
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp)479
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h)21
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp)310
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h)21
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/BufferToTexture11.hlsl (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/BufferToTexture11.hlsl)3
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Clear11.hlsl (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl)21
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl)0
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough3D11.hlsl (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Passthrough3D11.hlsl)0
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Swizzle11.hlsl (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Swizzle11.hlsl)0
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp (renamed from src/3rdparty/angle/src/common/win32/NativeWindow.cpp)16
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp (renamed from src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp)116
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h110
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp (renamed from src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp)29
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h (renamed from src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h)30
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp (renamed from src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp)6
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h (renamed from src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp)74
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h)24
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp)12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h)15
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp36
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h29
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp)7
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h)11
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp422
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h41
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp)106
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h)28
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp)4
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp)43
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h)29
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp)1080
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h)167
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h)12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp)8
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.h)14
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp)23
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h)21
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp)26
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h)26
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h)12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp)18
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp)14
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h)13
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp)96
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h)20
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp)91
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h)14
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps)6
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs (renamed from src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs)4
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h)6
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.cpp147
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h50
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/generatemip.h)12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.inl (renamed from src/3rdparty/angle/src/libGLESv2/renderer/generatemip.inl)2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/imageformats.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/imageformats.h)10
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/loadimage.cpp)13
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.h (renamed from src/3rdparty/angle/src/libGLESv2/renderer/loadimage.h)12
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.inl (renamed from src/3rdparty/angle/src/libGLESv2/renderer/loadimage.inl)2
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimageSSE2.cpp (renamed from src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp)39
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationEGL.cpp503
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationEGL.h49
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES.cpp (renamed from src/3rdparty/angle/src/libGLESv2/validationES.cpp)406
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES.h (renamed from src/3rdparty/angle/src/libGLESv2/validationES.h)22
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES2.cpp (renamed from src/3rdparty/angle/src/libGLESv2/validationES2.cpp)286
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES2.h (renamed from src/3rdparty/angle/src/libGLESv2/validationES2.h)8
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES3.cpp (renamed from src/3rdparty/angle/src/libGLESv2/validationES3.cpp)266
-rw-r--r--src/3rdparty/angle/src/libANGLE/validationES3.h (renamed from src/3rdparty/angle/src/libGLESv2/validationES3.h)11
-rw-r--r--src/3rdparty/angle/src/libEGL/Config.cpp353
-rw-r--r--src/3rdparty/angle/src/libEGL/Config.h114
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.cpp648
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.h104
-rw-r--r--src/3rdparty/angle/src/libEGL/Error.cpp48
-rw-r--r--src/3rdparty/angle/src/libEGL/Error.h39
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.cpp505
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.h120
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGL.cpp1235
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGL.def12
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGL.rc103
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGL_mingw32.def12
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGLd.def12
-rw-r--r--src/3rdparty/angle/src/libEGL/main.cpp203
-rw-r--r--src/3rdparty/angle/src/libEGL/main.h45
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Error.cpp48
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Error.h39
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py78
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp672
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Framebuffer.h126
-rw-r--r--src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp63
-rw-r--r--src/3rdparty/angle/src/libGLESv2/HandleAllocator.h44
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Program.cpp668
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Program.h151
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Texture.cpp1012
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Texture.h241
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp1127
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_egl.h74
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp271
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.h30
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.cpp4318
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.h163
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp1058
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.h78
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.cpp3394
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.h125
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.cpp14
-rw-r--r--src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.h23
-rw-r--r--src/3rdparty/angle/src/libGLESv2/formatutils.h106
-rw-r--r--src/3rdparty/angle/src/libGLESv2/global_state.cpp235
-rw-r--r--src/3rdparty/angle/src/libGLESv2/global_state.h49
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp8423
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2.def12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2.rc103
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2d.def12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.cpp186
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.h61
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h52
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp46
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp36
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h53
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h41
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp172
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h193
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h78
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h64
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h39
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.h35
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp26
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h50
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h51
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp801
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp255
-rw-r--r--src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h6
-rw-r--r--src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp2
-rw-r--r--src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h2
-rw-r--r--src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.h6
-rw-r--r--src/3rdparty/angle/src/third_party/trace_event/trace_event.h795
-rw-r--r--src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch477
-rw-r--r--src/angle/patches/0001-ANGLE-Improve-Windows-Phone-Support.patch439
-rw-r--r--src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch927
-rw-r--r--src/angle/patches/0003-ANGLE-Fix-compilation-on-MSVC2010-2012.patch363
-rw-r--r--src/angle/patches/0004-ANGLE-Dynamically-load-D3D-compiler-from-a-list.patch (renamed from src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch)33
-rw-r--r--src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch109
-rw-r--r--src/angle/patches/0005-ANGLE-Add-support-for-querying-platform-device.patch84
-rw-r--r--src/angle/patches/0009-ANGLE-Support-WinRT.patch837
-rw-r--r--src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch637
-rw-r--r--src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch48
-rw-r--r--src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch100
-rw-r--r--src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch69
-rw-r--r--src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch536
-rw-r--r--src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch169
-rw-r--r--src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch62
-rw-r--r--src/angle/patches/0018-ANGLE-Fix-releasing-textures-after-we-kill-D3D11.patch106
-rw-r--r--src/angle/patches/0019-ANGLE-Fix-handling-of-shader-source-with-fixed-lengt.patch37
-rw-r--r--src/angle/patches/0020-ANGLE-Do-not-use-std-strlen.patch30
-rw-r--r--src/angle/patches/0020-ANGLE-Fix-compilation-with-MSVC2013-Update4.patch43
-rw-r--r--src/angle/src/common/common.pri18
-rw-r--r--src/angle/src/compiler/preprocessor/preprocessor.pro2
-rw-r--r--src/angle/src/compiler/translator.pro39
-rw-r--r--src/angle/src/config.pri5
-rw-r--r--src/angle/src/libEGL/libEGL.pro35
-rw-r--r--src/angle/src/libGLESv2/libGLESv2.pro760
511 files changed, 40462 insertions, 31173 deletions
diff --git a/mkspecs/features/win32/opengl.prf b/mkspecs/features/win32/opengl.prf
index 46101d6b76..8173348bc4 100644
--- a/mkspecs/features/win32/opengl.prf
+++ b/mkspecs/features/win32/opengl.prf
@@ -21,7 +21,7 @@ wince* {
QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES2_RELEASE
}
DEFINES += QT_OPENGL_ES_2 QT_OPENGL_ES_2_ANGLE
- contains(QT_CONFIG, static): DEFINES += QT_OPENGL_ES_2_ANGLE_STATIC
+ contains(QT_CONFIG, static): DEFINES += QT_OPENGL_ES_2_ANGLE_STATIC GL_APICALL= EGLAPI=
QT_CONFIG -= opengl
} else {
!contains(QT_CONFIG, dynamicgl) {
diff --git a/src/3rdparty/angle/.gitignore b/src/3rdparty/angle/.gitignore
index cbb7e6a5af..17958a0fb5 100644
--- a/src/3rdparty/angle/.gitignore
+++ b/src/3rdparty/angle/.gitignore
@@ -6,19 +6,28 @@ build
extensions
samples
tests
-third_party
src/ipch
+util
.svn
# Files from ANGLE we don't want/need
DEPS
+*.chromium
+*.isolate
+*.md
+*.gn
*.gyp
*.gypi
*.sh
*.bat
*.patch
*.py
+*.rc
+*_unittest.cpp
codereview.settings
+src/commit.h
+src/libANGLE/renderer/gl
+src/third_party/khronos/GL
# Generated by flex/bison
src/compiler/preprocessor/Tokenizer.cpp
@@ -28,5 +37,5 @@ src/compiler/translator/glslang_tab.cpp
src/compiler/translator/glslang_tab.h
# Generated by FXC
-src/libGLESv2/renderer/d3d/d3d9/shaders/compiled/*.h
-src/libGLESv2/renderer/d3d/d3d11/shaders/compiled/*.h
+src/libANGLE/renderer/d3d/d3d9/shaders/compiled/*.h
+src/libANGLE/renderer/d3d/d3d11/shaders/compiled/*.h
diff --git a/src/3rdparty/angle/AUTHORS b/src/3rdparty/angle/AUTHORS
index be114bcf68..836bed8e8a 100644
--- a/src/3rdparty/angle/AUTHORS
+++ b/src/3rdparty/angle/AUTHORS
@@ -16,17 +16,22 @@ Autodesk, Inc.
BlackBerry Limited
Cable Television Laboratories, Inc.
Cloud Party, Inc.
+Imagination Technologies Ltd.
Intel Corporation
Mozilla Corporation
Turbulenz
Klarälvdalens Datakonsult AB
+Microsoft Corporation
Microsoft Open Technologies, Inc.
NVIDIA Corporation
+Opera Software ASA
+The Qt Company Ltd.
Jacek Caban
Mark Callow
Ginn Chen
Tibor den Ouden
+Régis Fénéon
James Hauxwell
Sam Hocevar
Pierre Leveille
@@ -35,3 +40,4 @@ Boying Lu
Aitor Moreno
Yuri O'Donnell
Josh Soref
+Maks Naumov
diff --git a/src/3rdparty/angle/CONTRIBUTORS b/src/3rdparty/angle/CONTRIBUTORS
index 6b27416e38..5252141973 100644
--- a/src/3rdparty/angle/CONTRIBUTORS
+++ b/src/3rdparty/angle/CONTRIBUTORS
@@ -1,4 +1,4 @@
-# This is the official list of people who can contribute
+# This is the official list of people who can contribute
# (and who have contributed) code to the ANGLE project
# repository.
# The AUTHORS file lists the copyright holders; this file
@@ -40,6 +40,7 @@ Google Inc.
thestig@chromium.org
Justin Schuh
Scott Graham
+ Corentin Wallez
Adobe Systems Inc.
Alexandru Chiculita
@@ -55,6 +56,9 @@ Cloud Party, Inc.
The Qt Company Ltd.
Andrew Knight
+Imagination Technologies Ltd.
+ Gregoire Payen de La Garanderie
+
Intel Corporation
Jin Yang
Andy Chen
@@ -80,10 +84,21 @@ Mark Banner (standard8mbp)
David Kilzer
Jacek Caban
Tibor den Ouden
+Régis Fénéon
+
+Microsoft Corporation
+ Cooper Partin
+ Austin Kinross
+ Minmin Gong
Microsoft Open Technologies, Inc.
-Cooper Partin
-Austin Kinross
+ Cooper Partin
+ Austin Kinross
NVIDIA Corporation
Olli Etuaho
+ Arun Patole
+ Qingqing Deng
+
+Opera Software ASA
+ Daniel Bratell
diff --git a/src/3rdparty/angle/include/EGL/egl.h b/src/3rdparty/angle/include/EGL/egl.h
index 12590a0e20..5a27291213 100644
--- a/src/3rdparty/angle/include/EGL/egl.h
+++ b/src/3rdparty/angle/include/EGL/egl.h
@@ -33,12 +33,12 @@ extern "C" {
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
-** Khronos $Revision: 27018 $ on $Date: 2014-06-10 08:06:12 -0700 (Tue, 10 Jun 2014) $
+** Khronos $Revision: 29318 $ on $Date: 2015-01-02 03:16:10 -0800 (Fri, 02 Jan 2015) $
*/
#include <EGL/eglplatform.h>
-/* Generated on date 20140610 */
+/* Generated on date 20150102 */
/* Generated C header for:
* API: egl
@@ -240,6 +240,7 @@ EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
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
@@ -281,10 +282,14 @@ typedef khronos_utime_nanoseconds_t EGLTime;
#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 ((EGLImage)0)
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);
diff --git a/src/3rdparty/angle/include/EGL/eglext.h b/src/3rdparty/angle/include/EGL/eglext.h
index 0cc5eec293..a44afecb3f 100644
--- a/src/3rdparty/angle/include/EGL/eglext.h
+++ b/src/3rdparty/angle/include/EGL/eglext.h
@@ -440,24 +440,28 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#ifndef EGL_ANGLE_platform_angle
#define EGL_ANGLE_platform_angle 1
-#define EGL_PLATFORM_ANGLE_ANGLE 0x3201
-#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202
-#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3203
-#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3204
-#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3205
+#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
#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 0x3206
-#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207
-#define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208
+#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
+#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C
+#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
#endif /* EGL_ANGLE_platform_angle_d3d */
#ifndef EGL_ANGLE_platform_angle_opengl
#define EGL_ANGLE_platform_angle_opengl 1
-#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3209
-#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320A
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
#endif /* EGL_ANGLE_platform_angle_opengl */
#ifndef EGL_ARM_pixmap_multisample_discard
diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h
index 2eb3674a0b..519df3e750 100644
--- a/src/3rdparty/angle/include/EGL/eglplatform.h
+++ b/src/3rdparty/angle/include/EGL/eglplatform.h
@@ -73,15 +73,14 @@
#endif
#include <windows.h>
+typedef HDC EGLNativeDisplayType;
typedef HBITMAP EGLNativePixmapType;
-#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) /* Windows Store */
+#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) /* Windows Desktop */
+typedef HWND EGLNativeWindowType;
+#else /* Windows Store */
#include <inspectable.h>
-typedef IInspectable* EGLNativeDisplayType;
typedef IInspectable* EGLNativeWindowType;
-#else
-typedef HDC EGLNativeDisplayType;
-typedef HWND EGLNativeWindowType;
#endif
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
@@ -110,6 +109,14 @@ typedef Display *EGLNativeDisplayType;
typedef Pixmap EGLNativePixmapType;
typedef Window EGLNativeWindowType;
+#elif defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) )
+
+// TODO(jmadill): native implementation for OSX
+
+typedef void *EGLNativeDisplayType;
+typedef void *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
#else
#error "Platform not recognized"
#endif
diff --git a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
index 647fed6a02..126205af2c 100644
--- a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
+++ b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
@@ -3,8 +3,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-#ifndef _COMPILER_INTERFACE_INCLUDED_
-#define _COMPILER_INTERFACE_INCLUDED_
+#ifndef GLSLANG_SHADERLANG_H_
+#define GLSLANG_SHADERLANG_H_
#if defined(COMPONENT_BUILD) && !defined(ANGLE_TRANSLATOR_STATIC)
#if defined(_WIN32) || defined(_WIN64)
@@ -48,7 +48,7 @@ typedef unsigned int GLenum;
// Version number for shader translation API.
// It is incremented every time the API changes.
-#define ANGLE_SH_VERSION 132
+#define ANGLE_SH_VERSION 134
typedef enum {
SH_GLES2_SPEC = 0x8B40,
@@ -81,11 +81,16 @@ typedef enum {
} ShShaderSpec;
typedef enum {
- SH_ESSL_OUTPUT = 0x8B45,
- SH_GLSL_OUTPUT = 0x8B46,
- SH_HLSL_OUTPUT = 0x8B47,
- SH_HLSL9_OUTPUT = 0x8B47,
- SH_HLSL11_OUTPUT = 0x8B48
+ SH_ESSL_OUTPUT = 0x8B45,
+ // SH_GLSL_OUTPUT is deprecated. This is to not break the build.
+ SH_GLSL_OUTPUT = 0x8B46,
+ SH_GLSL_COMPATIBILITY_OUTPUT = 0x8B46,
+ SH_GLSL_CORE_OUTPUT = 0x8B47,
+
+ // HLSL output only supported in some configurations.
+ SH_HLSL_OUTPUT = 0x8B48,
+ SH_HLSL9_OUTPUT = 0x8B48,
+ SH_HLSL11_OUTPUT = 0x8B49
} ShShaderOutput;
// Compile options.
@@ -223,6 +228,10 @@ typedef struct
int EXT_draw_buffers;
int EXT_frag_depth;
int EXT_shader_texture_lod;
+ int WEBGL_debug_shader_precision;
+ int EXT_shader_framebuffer_fetch;
+ int NV_shader_framebuffer_fetch;
+ int ARM_shader_framebuffer_fetch;
// 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
@@ -290,7 +299,8 @@ COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle ha
// spec: Specifies the language spec the compiler must conform to -
// SH_GLES2_SPEC or SH_WEBGL_SPEC.
// output: Specifies the output code type - SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
-// SH_HLSL9_OUTPUT or SH_HLSL11_OUTPUT.
+// SH_HLSL9_OUTPUT or SH_HLSL11_OUTPUT. Note: HLSL output is only
+// supported in some configurations.
// resources: Specifies the built-in resources.
COMPILER_EXPORT ShHandle ShConstructCompiler(
sh::GLenum type,
@@ -408,4 +418,4 @@ COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle,
const std::string &uniformName,
unsigned int *indexOut);
-#endif // _COMPILER_INTERFACE_INCLUDED_
+#endif // GLSLANG_SHADERLANG_H_
diff --git a/src/3rdparty/angle/include/GLSLANG/ShaderVars.h b/src/3rdparty/angle/include/GLSLANG/ShaderVars.h
index da21c3e76e..4128c343f8 100644
--- a/src/3rdparty/angle/include/GLSLANG/ShaderVars.h
+++ b/src/3rdparty/angle/include/GLSLANG/ShaderVars.h
@@ -7,8 +7,8 @@
// Types to represent GL variables (varyings, uniforms, etc)
//
-#ifndef _COMPILER_INTERFACE_VARIABLES_
-#define _COMPILER_INTERFACE_VARIABLES_
+#ifndef GLSLANG_SHADERVARS_H_
+#define GLSLANG_SHADERVARS_H_
#include <string>
#include <vector>
@@ -28,6 +28,9 @@ enum InterpolationType
INTERPOLATION_FLAT
};
+// Validate link & SSO consistency of interpolation qualifiers
+COMPILER_EXPORT 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
{
@@ -182,4 +185,4 @@ struct COMPILER_EXPORT InterfaceBlock
}
-#endif // _COMPILER_INTERFACE_VARIABLES_
+#endif // GLSLANG_SHADERVARS_H_
diff --git a/src/3rdparty/angle/include/KHR/khrplatform.h b/src/3rdparty/angle/include/KHR/khrplatform.h
index 1ac2d3f324..c9e6f17d34 100644..100755
--- a/src/3rdparty/angle/include/KHR/khrplatform.h
+++ b/src/3rdparty/angle/include/KHR/khrplatform.h
@@ -97,7 +97,7 @@
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
-#if defined(_WIN32) && !defined(__SCITECH_SNAP__) && !defined(QT_OPENGL_ES_2_ANGLE_STATIC)
+#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
diff --git a/src/3rdparty/angle/include/angle_gl.h b/src/3rdparty/angle/include/angle_gl.h
index d093f75ee2..e7ecdbd2f0 100644
--- a/src/3rdparty/angle/include/angle_gl.h
+++ b/src/3rdparty/angle/include/angle_gl.h
@@ -7,8 +7,8 @@
// Includes all necessary GL headers and definitions for ANGLE.
//
-#ifndef ANGLE_GL_H_
-#define ANGLE_GL_H_
+#ifndef ANGLEGL_H_
+#define ANGLEGL_H_
#include "GLES2/gl2.h"
#include "GLES2/gl2ext.h"
@@ -20,4 +20,4 @@
#define GL_SAMPLER_2D_RECT_ARB 0x8B63
#endif
-#endif // ANGLE_GL_H_
+#endif // ANGLEGL_H_
diff --git a/src/3rdparty/angle/include/export.h b/src/3rdparty/angle/include/export.h
new file mode 100644
index 0000000000..cdf6245d6d
--- /dev/null
+++ b/src/3rdparty/angle/include/export.h
@@ -0,0 +1,28 @@
+//
+// Copyright(c) 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(_WIN32)
+# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION)
+# define ANGLE_EXPORT __declspec(dllexport)
+# else
+# define ANGLE_EXPORT __declspec(dllimport)
+# endif
+#elif defined(__GNUC__)
+# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION)
+# define ANGLE_EXPORT __attribute__((visibility ("default")))
+# else
+# define ANGLE_EXPORT
+# endif
+#else
+# define ANGLE_EXPORT
+#endif
+
+#endif // LIBGLESV2_EXPORT_H_
diff --git a/src/3rdparty/angle/include/platform/Platform.h b/src/3rdparty/angle/include/platform/Platform.h
new file mode 100644
index 0000000000..d915d5c0fd
--- /dev/null
+++ b/src/3rdparty/angle/include/platform/Platform.h
@@ -0,0 +1,112 @@
+//
+// Copyright (c) 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.h: The public interface ANGLE exposes to the API layer, for
+// doing platform-specific tasks like gathering data, or for tracing.
+
+#ifndef ANGLE_PLATFORM_H
+#define ANGLE_PLATFORM_H
+
+#include <stdint.h>
+
+#include "../export.h"
+
+namespace angle
+{
+
+class Platform
+{
+ public:
+
+ // Tracing --------
+
+ typedef uint64_t TraceEventHandle;
+
+ // 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 consutruction and destruction of
+ // objects, specify the pointer as the id parameter.
+ // - 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.
+ virtual TraceEventHandle addTraceEvent(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.
+ virtual void updateTraceEventDuration(const unsigned char* categoryEnabledFlag, const char* name, TraceEventHandle) { }
+
+ // Callbacks for reporting histogram data.
+ // CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50 would do.
+ virtual void histogramCustomCounts(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.
+ virtual void histogramEnumeration(const char* name, int sample, int boundaryValue) { }
+ // Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets.
+ virtual void histogramSparse(const char* name, int sample) { }
+
+ protected:
+ virtual ~Platform() { }
+};
+
+}
+
+typedef void(*ANGLEPlatformInitializeFunc)(angle::Platform*);
+ANGLE_EXPORT void ANGLEPlatformInitialize(angle::Platform*);
+
+typedef void (*ANGLEPlatformShutdownFunc)();
+ANGLE_EXPORT void ANGLEPlatformShutdown();
+
+typedef angle::Platform *(*ANGLEPlatformCurrentFunc)();
+ANGLE_EXPORT angle::Platform *ANGLEPlatformCurrent();
+
+#endif // ANGLE_PLATFORM_H
diff --git a/src/3rdparty/angle/src/commit.h b/src/3rdparty/angle/src/commit.h
deleted file mode 100644
index 08fc893c25..0000000000
--- a/src/3rdparty/angle/src/commit.h
+++ /dev/null
@@ -1,12 +0,0 @@
-//
-// Copyright (c) 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.
-//
-// commit.h:
-// This is a default commit hash header, when git is not available.
-//
-
-#define ANGLE_COMMIT_HASH "30d6c255d238"
-#define ANGLE_COMMIT_HASH_SIZE 12
-#define ANGLE_COMMIT_DATE "2014-11-13 17:37:03 +0000"
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp b/src/3rdparty/angle/src/common/MemoryBuffer.cpp
index 2b5b09a324..e7a3fb4a2b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp
+++ b/src/3rdparty/angle/src/common/MemoryBuffer.cpp
@@ -4,12 +4,13 @@
// found in the LICENSE file.
//
-#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
-#include "common/debug.h"
+#include "common/MemoryBuffer.h"
#include <algorithm>
#include <cstdlib>
+#include "common/debug.h"
+
namespace rx
{
@@ -32,26 +33,31 @@ bool MemoryBuffer::resize(size_t size)
free(mData);
mData = NULL;
mSize = 0;
+ return true;
+ }
+
+ if (size == mSize)
+ {
+ return true;
}
- else
+
+ // Only reallocate if the size has changed.
+ uint8_t *newMemory = reinterpret_cast<uint8_t*>(malloc(sizeof(uint8_t) * size));
+ if (newMemory == NULL)
+ {
+ return false;
+ }
+
+ if (mData)
{
- uint8_t *newMemory = reinterpret_cast<uint8_t*>(malloc(sizeof(uint8_t) * size));
- if (newMemory == NULL)
- {
- 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;
+ // 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;
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.h b/src/3rdparty/angle/src/common/MemoryBuffer.h
index c65f79fe10..ec621cbca7 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/MemoryBuffer.h
+++ b/src/3rdparty/angle/src/common/MemoryBuffer.h
@@ -4,16 +4,18 @@
// found in the LICENSE file.
//
-#ifndef LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H_
-#define LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H_
+#ifndef COMMON_MEMORYBUFFER_H_
+#define COMMON_MEMORYBUFFER_H_
+
+#include "common/angleutils.h"
#include <cstddef>
-#include <cstdint>
+#include <stdint.h>
namespace rx
{
-class MemoryBuffer
+class MemoryBuffer : angle::NonCopyable
{
public:
MemoryBuffer();
@@ -33,4 +35,4 @@ class MemoryBuffer
}
-#endif // LIBGLESV2_RENDERER_D3D_MEMORYBUFFER_H
+#endif // COMMON_MEMORYBUFFER_H_
diff --git a/src/3rdparty/angle/src/common/Optional.h b/src/3rdparty/angle/src/common/Optional.h
new file mode 100644
index 0000000000..9665b7ddf6
--- /dev/null
+++ b/src/3rdparty/angle/src/common/Optional.h
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 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_
+
+template <class T>
+struct Optional
+{
+ Optional()
+ : mValid(false),
+ mValue(T())
+ {}
+
+ explicit 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;
+ }
+
+ static Optional None()
+ {
+ return Optional();
+ }
+
+ bool valid() const { return mValid; }
+ 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);
+ }
+
+ private:
+ bool mValid;
+ T mValue;
+};
+
+#endif // COMMON_OPTIONAL_H_
diff --git a/src/3rdparty/angle/src/common/RefCountObject.h b/src/3rdparty/angle/src/common/RefCountObject.h
deleted file mode 100644
index 6eeaee1928..0000000000
--- a/src/3rdparty/angle/src/common/RefCountObject.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// 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 COMMON_REFCOUNTOBJECT_H_
-#define COMMON_REFCOUNTOBJECT_H_
-
-#include "common/debug.h"
-
-#include "angle_gl.h"
-
-#include <cstddef>
-
-class RefCountObject
-{
- public:
- explicit RefCountObject(GLuint id);
- virtual ~RefCountObject();
-
- virtual void addRef() const;
- virtual void release() const;
-
- GLuint id() const { return mId; }
-
- private:
- GLuint mId;
-
- mutable std::size_t mRefCount;
-};
-
-class RefCountObjectBindingPointer
-{
- protected:
- RefCountObjectBindingPointer() : mObject(NULL) { }
- ~RefCountObjectBindingPointer() { ASSERT(mObject == NULL); } // Objects have to be released before the resource manager is destroyed, so they must be explicitly cleaned up.
-
- void set(RefCountObject *newObject);
- RefCountObject *get() const { return mObject; }
-
- public:
- GLuint id() const { return (mObject != NULL) ? mObject->id() : 0; }
- bool operator!() const { return (get() == NULL); }
-
- private:
- RefCountObject *mObject;
-};
-
-template <class ObjectType>
-class BindingPointer : public RefCountObjectBindingPointer
-{
- public:
- void set(ObjectType *newObject) { RefCountObjectBindingPointer::set(newObject); }
- ObjectType *get() const { return static_cast<ObjectType*>(RefCountObjectBindingPointer::get()); }
- ObjectType *operator->() const { return get(); }
-};
-
-template <class ObjectType>
-class OffsetBindingPointer : public RefCountObjectBindingPointer
-{
- public:
- OffsetBindingPointer() : mOffset(0), mSize(0) { }
-
- void set(ObjectType *newObject)
- {
- RefCountObjectBindingPointer::set(newObject);
- mOffset = 0;
- mSize = 0;
- }
-
- void set(ObjectType *newObject, GLintptr offset, GLsizeiptr size)
- {
- RefCountObjectBindingPointer::set(newObject);
- mOffset = offset;
- mSize = size;
- }
-
- GLintptr getOffset() const { return mOffset; }
- GLsizeiptr getSize() const { return mSize; }
-
- ObjectType *get() const { return static_cast<ObjectType*>(RefCountObjectBindingPointer::get()); }
- ObjectType *operator->() const { return get(); }
-
- private:
- GLintptr mOffset;
- GLsizeiptr mSize;
-};
-
-#endif // COMMON_REFCOUNTOBJECT_H_
diff --git a/src/3rdparty/angle/src/common/angleutils.cpp b/src/3rdparty/angle/src/common/angleutils.cpp
index c1367c460a..af5eb6c447 100644
--- a/src/3rdparty/angle/src/common/angleutils.cpp
+++ b/src/3rdparty/angle/src/common/angleutils.cpp
@@ -5,7 +5,8 @@
//
#include "common/angleutils.h"
-#include "debug.h"
+#include "common/debug.h"
+
#include <stdio.h>
#include <vector>
diff --git a/src/3rdparty/angle/src/common/angleutils.h b/src/3rdparty/angle/src/common/angleutils.h
index b343ece5bc..4cf84a3182 100644
--- a/src/3rdparty/angle/src/common/angleutils.h
+++ b/src/3rdparty/angle/src/common/angleutils.h
@@ -11,19 +11,31 @@
#include "common/platform.h"
-#include <stddef.h>
-#include <limits.h>
+#include <climits>
+#include <cstdarg>
+#include <cstddef>
#include <string>
#include <set>
#include <sstream>
-#include <cstdarg>
#include <vector>
-// A macro to disallow the copy constructor and operator= functions
-// This must be used in the private: declarations for a class
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
- TypeName(const TypeName&); \
- void operator=(const TypeName&)
+// A helper class to disallow copy and assignment operators
+namespace angle
+{
+
+class NonCopyable
+{
+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+ public:
+ NonCopyable() = default;
+ ~NonCopyable() = default;
+ protected:
+ NonCopyable(const NonCopyable&) = delete;
+ void operator=(const NonCopyable&) = delete;
+#endif
+};
+
+}
template <typename T, size_t N>
inline size_t ArraySize(T(&)[N])
@@ -150,13 +162,12 @@ std::string FormatString(const char *fmt, ...);
#define snprintf _snprintf
#endif
-#define VENDOR_ID_AMD 0x1002
-#define VENDOR_ID_INTEL 0x8086
-#define VENDOR_ID_NVIDIA 0x10DE
-
#define GL_BGRA4_ANGLEX 0x6ABC
#define GL_BGR5_A1_ANGLEX 0x6ABD
#define GL_INT_64_ANGLEX 0x6ABE
#define GL_STRUCT_ANGLEX 0x6ABF
+// Hidden enum for the NULL D3D device type.
+#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x6AC0
+
#endif // COMMON_ANGLEUTILS_H_
diff --git a/src/3rdparty/angle/src/common/debug.cpp b/src/3rdparty/angle/src/common/debug.cpp
index 5f55ff1e39..2fc0a2984a 100644
--- a/src/3rdparty/angle/src/common/debug.cpp
+++ b/src/3rdparty/angle/src/common/debug.cpp
@@ -17,172 +17,9 @@
namespace gl
{
-#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
-// Wraps the D3D9/D3D11 debug annotation functions.
-class DebugAnnotationWrapper
-{
- public:
- DebugAnnotationWrapper() { };
- virtual ~DebugAnnotationWrapper() { };
- virtual void beginEvent(const std::wstring &eventName) = 0;
- virtual void endEvent() = 0;
- virtual void setMarker(const std::wstring &markerName) = 0;
- virtual bool getStatus() = 0;
-};
-#if defined(ANGLE_ENABLE_D3D9)
-class D3D9DebugAnnotationWrapper : public DebugAnnotationWrapper
+namespace
{
- public:
- void beginEvent(const std::wstring &eventName)
- {
- D3DPERF_BeginEvent(0, eventName.c_str());
- }
-
- void endEvent()
- {
- D3DPERF_EndEvent();
- }
-
- void setMarker(const std::wstring &markerName)
- {
- D3DPERF_SetMarker(0, markerName.c_str());
- }
-
- bool getStatus()
- {
- return !!D3DPERF_GetStatus();
- }
-};
-#endif // ANGLE_ENABLE_D3D9
-
-#if defined(ANGLE_ENABLE_D3D11)
-class D3D11DebugAnnotationWrapper : public DebugAnnotationWrapper
-{
- public:
-
- D3D11DebugAnnotationWrapper()
- : mInitialized(false),
- mD3d11Module(NULL),
- mUserDefinedAnnotation(NULL)
- {
- // D3D11 devices can't be created during DllMain.
- // We defer device creation until the object is actually used.
- }
-
- ~D3D11DebugAnnotationWrapper()
- {
- if (mInitialized)
- {
- SafeRelease(mUserDefinedAnnotation);
- FreeLibrary(mD3d11Module);
- }
- }
-
- virtual void beginEvent(const std::wstring &eventName)
- {
- initializeDevice();
-
- mUserDefinedAnnotation->BeginEvent(eventName.c_str());
- }
-
- virtual void endEvent()
- {
- initializeDevice();
-
- mUserDefinedAnnotation->EndEvent();
- }
-
- virtual void setMarker(const std::wstring &markerName)
- {
- initializeDevice();
-
- mUserDefinedAnnotation->SetMarker(markerName.c_str());
- }
-
- virtual bool getStatus()
- {
- // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in Visual Studio 2013.
-
-#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE)
- // In the Windows Store, we can use IDXGraphicsAnalysis. The call to GetDebugInterface1 only succeeds if the app is under capture.
- // This should only be called in DEBUG mode.
- // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows Store ingestion checks.
- IDXGraphicsAnalysis* graphicsAnalysis;
- DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis));
- bool underCapture = (graphicsAnalysis != NULL);
- SafeRelease(graphicsAnalysis);
- return underCapture;
-#endif
-
- // Otherwise, we have to return true here.
- return true;
- }
-
- protected:
-
- void initializeDevice()
- {
- if (!mInitialized)
- {
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
- ASSERT(mD3d11Module);
-
- PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
- ASSERT(D3D11CreateDevice != NULL);
-#endif // !ANGLE_ENABLE_WINDOWS_STORE
-
- ID3D11Device* device = NULL;
- ID3D11DeviceContext* context = NULL;
-
- HRESULT hr = E_FAIL;
-
- // Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device.
- hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device, NULL, &context);
- ASSERT(SUCCEEDED(hr));
-
- hr = context->QueryInterface(__uuidof(mUserDefinedAnnotation), reinterpret_cast<void**>(&mUserDefinedAnnotation));
- ASSERT(SUCCEEDED(hr) && mUserDefinedAnnotation != NULL);
-
- SafeRelease(device);
- SafeRelease(context);
-
- mInitialized = true;
- }
- }
-
- bool mInitialized;
- HMODULE mD3d11Module;
- ID3DUserDefinedAnnotation* mUserDefinedAnnotation;
-};
-#endif // ANGLE_ENABLE_D3D11
-
-static DebugAnnotationWrapper* g_DebugAnnotationWrapper = NULL;
-
-void InitializeDebugAnnotations()
-{
-#if defined(ANGLE_ENABLE_D3D9)
- g_DebugAnnotationWrapper = new D3D9DebugAnnotationWrapper();
-#elif defined(ANGLE_ENABLE_D3D11)
- // If the project uses D3D9 then we can use the D3D9 debug annotations, even with the D3D11 renderer.
- // However, if D3D9 is unavailable (e.g. in Windows Store), then we use D3D11 debug annotations.
- // The D3D11 debug annotations are methods on ID3DUserDefinedAnnotation, which is implemented by the DeviceContext.
- // This doesn't have to be the same DeviceContext that the renderer uses, though.
- g_DebugAnnotationWrapper = new D3D11DebugAnnotationWrapper();
-#endif
-}
-
-void UninitializeDebugAnnotations()
-{
- if (g_DebugAnnotationWrapper != NULL)
- {
- SafeDelete(g_DebugAnnotationWrapper);
- }
-}
-
-#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
-
enum DebugTraceOutputType
{
DebugTraceOutputTypeNone,
@@ -190,29 +27,44 @@ enum DebugTraceOutputType
DebugTraceOutputTypeBeginEvent
};
-static void output(bool traceInDebugOnly, DebugTraceOutputType outputType, const char *format, va_list vararg)
-{
-#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
- static std::vector<char> buffer(512);
+DebugAnnotator *g_debugAnnotator = nullptr;
- if (perfActive())
+void output(bool traceInDebugOnly, MessageType messageType, DebugTraceOutputType outputType,
+ const char *format, va_list vararg)
+{
+ if (DebugAnnotationsActive())
{
+ static std::vector<char> buffer(512);
size_t len = FormatStringIntoVector(format, vararg, buffer);
std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len);
+ ASSERT(g_debugAnnotator != nullptr);
switch (outputType)
{
- case DebugTraceOutputTypeNone:
- break;
- case DebugTraceOutputTypeBeginEvent:
- g_DebugAnnotationWrapper->beginEvent(formattedWideMessage);
- break;
- case DebugTraceOutputTypeSetMarker:
- g_DebugAnnotationWrapper->setMarker(formattedWideMessage);
- break;
+ case DebugTraceOutputTypeNone:
+ break;
+ case DebugTraceOutputTypeBeginEvent:
+ g_debugAnnotator->beginEvent(formattedWideMessage);
+ break;
+ case DebugTraceOutputTypeSetMarker:
+ g_debugAnnotator->setMarker(formattedWideMessage);
+ break;
}
}
-#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
+
+ std::string formattedMessage;
+ UNUSED_TRACE_VARIABLE(formattedMessage);
+
+#if !defined(NDEBUG) && defined(_MSC_VER)
+ if (messageType == MESSAGE_ERR)
+ {
+ if (formattedMessage.empty())
+ {
+ formattedMessage = FormatString(format, vararg);
+ }
+ OutputDebugStringA(formattedMessage.c_str());
+ }
+#endif
#if defined(ANGLE_ENABLE_DEBUG_TRACE)
#if defined(NDEBUG)
@@ -221,7 +73,10 @@ static void output(bool traceInDebugOnly, DebugTraceOutputType outputType, const
return;
}
#endif // NDEBUG
- std::string formattedMessage = FormatString(format, vararg);
+ if (formattedMessage.empty())
+ {
+ formattedMessage = FormatString(format, vararg);
+ }
static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
if (file)
@@ -237,53 +92,57 @@ static void output(bool traceInDebugOnly, DebugTraceOutputType outputType, const
#endif // ANGLE_ENABLE_DEBUG_TRACE
}
-void trace(bool traceInDebugOnly, const char *format, ...)
+} // namespace
+
+bool DebugAnnotationsActive()
{
- va_list vararg;
- va_start(vararg, format);
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
- output(traceInDebugOnly, DebugTraceOutputTypeSetMarker, format, vararg);
+ return g_debugAnnotator != nullptr && g_debugAnnotator->getStatus();
#else
- output(traceInDebugOnly, DebugTraceOutputTypeNone, format, vararg);
+ return false;
#endif
- va_end(vararg);
}
-bool perfActive()
+void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator)
{
-#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
- static bool active = g_DebugAnnotationWrapper->getStatus();
- return active;
-#else
- return false;
-#endif
+ UninitializeDebugAnnotations();
+ g_debugAnnotator = debugAnnotator;
+}
+
+void UninitializeDebugAnnotations()
+{
+ // Pointer is not managed.
+ g_debugAnnotator = nullptr;
+}
+
+void trace(bool traceInDebugOnly, MessageType messageType, const char *format, ...)
+{
+ va_list vararg;
+ va_start(vararg, format);
+ output(traceInDebugOnly, messageType, DebugTraceOutputTypeSetMarker, format, vararg);
+ va_end(vararg);
}
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
{
#if !defined(ANGLE_ENABLE_DEBUG_TRACE)
- if (!perfActive())
+ if (!DebugAnnotationsActive())
{
return;
}
#endif // !ANGLE_ENABLE_DEBUG_TRACE
va_list vararg;
va_start(vararg, format);
-#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
- output(true, DebugTraceOutputTypeBeginEvent, format, vararg);
-#else
- output(true, DebugTraceOutputTypeNone, format, vararg);
-#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
+ output(true, MESSAGE_EVENT, DebugTraceOutputTypeBeginEvent, format, vararg);
va_end(vararg);
}
ScopedPerfEventHelper::~ScopedPerfEventHelper()
{
-#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
- if (perfActive())
+ if (DebugAnnotationsActive())
{
- g_DebugAnnotationWrapper->endEvent();
+ g_debugAnnotator->endEvent();
}
-#endif
}
+
}
diff --git a/src/3rdparty/angle/src/common/debug.h b/src/3rdparty/angle/src/common/debug.h
index c177f51314..c4f118ebae 100644
--- a/src/3rdparty/angle/src/common/debug.h
+++ b/src/3rdparty/angle/src/common/debug.h
@@ -9,8 +9,9 @@
#ifndef COMMON_DEBUG_H_
#define COMMON_DEBUG_H_
-#include <stdio.h>
#include <assert.h>
+#include <stdio.h>
+#include <string>
#include "common/angleutils.h"
@@ -20,50 +21,71 @@
namespace gl
{
- // Outputs text to the debugging log, or the debugging window
- void trace(bool traceInDebugOnly, const char *format, ...);
- // Returns whether D3DPERF is active.
- bool perfActive();
+enum MessageType
+{
+ MESSAGE_TRACE,
+ MESSAGE_FIXME,
+ MESSAGE_ERR,
+ MESSAGE_EVENT,
+};
- // Pairs a D3D begin event with an end event.
- class ScopedPerfEventHelper
- {
- public:
- ScopedPerfEventHelper(const char* format, ...);
- ~ScopedPerfEventHelper();
+// Outputs text to the debugging log, or the debugging window
+void trace(bool traceInDebugOnly, MessageType messageType, const char *format, ...);
- private:
- DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper);
- };
+// Pairs a D3D begin event with an end event.
+class ScopedPerfEventHelper : angle::NonCopyable
+{
+ public:
+ ScopedPerfEventHelper(const char* format, ...);
+ ~ScopedPerfEventHelper();
+};
+
+// Wraps the D3D9/D3D11 debug annotation functions.
+class DebugAnnotator : angle::NonCopyable
+{
+ public:
+ DebugAnnotator() { };
+ virtual ~DebugAnnotator() { };
+ virtual void beginEvent(const std::wstring &eventName) = 0;
+ virtual void endEvent() = 0;
+ virtual void setMarker(const std::wstring &markerName) = 0;
+ virtual bool getStatus() = 0;
+};
+
+void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator);
+void UninitializeDebugAnnotations();
+bool DebugAnnotationsActive();
- void InitializeDebugAnnotations();
- void UninitializeDebugAnnotations();
}
-// A macro to output a trace of a function call and its arguments to the debugging log
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
-#define TRACE(message, ...) gl::trace(true, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define ANGLE_TRACE_ENABLED
+#endif
+
+// A macro to output a trace of a function call and its arguments to the debugging log
+#if defined(ANGLE_TRACE_ENABLED)
+#define TRACE(message, ...) gl::trace(true, gl::MESSAGE_TRACE, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define TRACE(message, ...) (void(0))
#endif
// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing.
-#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
-#define FIXME(message, ...) gl::trace(false, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#if defined(ANGLE_TRACE_ENABLED)
+#define FIXME(message, ...) gl::trace(false, gl::MESSAGE_FIXME, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define FIXME(message, ...) (void(0))
#endif
// A macro to output a function call and its arguments to the debugging log, in case of error.
-#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
-#define ERR(message, ...) gl::trace(false, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#if defined(ANGLE_TRACE_ENABLED)
+#define ERR(message, ...) gl::trace(false, gl::MESSAGE_ERR, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define ERR(message, ...) (void(0))
#endif
// A macro to log a performance event around a scope.
-#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+#if defined(ANGLE_TRACE_ENABLED)
#if defined(_MSC_VER)
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__);
#else
@@ -73,6 +95,10 @@ namespace gl
#define EVENT(message, ...) (void(0))
#endif
+#if defined(ANGLE_TRACE_ENABLED)
+#undef ANGLE_TRACE_ENABLED
+#endif
+
// A macro asserting a condition and outputting failures to the debug log
#if !defined(NDEBUG)
#define ASSERT(expression) do { \
@@ -130,14 +156,4 @@ namespace gl
#define HAS_DYNAMIC_TYPE(type, obj) true
#endif
-// A macro functioning as a compile-time assert to validate constant conditions
-#if (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__GNUC__) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3))
-#define META_ASSERT_MSG(condition, msg) static_assert(condition, msg)
-#else
-#define META_ASSERT_CONCAT(a, b) a ## b
-#define META_ASSERT_CONCAT2(a, b) META_ASSERT_CONCAT(a, b)
-#define META_ASSERT_MSG(condition, msg) typedef int META_ASSERT_CONCAT2(COMPILE_TIME_ASSERT_, __LINE__)[static_cast<bool>(condition)?1:-1]
-#endif
-#define META_ASSERT(condition) META_ASSERT_MSG(condition, "compile time assertion failed.")
-
#endif // COMMON_DEBUG_H_
diff --git a/src/3rdparty/angle/src/common/event_tracer.cpp b/src/3rdparty/angle/src/common/event_tracer.cpp
new file mode 100644
index 0000000000..eb0c98c9e5
--- /dev/null
+++ b/src/3rdparty/angle/src/common/event_tracer.cpp
@@ -0,0 +1,38 @@
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "common/event_tracer.h"
+
+namespace gl
+{
+
+GetCategoryEnabledFlagFunc g_getCategoryEnabledFlag;
+AddTraceEventFunc g_addTraceEvent;
+
+} // namespace gl
+
+namespace gl
+{
+
+const unsigned char* TraceGetTraceCategoryEnabledFlag(const char* name)
+{
+ if (g_getCategoryEnabledFlag)
+ {
+ return g_getCategoryEnabledFlag(name);
+ }
+ static unsigned char disabled = 0;
+ return &disabled;
+}
+
+void TraceAddTraceEvent(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)
+{
+ if (g_addTraceEvent)
+ {
+ g_addTraceEvent(phase, categoryGroupEnabled, name, id, numArgs, argNames, argTypes, argValues, flags);
+ }
+}
+
+} // namespace gl
diff --git a/src/3rdparty/angle/src/common/event_tracer.h b/src/3rdparty/angle/src/common/event_tracer.h
new file mode 100644
index 0000000000..dbe4c1bef9
--- /dev/null
+++ b/src/3rdparty/angle/src/common/event_tracer.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_EVENT_TRACER_H_
+#define COMMON_EVENT_TRACER_H_
+
+#include "common/platform.h"
+
+extern "C" {
+
+typedef const unsigned char* (*GetCategoryEnabledFlagFunc)(const char* name);
+typedef void (*AddTraceEventFunc)(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 gl
+{
+
+extern GetCategoryEnabledFlagFunc g_getCategoryEnabledFlag;
+extern AddTraceEventFunc g_addTraceEvent;
+
+const unsigned char* TraceGetTraceCategoryEnabledFlag(const char* name);
+
+void TraceAddTraceEvent(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);
+
+}
+
+#endif // COMMON_EVENT_TRACER_H_
diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h
index a1717892fd..1015bd2312 100644
--- a/src/3rdparty/angle/src/common/mathutil.h
+++ b/src/3rdparty/angle/src/common/mathutil.h
@@ -6,8 +6,8 @@
// mathutil.h: Math and bit manipulation functions.
-#ifndef LIBGLESV2_MATHUTIL_H_
-#define LIBGLESV2_MATHUTIL_H_
+#ifndef COMMON_MATHUTIL_H_
+#define COMMON_MATHUTIL_H_
#include "common/debug.h"
#include "common/platform.h"
@@ -15,6 +15,7 @@
#include <limits>
#include <algorithm>
#include <string.h>
+#include <stdlib.h>
namespace gl
{
@@ -118,6 +119,9 @@ inline bool supportsSSE2()
return supports;
}
+#if defined(__GNUC__)
+ supports = __builtin_cpu_supports("sse2");
+#else
int info[4];
__cpuid(info, 0);
@@ -127,6 +131,7 @@ inline bool supportsSSE2()
supports = (info[3] >> 26) & 1;
}
+#endif
checked = true;
@@ -353,7 +358,7 @@ inline float float11ToFloat32(unsigned short fp11)
}
else // The value is zero
{
- exponent = -112;
+ exponent = static_cast<unsigned short>(-112);
}
return bitCast<float>(((exponent + 112) << 23) | (mantissa << 17));
@@ -392,7 +397,7 @@ inline float float10ToFloat32(unsigned short fp11)
}
else // The value is zero
{
- exponent = -112;
+ exponent = static_cast<unsigned short>(-112);
}
return bitCast<float>(((exponent + 112) << 23) | (mantissa << 18));
@@ -402,7 +407,7 @@ inline float float10ToFloat32(unsigned short fp11)
template <typename T>
inline float normalizedToFloat(T input)
{
- META_ASSERT(std::numeric_limits<T>::is_integer);
+ static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
const float inverseMax = 1.0f / std::numeric_limits<T>::max();
return input * inverseMax;
@@ -411,8 +416,8 @@ inline float normalizedToFloat(T input)
template <unsigned int inputBitCount, typename T>
inline float normalizedToFloat(T input)
{
- META_ASSERT(std::numeric_limits<T>::is_integer);
- META_ASSERT(inputBitCount < (sizeof(T) * 8));
+ 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.");
const float inverseMax = 1.0f / ((1 << inputBitCount) - 1);
return input * inverseMax;
@@ -427,14 +432,15 @@ inline T floatToNormalized(float input)
template <unsigned int outputBitCount, typename T>
inline T floatToNormalized(float input)
{
- META_ASSERT(outputBitCount < (sizeof(T) * 8));
+ static_assert(outputBitCount < (sizeof(T) * 8), "T must have more bits than outputBitCount.");
return ((1 << outputBitCount) - 1) * input + 0.5f;
}
template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
inline T getShiftedData(T input)
{
- META_ASSERT(inputBitCount + inputBitStart <= (sizeof(T) * 8));
+ 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;
}
@@ -442,7 +448,8 @@ inline T getShiftedData(T input)
template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
inline T shiftData(T input)
{
- META_ASSERT(inputBitCount + inputBitStart <= (sizeof(T) * 8));
+ 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;
}
@@ -503,6 +510,7 @@ inline unsigned int averageFloat10(unsigned int a, unsigned int b)
namespace rx
{
+// Represents intervals of the type [a, b)
template <typename T>
struct Range
{
@@ -513,6 +521,18 @@ struct Range
T end;
T length() const { return end - start; }
+
+ bool intersects(Range<T> other)
+ {
+ if (start <= other.start)
+ {
+ return other.start < end;
+ }
+ else
+ {
+ return start < other.end;
+ }
+ }
};
typedef Range<int> RangeI;
@@ -533,14 +553,14 @@ inline unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor)
template <class T>
inline bool IsUnsignedAdditionSafe(T lhs, T rhs)
{
- META_ASSERT(!std::numeric_limits<T>::is_signed);
+ static_assert(!std::numeric_limits<T>::is_signed, "T must be unsigned.");
return (rhs <= std::numeric_limits<T>::max() - lhs);
}
template <class T>
inline bool IsUnsignedMultiplicationSafe(T lhs, T rhs)
{
- META_ASSERT(!std::numeric_limits<T>::is_signed);
+ static_assert(!std::numeric_limits<T>::is_signed, "T must be unsigned.");
return (lhs == T(0) || rhs == T(0) || (rhs <= std::numeric_limits<T>::max() / lhs));
}
@@ -550,6 +570,21 @@ inline bool IsIntegerCastSafe(BigIntT bigValue)
return (static_cast<BigIntT>(static_cast<SmallIntT>(bigValue)) == bigValue);
}
+#if defined(_MSC_VER)
+
+#define ANGLE_ROTL(x,y) _rotl(x,y)
+
+#else
+
+inline uint32_t RotL(uint32_t x, int8_t r)
+{
+ return (x << r) | (x >> (32 - r));
+}
+
+#define ANGLE_ROTL(x,y) RotL(x,y)
+
+#endif // namespace rx
+
}
-#endif // LIBGLESV2_MATHUTIL_H_
+#endif // COMMON_MATHUTIL_H_
diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
index 5bf97f9184..3a2aa91bed 100644
--- a/src/3rdparty/angle/src/common/platform.h
+++ b/src/3rdparty/angle/src/common/platform.h
@@ -14,12 +14,12 @@
#elif defined(__APPLE__)
# define ANGLE_PLATFORM_APPLE 1
# define ANGLE_PLATFORM_POSIX 1
-#elif defined(__linux__)
-# define ANGLE_PLATFORM_LINUX 1
-# define ANGLE_PLATFORM_POSIX 1
#elif defined(ANDROID)
# define ANGLE_PLATFORM_ANDROID 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__) || \
@@ -34,9 +34,6 @@
#endif
#ifdef ANGLE_PLATFORM_WINDOWS
-# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
-# define ANGLE_ENABLE_WINDOWS_STORE 1
-# endif
# ifndef STRICT
# define STRICT 1
# endif
@@ -50,24 +47,32 @@
# include <windows.h>
# include <intrin.h>
+# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
+# define ANGLE_ENABLE_WINDOWS_STORE 1
+# endif
+
# if defined(ANGLE_ENABLE_D3D9)
# include <d3d9.h>
-# include <dxgi.h>
-# if !defined(COMPILER_IMPLEMENTATION)
+# if !defined(ANGLE_TRANSLATOR_IMPLEMENTATION)
# include <d3dcompiler.h>
# endif
# endif
# if defined(ANGLE_ENABLE_D3D11)
# include <d3d10_1.h>
-# include <d3d10.h>
# include <d3d11.h>
# include <dxgi.h>
-# if defined(_MSC_VER) && (_MSC_VER >= 1700)
+# if defined(__MINGW32__) && !defined(__d3d11sdklayers_h__)
+# define ANGLE_MINGW32_COMPAT
+# endif
+# if defined(_MSC_VER) && _MSC_VER >= 1800
+# define ANGLE_ENABLE_D3D11_1
+# endif
+# if defined(ANGLE_ENABLE_D3D11_1)
# include <d3d11_1.h>
# include <dxgi1_2.h>
# endif
-# if !defined(COMPILER_IMPLEMENTATION)
+# if !defined(ANGLE_TRANSLATOR_IMPLEMENTATION)
# include <d3dcompiler.h>
# endif
# endif
@@ -75,88 +80,24 @@
# if defined(ANGLE_ENABLE_WINDOWS_STORE)
# include <dxgi1_3.h>
# if defined(_DEBUG)
-# if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
+# if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
# include <DXProgrammableCapture.h>
# endif
# include <dxgidebug.h>
# endif
# endif
-# if defined(__MINGW32__) // Missing defines on MinGW
-typedef enum D3D11_MAP_FLAG
-{
- D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000L
-} D3D11_MAP_FLAG;
-typedef struct D3D11_QUERY_DATA_SO_STATISTICS
-{
- UINT64 NumPrimitivesWritten;
- UINT64 PrimitivesStorageNeeded;
-} D3D11_QUERY_DATA_SO_STATISTICS;
-typedef HRESULT (WINAPI *PFN_D3D11_CREATE_DEVICE)(
- IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL *,
- UINT FeatureLevels, UINT, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **);
-#define D3D11_MESSAGE_CATEGORY UINT
-#define D3D11_MESSAGE_SEVERITY UINT
-#define D3D11_MESSAGE_ID UINT
-struct D3D11_MESSAGE;
-typedef struct D3D11_INFO_QUEUE_FILTER_DESC
-{
- UINT NumCategories;
- D3D11_MESSAGE_CATEGORY *pCategoryList;
- UINT NumSeverities;
- D3D11_MESSAGE_SEVERITY *pSeverityList;
- UINT NumIDs;
- D3D11_MESSAGE_ID *pIDList;
-} D3D11_INFO_QUEUE_FILTER_DESC;
-typedef struct D3D11_INFO_QUEUE_FILTER
-{
- D3D11_INFO_QUEUE_FILTER_DESC AllowList;
- D3D11_INFO_QUEUE_FILTER_DESC DenyList;
-} D3D11_INFO_QUEUE_FILTER;
-static const IID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 };
-MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") ID3D11InfoQueue : public IUnknown
-{
-public:
- virtual HRESULT __stdcall SetMessageCountLimit(UINT64) = 0;
- virtual void __stdcall ClearStoredMessages() = 0;
- virtual HRESULT __stdcall GetMessage(UINT64, D3D11_MESSAGE *, SIZE_T *) = 0;
- virtual UINT64 __stdcall GetNumMessagesAllowedByStorageFilter() = 0;
- virtual UINT64 __stdcall GetNumMessagesDeniedByStorageFilter() = 0;
- virtual UINT64 __stdcall GetNumStoredMessages() = 0;
- virtual UINT64 __stdcall GetNumStoredMessagesAllowedByRetrievalFilter() = 0;
- virtual UINT64 __stdcall GetNumMessagesDiscardedByMessageCountLimit() = 0;
- virtual UINT64 __stdcall GetMessageCountLimit() = 0;
- virtual HRESULT __stdcall AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
- virtual HRESULT __stdcall GetStorageFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
- virtual void __stdcall ClearStorageFilter() = 0;
- virtual HRESULT __stdcall PushEmptyStorageFilter() = 0;
- virtual HRESULT __stdcall PushCopyOfStorageFilter() = 0;
- virtual HRESULT __stdcall PushStorageFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
- virtual void __stdcall PopStorageFilter() = 0;
- virtual UINT __stdcall GetStorageFilterStackSize() = 0;
- virtual HRESULT __stdcall AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
- virtual HRESULT __stdcall GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
- virtual void __stdcall ClearRetrievalFilter() = 0;
- virtual HRESULT __stdcall PushEmptyRetrievalFilter() = 0;
- virtual HRESULT __stdcall PushCopyOfRetrievalFilter() = 0;
- virtual HRESULT __stdcall PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
- virtual void __stdcall PopRetrievalFilter() = 0;
- virtual UINT __stdcall GetRetrievalFilterStackSize() = 0;
- virtual HRESULT __stdcall AddMessage(D3D11_MESSAGE_CATEGORY, D3D11_MESSAGE_SEVERITY, D3D11_MESSAGE_ID, LPCSTR) = 0;
- virtual HRESULT __stdcall AddApplicationMessage(D3D11_MESSAGE_SEVERITY, LPCSTR) = 0;
- virtual HRESULT __stdcall SetBreakOnCategory(D3D11_MESSAGE_CATEGORY, BOOL) = 0;
- virtual HRESULT __stdcall SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY, BOOL) = 0;
- virtual HRESULT __stdcall SetBreakOnID(D3D11_MESSAGE_ID, BOOL) = 0;
- virtual BOOL __stdcall GetBreakOnCategory(D3D11_MESSAGE_CATEGORY) = 0;
- virtual BOOL __stdcall GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY) = 0;
- virtual BOOL __stdcall GetBreakOnID(D3D11_MESSAGE_ID) = 0;
- virtual void __stdcall SetMuteDebugOutput(BOOL) = 0;
- virtual BOOL __stdcall GetMuteDebugOutput() = 0;
-};
-#endif // __MINGW32__
+# if defined(_MSC_VER) && (_MSC_VER <= 1600)
+# define final
+# define override
+# endif
# undef near
# undef far
#endif
+#if !defined(_M_ARM) && !defined(ANGLE_PLATFORM_ANDROID)
+# define ANGLE_USE_SSE
+#endif
+
#endif // COMMON_PLATFORM_H_
diff --git a/src/3rdparty/angle/src/common/tls.h b/src/3rdparty/angle/src/common/tls.h
index 8a06e92d1a..ca9e07ab70 100644
--- a/src/3rdparty/angle/src/common/tls.h
+++ b/src/3rdparty/angle/src/common/tls.h
@@ -15,7 +15,9 @@
// TLS does not exist for Windows Store and needs to be emulated
# ifdef ANGLE_ENABLE_WINDOWS_STORE
-# define TLS_OUT_OF_INDEXES -1
+# ifndef TLS_OUT_OF_INDEXES
+# define TLS_OUT_OF_INDEXES static_cast<DWORD>(0xFFFFFFFF)
+# endif
# ifndef CREATE_SUSPENDED
# define CREATE_SUSPENDED 0x00000004
# endif
diff --git a/src/3rdparty/angle/src/common/utilities.cpp b/src/3rdparty/angle/src/common/utilities.cpp
index 0eae42cac2..501e9c2564 100644
--- a/src/3rdparty/angle/src/common/utilities.cpp
+++ b/src/3rdparty/angle/src/common/utilities.cpp
@@ -254,7 +254,7 @@ int VariableColumnCount(GLenum type)
return 0;
}
-bool IsSampler(GLenum type)
+bool IsSamplerType(GLenum type)
{
switch (type)
{
@@ -343,9 +343,27 @@ int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsig
return -1;
}
-bool IsCubemapTextureTarget(GLenum target)
+static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1, "Unexpected GL cube map enum value.");
+static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2, "Unexpected GL cube map enum value.");
+static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3, "Unexpected GL cube map enum value.");
+static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4, "Unexpected GL cube map enum value.");
+static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5, "Unexpected GL cube map enum value.");
+
+bool IsCubeMapTextureTarget(GLenum target)
+{
+ return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
+}
+
+size_t CubeMapTextureTargetToLayerIndex(GLenum target)
{
- return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
+ ASSERT(IsCubeMapTextureTarget(target));
+ return target - static_cast<size_t>(FirstCubeMapTextureTarget);
+}
+
+GLenum LayerIndexToCubeMapTextureTarget(size_t index)
+{
+ ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
+ return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
}
bool IsTriangleMode(GLenum drawMode)
@@ -486,10 +504,15 @@ void writeFile(const char* path, const void* content, size_t size)
}
#endif // !ANGLE_ENABLE_WINDOWS_STORE
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && _MSC_FULL_VER < 180031101
+#if defined (ANGLE_PLATFORM_WINDOWS)
-void Sleep(unsigned long dwMilliseconds)
+// 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()
{
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+ // This implementation of Sleep exists because it is not available prior to Update 4.
static HANDLE singletonEvent = nullptr;
HANDLE sleepEvent = singletonEvent;
if (!sleepEvent)
@@ -510,7 +533,10 @@ void Sleep(unsigned long dwMilliseconds)
}
// Emulate sleep by waiting with timeout on an event that is never signalled.
- WaitForSingleObjectEx(sleepEvent, dwMilliseconds, false);
+ WaitForSingleObjectEx(sleepEvent, 0, false);
+#else
+ Sleep(0);
+#endif
}
-#endif // ANGLE_ENABLE_WINDOWS_STORE
+#endif
diff --git a/src/3rdparty/angle/src/common/utilities.h b/src/3rdparty/angle/src/common/utilities.h
index 7583d3e160..9f7f5e03c0 100644
--- a/src/3rdparty/angle/src/common/utilities.h
+++ b/src/3rdparty/angle/src/common/utilities.h
@@ -6,8 +6,8 @@
// utilities.h: Conversion functions and other utility routines.
-#ifndef LIBGLESV2_UTILITIES_H
-#define LIBGLESV2_UTILITIES_H
+#ifndef COMMON_UTILITIES_H_
+#define COMMON_UTILITIES_H_
#include "angle_gl.h"
#include <string>
@@ -24,7 +24,7 @@ size_t VariableExternalSize(GLenum type);
GLenum VariableBoolVectorType(GLenum type);
int VariableRowCount(GLenum type);
int VariableColumnCount(GLenum type);
-bool IsSampler(GLenum type);
+bool IsSamplerType(GLenum type);
bool IsMatrixType(GLenum type);
GLenum TransposeMatrixType(GLenum type);
int VariableRegisterCount(GLenum type);
@@ -34,7 +34,11 @@ int VariableSortOrder(GLenum type);
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
-bool IsCubemapTextureTarget(GLenum target);
+static const GLenum FirstCubeMapTextureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+static const GLenum LastCubeMapTextureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+bool IsCubeMapTextureTarget(GLenum target);
+size_t CubeMapTextureTargetToLayerIndex(GLenum target);
+GLenum LayerIndexToCubeMapTextureTarget(size_t index);
bool IsTriangleMode(GLenum drawMode);
@@ -51,8 +55,8 @@ std::string getTempPath();
void writeFile(const char* path, const void* data, size_t size);
#endif
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && _MSC_FULL_VER < 180031101
-void Sleep(_In_ unsigned long dwMilliseconds);
+#if defined (ANGLE_PLATFORM_WINDOWS)
+void ScheduleYield();
#endif
-#endif // LIBGLESV2_UTILITIES_H
+#endif // COMMON_UTILITIES_H_
diff --git a/src/3rdparty/angle/src/common/version.h b/src/3rdparty/angle/src/common/version.h
index f01e0242cb..758c78d44a 100644
--- a/src/3rdparty/angle/src/common/version.h
+++ b/src/3rdparty/angle/src/common/version.h
@@ -1,4 +1,13 @@
-#include "../commit.h"
+//
+// Copyright (c) 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_VERSION_H_
+#define COMMON_VERSION_H_
+
+#include "id/commit.h"
#define ANGLE_MAJOR_VERSION 2
#define ANGLE_MINOR_VERSION 1
@@ -10,3 +19,5 @@
ANGLE_MACRO_STRINGIFY(ANGLE_MAJOR_VERSION) "." \
ANGLE_MACRO_STRINGIFY(ANGLE_MINOR_VERSION) "." \
ANGLE_COMMIT_HASH
+
+#endif // COMMON_VERSION_H_
diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
deleted file mode 100644
index 1c5512417d..0000000000
--- a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// Copyright (c) 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.
-//
-
-// CoreWindowNativeWindow.h: NativeWindow for managing ICoreWindow native window types.
-
-#ifndef COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
-#define COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
-
-#include "common/winrt/InspectableNativeWindow.h"
-#include <memory>
-#include <windows.graphics.display.h>
-
-namespace rx
-{
-
-class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
-{
- public:
- ~CoreWindowNativeWindow();
-
- bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
- bool registerForSizeChangeEvents();
- void unregisterForSizeChangeEvents();
- HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
-
- private:
- HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
-
- ComPtr<ABI::Windows::UI::Core::ICoreWindow> mCoreWindow;
- ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation> mDisplayInformation;
- ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
-};
-
-}
-
-#endif // COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h
index a7587ed657..5922d03857 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
-#define COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
+#ifndef COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
+#define COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
#include <string>
@@ -84,4 +84,5 @@ class Diagnostics
};
} // namespace pp
-#endif // COMPILER_PREPROCESSOR_DIAGNOSTICS_H_
+
+#endif // COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
index eec0d5e5f0..cf67895764 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
-#define COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
+#ifndef COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
+#define COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
#include <string>
@@ -41,4 +41,5 @@ class DirectiveHandler
};
} // namespace pp
-#endif // COMPILER_PREPROCESSOR_DIRECTIVE_HANDLER_H_
+
+#endif // COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h
index 335091781c..e1acdbb8d0 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_
-#define COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_
+#ifndef COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
+#define COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
#include "Lexer.h"
#include "Macro.h"
@@ -78,5 +78,5 @@ class DirectiveParser : public Lexer
};
} // namespace pp
-#endif // COMPILER_PREPROCESSOR_DIRECTIVE_PARSER_H_
+#endif // COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h
index f040cb01fa..4b80ba7261 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_
-#define COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_
+#ifndef COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
+#define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
#include "pp_utils.h"
@@ -31,4 +31,5 @@ class ExpressionParser
};
} // namespace pp
-#endif // COMPILER_PREPROCESSOR_EXPRESSION_PARSER_H_
+
+#endif // COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y
index 662a31b650..8caf36bfc8 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y
+++ b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y
@@ -28,7 +28,7 @@ WHICH GENERATES THE GLSL ES preprocessor expression parser.
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
#elif defined(_MSC_VER)
-#pragma warning(disable: 4065 4701)
+#pragma warning(disable: 4065 4701 4702)
#endif
#include "ExpressionParser.h"
@@ -69,7 +69,7 @@ struct Context
%}
%pure-parser
-%name-prefix="pp"
+%name-prefix "pp"
%parse-param {Context *context}
%lex-param {Context *context}
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Input.h b/src/3rdparty/angle/src/compiler/preprocessor/Input.h
index 2ac4f0c170..e951cb4d5f 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/Input.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Input.h
@@ -58,5 +58,5 @@ class Input
};
} // namespace pp
-#endif // COMPILER_PREPROCESSOR_INPUT_H_
+#endif // COMPILER_PREPROCESSOR_INPUT_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h
index d42d3db7e0..990dc5e21d 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h
@@ -21,5 +21,5 @@ class Lexer
};
} // namespace pp
-#endif // COMPILER_PREPROCESSOR_LEXER_H_
+#endif // COMPILER_PREPROCESSOR_LEXER_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Macro.h b/src/3rdparty/angle/src/compiler/preprocessor/Macro.h
index b77e7bc15c..7662a9c5a2 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/Macro.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Macro.h
@@ -46,4 +46,5 @@ struct Macro
typedef std::map<std::string, Macro> MacroSet;
} // namespace pp
+
#endif // COMPILER_PREPROCESSOR_MACRO_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h
index d4fd091786..5a0c7751a8 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
-#define COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
+#ifndef COMPILER_PREPROCESSOR_MACROEXPANDER_H_
+#define COMPILER_PREPROCESSOR_MACROEXPANDER_H_
#include <cassert>
#include <memory>
@@ -85,5 +85,5 @@ class MacroExpander : public Lexer
};
} // namespace pp
-#endif // COMPILER_PREPROCESSOR_MACRO_EXPANDER_H_
+#endif // COMPILER_PREPROCESSOR_MACROEXPANDER_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h
index 0a55f1c9c1..fe25daa123 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h
@@ -50,5 +50,5 @@ class Preprocessor
};
} // namespace pp
-#endif // COMPILER_PREPROCESSOR_PREPROCESSOR_H_
+#endif // COMPILER_PREPROCESSOR_PREPROCESSOR_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h b/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h
index d4c1a5e178..af8a8d5d19 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_
-#define COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_
+#ifndef COMPILER_PREPROCESSOR_SOURCELOCATION_H_
+#define COMPILER_PREPROCESSOR_SOURCELOCATION_H_
namespace pp
{
@@ -43,4 +43,5 @@ inline bool operator!=(const SourceLocation &lhs, const SourceLocation &rhs)
}
} // namespace pp
-#endif // COMPILER_PREPROCESSOR_SOURCE_LOCATION_H_
+
+#endif // COMPILER_PREPROCESSOR_SOURCELOCATION_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Token.h b/src/3rdparty/angle/src/compiler/preprocessor/Token.h
index 8832e279c7..347c47e307 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/Token.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Token.h
@@ -116,4 +116,5 @@ inline bool operator!=(const Token &lhs, const Token &rhs)
extern std::ostream &operator<<(std::ostream &out, const Token &token);
} // namepsace pp
+
#endif // COMPILER_PREPROCESSOR_TOKEN_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h
index 07ad93da05..78eb86dd3b 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h
@@ -55,5 +55,5 @@ class Tokenizer : public Lexer
};
} // namespace pp
-#endif // COMPILER_PREPROCESSOR_TOKENIZER_H_
+#endif // COMPILER_PREPROCESSOR_TOKENIZER_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l
index 2a77b905a4..89cb5c8596 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l
@@ -267,7 +267,9 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
namespace pp {
-Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(0)
+Tokenizer::Tokenizer(Diagnostics *diagnostics)
+ : mHandle(0),
+ mMaxTokenSize(256)
{
mContext.diagnostics = diagnostics;
}
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h b/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h
index 8a24540696..58c51b0961 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h
@@ -6,8 +6,8 @@
// numeric_lex.h: Functions to extract numeric values from string.
-#ifndef COMPILER_PREPROCESSOR_NUMERIC_LEX_H_
-#define COMPILER_PREPROCESSOR_NUMERIC_LEX_H_
+#ifndef COMPILER_PREPROCESSOR_NUMERICLEX_H_
+#define COMPILER_PREPROCESSOR_NUMERICLEX_H_
#include <sstream>
@@ -58,4 +58,5 @@ bool numeric_lex_float(const std::string &str, FloatType *value)
}
} // namespace pp.
-#endif // COMPILER_PREPROCESSOR_NUMERIC_LEX_H_
+
+#endif // COMPILER_PREPROCESSOR_NUMERICLEX_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/BaseTypes.h b/src/3rdparty/angle/src/compiler/translator/BaseTypes.h
index 324b0669f4..ee1428b2d3 100644
--- a/src/3rdparty/angle/src/compiler/translator/BaseTypes.h
+++ b/src/3rdparty/angle/src/compiler/translator/BaseTypes.h
@@ -4,10 +4,10 @@
// found in the LICENSE file.
//
-#ifndef _BASICTYPES_INCLUDED_
-#define _BASICTYPES_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_BASETYPES_H_
+#define COMPILER_TRANSLATOR_BASETYPES_H_
-#include <assert.h>
+#include "compiler/translator/compilerdebug.h"
//
// Precision qualifiers
@@ -42,7 +42,15 @@ enum TBasicType
EbtInt,
EbtUInt,
EbtBool,
- EbtGVec4, // non type: represents vec4, ivec4 and uvec4
+ EbtGVec4, // non type: represents vec4, ivec4, and uvec4
+ EbtGenType, // non type: represents float, vec2, vec3, and vec4
+ EbtGenIType, // non type: represents int, ivec2, ivec3, and ivec4
+ EbtGenUType, // non type: represents uint, uvec2, uvec3, and uvec4
+ EbtGenBType, // non type: represents bool, bvec2, bvec3, and bvec4
+ EbtVec, // non type: represents vec2, vec3, and vec4
+ EbtIVec, // non type: represents ivec2, ivec3, and ivec4
+ EbtUVec, // non type: represents uvec2, uvec3, and uvec4
+ EbtBVec, // non type: represents bvec2, bvec3, and bvec4
EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
EbtSampler2D,
EbtSampler3D,
@@ -62,10 +70,10 @@ enum TBasicType
EbtSamplerCubeShadow,
EbtSampler2DArrayShadow,
EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
- EbtGSampler2D, // non type: represents sampler2D, isampler2D and usampler2D
- EbtGSampler3D, // non type: represents sampler3D, isampler3D and usampler3D
- EbtGSamplerCube, // non type: represents samplerCube, isamplerCube and usamplerCube
- EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray and usampler2DArray
+ EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D
+ EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D
+ EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube
+ EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray
EbtStruct,
EbtInterfaceBlock,
EbtAddress, // should be deprecated??
@@ -258,6 +266,11 @@ inline bool IsShadowSampler(TBasicType type)
return false;
}
+inline bool IsInteger(TBasicType type)
+{
+ return type == EbtInt || type == EbtUInt;
+}
+
inline bool SupportsPrecision(TBasicType type)
{
return type == EbtFloat || type == EbtInt || type == EbtUInt || IsSampler(type);
@@ -293,6 +306,9 @@ enum TQualifier
EvqInOut,
EvqConstReadOnly,
+ // built-ins read by vertex shader
+ EvqInstanceID,
+
// built-ins written by vertex shader
EvqPosition,
EvqPointSize,
@@ -307,6 +323,10 @@ enum TQualifier
EvqFragData,
EvqFragDepth,
+ // 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
@@ -383,6 +403,7 @@ inline const char* getQualifierString(TQualifier q)
case EvqIn: return "in"; break;
case EvqOut: return "out"; break;
case EvqInOut: return "inout"; break;
+ case EvqInstanceID: return "InstanceID"; break;
case EvqPosition: return "Position"; break;
case EvqPointSize: return "PointSize"; break;
case EvqFragCoord: return "FragCoord"; break;
@@ -396,7 +417,9 @@ inline const char* getQualifierString(TQualifier q)
case EvqSmoothIn: return "smooth in"; break;
case EvqCentroidIn: return "centroid in"; break;
case EvqFlatIn: return "flat in"; break;
- default: return "unknown qualifier";
+ case EvqLastFragColor: return "LastFragColor"; break;
+ case EvqLastFragData: return "LastFragData"; break;
+ default: UNREACHABLE(); return "unknown qualifier";
}
}
@@ -407,7 +430,7 @@ inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq)
case EmpUnspecified: return "mp_unspecified";
case EmpRowMajor: return "row_major";
case EmpColumnMajor: return "column_major";
- default: return "unknown matrix packing";
+ default: UNREACHABLE(); return "unknown matrix packing";
}
}
@@ -419,7 +442,7 @@ inline const char* getBlockStorageString(TLayoutBlockStorage bsq)
case EbsShared: return "shared";
case EbsPacked: return "packed";
case EbsStd140: return "std140";
- default: return "unknown block storage";
+ default: UNREACHABLE(); return "unknown block storage";
}
}
@@ -433,8 +456,8 @@ inline const char* getInterpolationString(TQualifier q)
case EvqSmoothIn: return "smooth"; break;
case EvqCentroidIn: return "centroid"; break;
case EvqFlatIn: return "flat"; break;
- default: return "unknown interpolation";
+ default: UNREACHABLE(); return "unknown interpolation";
}
}
-#endif // _BASICTYPES_INCLUDED_
+#endif // COMPILER_TRANSLATOR_BASETYPES_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
index 0e8239cc1e..51461207c5 100644
--- a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
@@ -8,193 +8,9 @@
#include "compiler/translator/BuiltInFunctionEmulator.h"
#include "compiler/translator/SymbolTable.h"
-namespace {
-
-// we use macros here instead of function definitions to work around more GLSL
-// compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are
-// problematic because if the argument has side-effects they will be repeatedly
-// evaluated. This is unlikely to show up in real shaders, but is something to
-// consider.
-const char* kFunctionEmulationVertexSource[] = {
- "#error no emulation for cos(float)",
- "#error no emulation for cos(vec2)",
- "#error no emulation for cos(vec3)",
- "#error no emulation for cos(vec4)",
-
- "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))",
- "#error no emulation for distance(vec2, vec2)",
- "#error no emulation for distance(vec3, vec3)",
- "#error no emulation for distance(vec4, vec4)",
-
- "#define webgl_dot_emu(x, y) ((x) * (y))",
- "#error no emulation for dot(vec2, vec2)",
- "#error no emulation for dot(vec3, vec3)",
- "#error no emulation for dot(vec4, vec4)",
-
- "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
- "#error no emulation for length(vec2)",
- "#error no emulation for length(vec3)",
- "#error no emulation for length(vec4)",
-
- "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))",
- "#error no emulation for normalize(vec2)",
- "#error no emulation for normalize(vec3)",
- "#error no emulation for normalize(vec4)",
-
- "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))",
- "#error no emulation for reflect(vec2, vec2)",
- "#error no emulation for reflect(vec3, vec3)",
- "#error no emulation for reflect(vec4, vec4)"
-};
-
-const char* kFunctionEmulationFragmentSource[] = {
- "webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }",
- "webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }",
- "webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }",
- "webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }",
-
- "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))",
- "#error no emulation for distance(vec2, vec2)",
- "#error no emulation for distance(vec3, vec3)",
- "#error no emulation for distance(vec4, vec4)",
-
- "#define webgl_dot_emu(x, y) ((x) * (y))",
- "#error no emulation for dot(vec2, vec2)",
- "#error no emulation for dot(vec3, vec3)",
- "#error no emulation for dot(vec4, vec4)",
-
- "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))",
- "#error no emulation for length(vec2)",
- "#error no emulation for length(vec3)",
- "#error no emulation for length(vec4)",
-
- "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))",
- "#error no emulation for normalize(vec2)",
- "#error no emulation for normalize(vec3)",
- "#error no emulation for normalize(vec4)",
-
- "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))",
- "#error no emulation for reflect(vec2, vec2)",
- "#error no emulation for reflect(vec3, vec3)",
- "#error no emulation for reflect(vec4, vec4)"
-};
-
-const bool kFunctionEmulationVertexMask[] = {
-#if defined(__APPLE__)
- // Work around ATI driver bugs in Mac.
- false, // TFunctionCos1
- false, // TFunctionCos2
- false, // TFunctionCos3
- false, // TFunctionCos4
- true, // TFunctionDistance1_1
- false, // TFunctionDistance2_2
- false, // TFunctionDistance3_3
- false, // TFunctionDistance4_4
- true, // TFunctionDot1_1
- false, // TFunctionDot2_2
- false, // TFunctionDot3_3
- false, // TFunctionDot4_4
- true, // TFunctionLength1
- false, // TFunctionLength2
- false, // TFunctionLength3
- false, // TFunctionLength4
- true, // TFunctionNormalize1
- false, // TFunctionNormalize2
- false, // TFunctionNormalize3
- false, // TFunctionNormalize4
- true, // TFunctionReflect1_1
- false, // TFunctionReflect2_2
- false, // TFunctionReflect3_3
- false, // TFunctionReflect4_4
-#else
- // Work around D3D driver bug in Win.
- false, // TFunctionCos1
- false, // TFunctionCos2
- false, // TFunctionCos3
- false, // TFunctionCos4
- false, // TFunctionDistance1_1
- false, // TFunctionDistance2_2
- false, // TFunctionDistance3_3
- false, // TFunctionDistance4_4
- false, // TFunctionDot1_1
- false, // TFunctionDot2_2
- false, // TFunctionDot3_3
- false, // TFunctionDot4_4
- false, // TFunctionLength1
- false, // TFunctionLength2
- false, // TFunctionLength3
- false, // TFunctionLength4
- false, // TFunctionNormalize1
- false, // TFunctionNormalize2
- false, // TFunctionNormalize3
- false, // TFunctionNormalize4
- false, // TFunctionReflect1_1
- false, // TFunctionReflect2_2
- false, // TFunctionReflect3_3
- false, // TFunctionReflect4_4
-#endif
- false // TFunctionUnknown
-};
-
-const bool kFunctionEmulationFragmentMask[] = {
-#if defined(__APPLE__)
- // Work around ATI driver bugs in Mac.
- true, // TFunctionCos1
- true, // TFunctionCos2
- true, // TFunctionCos3
- true, // TFunctionCos4
- true, // TFunctionDistance1_1
- false, // TFunctionDistance2_2
- false, // TFunctionDistance3_3
- false, // TFunctionDistance4_4
- true, // TFunctionDot1_1
- false, // TFunctionDot2_2
- false, // TFunctionDot3_3
- false, // TFunctionDot4_4
- true, // TFunctionLength1
- false, // TFunctionLength2
- false, // TFunctionLength3
- false, // TFunctionLength4
- true, // TFunctionNormalize1
- false, // TFunctionNormalize2
- false, // TFunctionNormalize3
- false, // TFunctionNormalize4
- true, // TFunctionReflect1_1
- false, // TFunctionReflect2_2
- false, // TFunctionReflect3_3
- false, // TFunctionReflect4_4
-#else
- // Work around D3D driver bug in Win.
- false, // TFunctionCos1
- false, // TFunctionCos2
- false, // TFunctionCos3
- false, // TFunctionCos4
- false, // TFunctionDistance1_1
- false, // TFunctionDistance2_2
- false, // TFunctionDistance3_3
- false, // TFunctionDistance4_4
- false, // TFunctionDot1_1
- false, // TFunctionDot2_2
- false, // TFunctionDot3_3
- false, // TFunctionDot4_4
- false, // TFunctionLength1
- false, // TFunctionLength2
- false, // TFunctionLength3
- false, // TFunctionLength4
- false, // TFunctionNormalize1
- false, // TFunctionNormalize2
- false, // TFunctionNormalize3
- false, // TFunctionNormalize4
- false, // TFunctionReflect1_1
- false, // TFunctionReflect2_2
- false, // TFunctionReflect3_3
- false, // TFunctionReflect4_4
-#endif
- false // TFunctionUnknown
-};
-
-class BuiltInFunctionEmulationMarker : public TIntermTraverser {
-public:
+class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
+{
+ public:
BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator& emulator)
: mEmulator(emulator)
{
@@ -238,148 +54,119 @@ public:
case EOpFaceForward:
case EOpReflect:
case EOpRefract:
+ case EOpOuterProduct:
case EOpMul:
break;
default:
return true;
};
const TIntermSequence& sequence = *(node->getSequence());
- // Right now we only handle built-in functions with two parameters.
- if (sequence.size() != 2)
- return true;
- TIntermTyped* param1 = sequence[0]->getAsTyped();
- TIntermTyped* param2 = sequence[1]->getAsTyped();
- if (!param1 || !param2)
+ bool needToEmulate = false;
+ // Right now we only handle built-in functions with two or three parameters.
+ if (sequence.size() == 2)
+ {
+ TIntermTyped* param1 = sequence[0]->getAsTyped();
+ TIntermTyped* param2 = sequence[1]->getAsTyped();
+ if (!param1 || !param2)
+ return true;
+ needToEmulate = mEmulator.SetFunctionCalled(
+ node->getOp(), param1->getType(), param2->getType());
+ }
+ else if (sequence.size() == 3)
+ {
+ TIntermTyped* param1 = sequence[0]->getAsTyped();
+ TIntermTyped* param2 = sequence[1]->getAsTyped();
+ TIntermTyped* param3 = sequence[2]->getAsTyped();
+ if (!param1 || !param2 || !param3)
+ return true;
+ needToEmulate = mEmulator.SetFunctionCalled(
+ node->getOp(), param1->getType(), param2->getType(), param3->getType());
+ }
+ else
+ {
return true;
- bool needToEmulate = mEmulator.SetFunctionCalled(
- node->getOp(), param1->getType(), param2->getType());
+ }
+
if (needToEmulate)
node->setUseEmulatedFunction();
}
return true;
}
-private:
+ private:
BuiltInFunctionEmulator& mEmulator;
};
-} // anonymous namepsace
+BuiltInFunctionEmulator::BuiltInFunctionEmulator()
+{}
-BuiltInFunctionEmulator::BuiltInFunctionEmulator(sh::GLenum shaderType)
+void BuiltInFunctionEmulator::addEmulatedFunction(
+ TOperator op, const TType& param,
+ const char* emulatedFunctionDefinition)
{
- if (shaderType == GL_FRAGMENT_SHADER) {
- mFunctionMask = kFunctionEmulationFragmentMask;
- mFunctionSource = kFunctionEmulationFragmentSource;
- } else {
- mFunctionMask = kFunctionEmulationVertexMask;
- mFunctionSource = kFunctionEmulationVertexSource;
- }
+ mEmulatedFunctions[FunctionId(op, param)] =
+ std::string(emulatedFunctionDefinition);
}
-bool BuiltInFunctionEmulator::SetFunctionCalled(
- TOperator op, const TType& param)
+void BuiltInFunctionEmulator::addEmulatedFunction(
+ TOperator op, const TType& param1, const TType& param2,
+ const char* emulatedFunctionDefinition)
{
- TBuiltInFunction function = IdentifyFunction(op, param);
- return SetFunctionCalled(function);
+ mEmulatedFunctions[FunctionId(op, param1, param2)] =
+ std::string(emulatedFunctionDefinition);
}
-bool BuiltInFunctionEmulator::SetFunctionCalled(
- TOperator op, const TType& param1, const TType& param2)
+void BuiltInFunctionEmulator::addEmulatedFunction(
+ TOperator op, const TType& param1, const TType& param2, const TType& param3,
+ const char* emulatedFunctionDefinition)
{
- TBuiltInFunction function = IdentifyFunction(op, param1, param2);
- return SetFunctionCalled(function);
+ mEmulatedFunctions[FunctionId(op, param1, param2, param3)] =
+ std::string(emulatedFunctionDefinition);
}
-bool BuiltInFunctionEmulator::SetFunctionCalled(
- BuiltInFunctionEmulator::TBuiltInFunction function) {
- if (function == TFunctionUnknown || mFunctionMask[function] == false)
- return false;
- for (size_t i = 0; i < mFunctions.size(); ++i) {
- if (mFunctions[i] == function)
- return true;
- }
- mFunctions.push_back(function);
- return true;
+bool BuiltInFunctionEmulator::IsOutputEmpty() const
+{
+ return (mFunctions.size() == 0);
}
-void BuiltInFunctionEmulator::OutputEmulatedFunctionDefinition(
- TInfoSinkBase& out, bool withPrecision) const
+void BuiltInFunctionEmulator::OutputEmulatedFunctions(
+ TInfoSinkBase& out) const
{
- if (mFunctions.size() == 0)
- return;
- out << "// BEGIN: Generated code for built-in function emulation\n\n";
- if (withPrecision) {
- out << "#if defined(GL_FRAGMENT_PRECISION_HIGH)\n"
- << "#define webgl_emu_precision highp\n"
- << "#else\n"
- << "#define webgl_emu_precision mediump\n"
- << "#endif\n\n";
- } else {
- out << "#define webgl_emu_precision\n\n";
- }
for (size_t i = 0; i < mFunctions.size(); ++i) {
- out << mFunctionSource[mFunctions[i]] << "\n\n";
+ out << mEmulatedFunctions.find(mFunctions[i])->second << "\n\n";
}
- out << "// END: Generated code for built-in function emulation\n\n";
}
-BuiltInFunctionEmulator::TBuiltInFunction
-BuiltInFunctionEmulator::IdentifyFunction(
+bool BuiltInFunctionEmulator::SetFunctionCalled(
TOperator op, const TType& param)
{
- if (param.getNominalSize() > 4 || param.getSecondarySize() > 4)
- return TFunctionUnknown;
- unsigned int function = TFunctionUnknown;
- switch (op) {
- case EOpCos:
- function = TFunctionCos1;
- break;
- case EOpLength:
- function = TFunctionLength1;
- break;
- case EOpNormalize:
- function = TFunctionNormalize1;
- break;
- default:
- break;
- }
- if (function == TFunctionUnknown)
- return TFunctionUnknown;
- if (param.isVector())
- function += param.getNominalSize() - 1;
- return static_cast<TBuiltInFunction>(function);
+ return SetFunctionCalled(FunctionId(op, param));
}
-BuiltInFunctionEmulator::TBuiltInFunction
-BuiltInFunctionEmulator::IdentifyFunction(
+bool BuiltInFunctionEmulator::SetFunctionCalled(
TOperator op, const TType& param1, const TType& param2)
{
- // Right now for all the emulated functions with two parameters, the two
- // parameters have the same type.
- if (param1.getNominalSize() != param2.getNominalSize() ||
- param1.getSecondarySize() != param2.getSecondarySize() ||
- param1.getNominalSize() > 4 || param1.getSecondarySize() > 4)
- return TFunctionUnknown;
+ return SetFunctionCalled(FunctionId(op, param1, param2));
+}
+
+bool BuiltInFunctionEmulator::SetFunctionCalled(
+ TOperator op, const TType& param1, const TType& param2, const TType& param3)
+{
+ return SetFunctionCalled(FunctionId(op, param1, param2, param3));
+}
- unsigned int function = TFunctionUnknown;
- switch (op) {
- case EOpDistance:
- function = TFunctionDistance1_1;
- break;
- case EOpDot:
- function = TFunctionDot1_1;
- break;
- case EOpReflect:
- function = TFunctionReflect1_1;
- break;
- default:
- break;
+bool BuiltInFunctionEmulator::SetFunctionCalled(
+ const FunctionId& functionId) {
+ if (mEmulatedFunctions.find(functionId) != mEmulatedFunctions.end())
+ {
+ for (size_t i = 0; i < mFunctions.size(); ++i) {
+ if (mFunctions[i] == functionId)
+ return true;
+ }
+ mFunctions.push_back(functionId);
+ return true;
}
- if (function == TFunctionUnknown)
- return TFunctionUnknown;
- if (param1.isVector())
- function += param1.getNominalSize() - 1;
- return static_cast<TBuiltInFunction>(function);
+ return false;
}
void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
@@ -387,6 +174,9 @@ void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
{
ASSERT(root);
+ if (mEmulatedFunctions.empty())
+ return;
+
BuiltInFunctionEmulationMarker marker(*this);
root->traverse(&marker);
}
@@ -404,3 +194,52 @@ TString BuiltInFunctionEmulator::GetEmulatedFunctionName(
return "webgl_" + name.substr(0, name.length() - 1) + "_emu(";
}
+BuiltInFunctionEmulator::FunctionId::FunctionId
+ (TOperator op, const TType& param)
+ : mOp(op),
+ mParam1(param),
+ mParam2(EbtVoid),
+ mParam3(EbtVoid)
+{
+}
+
+BuiltInFunctionEmulator::FunctionId::FunctionId
+ (TOperator op, const TType& param1, const TType& param2)
+ : mOp(op),
+ mParam1(param1),
+ mParam2(param2),
+ mParam3(EbtVoid)
+{
+}
+
+BuiltInFunctionEmulator::FunctionId::FunctionId
+ (TOperator op, const TType& param1, const TType& param2, const TType& param3)
+ : mOp(op),
+ mParam1(param1),
+ mParam2(param2),
+ mParam3(param3)
+{
+}
+
+bool BuiltInFunctionEmulator::FunctionId::operator==
+ (const BuiltInFunctionEmulator::FunctionId& other) const
+{
+ return (mOp == other.mOp &&
+ mParam1 == other.mParam1 &&
+ mParam2 == other.mParam2 &&
+ mParam3 == other.mParam3);
+}
+
+bool BuiltInFunctionEmulator::FunctionId::operator<
+ (const BuiltInFunctionEmulator::FunctionId& other) const
+{
+ if (mOp != other.mOp)
+ return mOp < other.mOp;
+ if (mParam1 != other.mParam1)
+ return mParam1 < other.mParam1;
+ if (mParam2 != other.mParam2)
+ return mParam2 < other.mParam2;
+ if (mParam3 != other.mParam3)
+ return mParam3 < other.mParam3;
+ return false; // all fields are equal
+}
diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.h b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.h
index c6bf77c386..df556985e1 100644
--- a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.h
+++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
-#define COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
+#ifndef COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
+#define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
@@ -13,23 +13,13 @@
//
// This class decides which built-in functions need to be replaced with the
// emulated ones.
-// It's only a workaround for OpenGL driver bugs, and isn't needed in general.
+// 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(sh::GLenum shaderType);
- // Records that a function is called by the shader and might needs to be
- // emulated. If the function's group is not in mFunctionGroupFilter, this
- // becomes an no-op.
- // Returns true if the function call needs to be replaced with an emulated
- // one.
- bool SetFunctionCalled(TOperator op, const TType& param);
- bool SetFunctionCalled(
- TOperator op, const TType& param1, const TType& param2);
-
- // Output function emulation definition. This should be before any other
- // shader source.
- void OutputEmulatedFunctionDefinition(TInfoSinkBase& out, bool withPrecision) const;
+class BuiltInFunctionEmulator
+{
+ public:
+ BuiltInFunctionEmulator();
void MarkBuiltInFunctionsForEmulation(TIntermNode* root);
@@ -38,54 +28,52 @@ public:
// "name(" becomes "webgl_name_emu(".
static TString GetEmulatedFunctionName(const TString& name);
-private:
- //
- // Built-in functions.
- //
- enum TBuiltInFunction {
- TFunctionCos1 = 0, // float cos(float);
- TFunctionCos2, // vec2 cos(vec2);
- TFunctionCos3, // vec3 cos(vec3);
- TFunctionCos4, // vec4 cos(vec4);
-
- TFunctionDistance1_1, // float distance(float, float);
- TFunctionDistance2_2, // vec2 distance(vec2, vec2);
- TFunctionDistance3_3, // vec3 distance(vec3, vec3);
- TFunctionDistance4_4, // vec4 distance(vec4, vec4);
-
- TFunctionDot1_1, // float dot(float, float);
- TFunctionDot2_2, // vec2 dot(vec2, vec2);
- TFunctionDot3_3, // vec3 dot(vec3, vec3);
- TFunctionDot4_4, // vec4 dot(vec4, vec4);
-
- TFunctionLength1, // float length(float);
- TFunctionLength2, // float length(vec2);
- TFunctionLength3, // float length(vec3);
- TFunctionLength4, // float length(vec4);
-
- TFunctionNormalize1, // float normalize(float);
- TFunctionNormalize2, // vec2 normalize(vec2);
- TFunctionNormalize3, // vec3 normalize(vec3);
- TFunctionNormalize4, // vec4 normalize(vec4);
-
- TFunctionReflect1_1, // float reflect(float, float);
- TFunctionReflect2_2, // vec2 reflect(vec2, vec2);
- TFunctionReflect3_3, // vec3 reflect(vec3, vec3);
- TFunctionReflect4_4, // vec4 reflect(vec4, vec4);
-
- TFunctionUnknown
- };
+ 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(TOperator op, const TType& param, const char* emulatedFunctionDefinition);
+ void addEmulatedFunction(TOperator op, const TType& param1, const TType& param2, const char* emulatedFunctionDefinition);
+ void addEmulatedFunction(TOperator op, const TType& param1, const TType& param2, const TType& param3, const char* emulatedFunctionDefinition);
- TBuiltInFunction IdentifyFunction(TOperator op, const TType& param);
- TBuiltInFunction IdentifyFunction(
+ 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(TOperator op, const TType& param);
+ bool SetFunctionCalled(
TOperator op, const TType& param1, const TType& param2);
+ bool SetFunctionCalled(
+ TOperator op, const TType& param1, const TType& param2, const TType& param3);
+
+ class FunctionId {
+ public:
+ FunctionId(TOperator op, const TType& param);
+ FunctionId(TOperator op, const TType& param1, const TType& param2);
+ FunctionId(TOperator op, const TType& param1, const TType& param2, const TType& param3);
+
+ bool operator==(const FunctionId& other) const;
+ bool operator<(const FunctionId& other) const;
+ private:
+ TOperator mOp;
+ TType mParam1;
+ TType mParam2;
+ TType mParam3;
+ };
- bool SetFunctionCalled(TBuiltInFunction function);
+ bool SetFunctionCalled(const FunctionId& functionId);
- std::vector<TBuiltInFunction> mFunctions;
+ // Map from function id to emulated function definition
+ std::map<FunctionId, std::string> mEmulatedFunctions;
- const bool* mFunctionMask; // a boolean flag for each function.
- const char** mFunctionSource;
+ // Called function ids
+ std::vector<FunctionId> mFunctions;
};
-#endif // COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
+#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
new file mode 100644
index 0000000000..9de99831ad
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
@@ -0,0 +1,37 @@
+//
+// Copyright (c) 2002-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 "angle_gl.h"
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
+#include "compiler/translator/SymbolTable.h"
+
+void InitBuiltInFunctionEmulatorForGLSL(BuiltInFunctionEmulator *emu, sh::GLenum shaderType)
+{
+ // we use macros here instead of function definitions to work around more GLSL
+ // compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are
+ // problematic because if the argument has side-effects they will be repeatedly
+ // evaluated. This is unlikely to show up in real shaders, but is something to
+ // consider.
+
+ TType float1(EbtFloat);
+ TType float2(EbtFloat, 2);
+ TType float3(EbtFloat, 3);
+ TType float4(EbtFloat, 4);
+
+ if (shaderType == GL_FRAGMENT_SHADER)
+ {
+ emu->addEmulatedFunction(EOpCos, float1, "webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }");
+ emu->addEmulatedFunction(EOpCos, float2, "webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }");
+ emu->addEmulatedFunction(EOpCos, float3, "webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }");
+ emu->addEmulatedFunction(EOpCos, float4, "webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }");
+ }
+ emu->addEmulatedFunction(EOpDistance, float1, float1, "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))");
+ emu->addEmulatedFunction(EOpDot, float1, float1, "#define webgl_dot_emu(x, y) ((x) * (y))");
+ emu->addEmulatedFunction(EOpLength, float1, "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))");
+ emu->addEmulatedFunction(EOpNormalize, float1, "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))");
+ emu->addEmulatedFunction(EOpReflect, float1, float1, "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))");
+}
diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h
new file mode 100644
index 0000000000..5707a4b35a
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h
@@ -0,0 +1,19 @@
+//
+// Copyright (c) 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"
+
+class BuiltInFunctionEmulator;
+
+//
+// This is only a workaround for OpenGL driver bugs, and isn't needed in general.
+//
+void InitBuiltInFunctionEmulatorForGLSL(BuiltInFunctionEmulator *emu, sh::GLenum shaderType);
+
+#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
new file mode 100644
index 0000000000..7123a0d5c0
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
@@ -0,0 +1,410 @@
+//
+// Copyright (c) 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 "angle_gl.h"
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
+#include "compiler/translator/SymbolTable.h"
+
+void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
+{
+ TType float1(EbtFloat);
+ TType float2(EbtFloat, 2);
+ TType float3(EbtFloat, 3);
+ TType float4(EbtFloat, 4);
+
+ emu->addEmulatedFunction(EOpMod, float1, float1,
+ "float webgl_mod_emu(float x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"
+ "\n");
+ emu->addEmulatedFunction(EOpMod, float2, float2,
+ "float2 webgl_mod_emu(float2 x, float2 y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"
+ "\n");
+ emu->addEmulatedFunction(EOpMod, float2, float1,
+ "float2 webgl_mod_emu(float2 x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"
+ "\n");
+ emu->addEmulatedFunction(EOpMod, float3, float3,
+ "float3 webgl_mod_emu(float3 x, float3 y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"
+ "\n");
+ emu->addEmulatedFunction(EOpMod, float3, float1,
+ "float3 webgl_mod_emu(float3 x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"
+ "\n");
+ emu->addEmulatedFunction(EOpMod, float4, float4,
+ "float4 webgl_mod_emu(float4 x, float4 y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"
+ "\n");
+ emu->addEmulatedFunction(EOpMod, float4, float1,
+ "float4 webgl_mod_emu(float4 x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"
+ "\n");
+
+ emu->addEmulatedFunction(EOpFaceForward, float1, float1, float1,
+ "float webgl_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"
+ "\n");
+ emu->addEmulatedFunction(EOpFaceForward, float2, float2, float2,
+ "float2 webgl_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"
+ "\n");
+ emu->addEmulatedFunction(EOpFaceForward, float3, float3, float3,
+ "float3 webgl_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"
+ "\n");
+ emu->addEmulatedFunction(EOpFaceForward, float4, float4, float4,
+ "float4 webgl_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"
+ "\n");
+
+ emu->addEmulatedFunction(EOpAtan, float1, float1,
+ "float webgl_atan_emu(float y, float x)\n"
+ "{\n"
+ " if(x == 0 && y == 0) x = 1;\n" // Avoid producing a NaN
+ " return atan2(y, x);\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpAtan, float2, float2,
+ "float2 webgl_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");
+ emu->addEmulatedFunction(EOpAtan, float3, float3,
+ "float3 webgl_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");
+ emu->addEmulatedFunction(EOpAtan, float4, float4,
+ "float4 webgl_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], x[2]), atan2(y[3], x[3]));\n"
+ "}\n");
+
+ emu->addEmulatedFunction(EOpAsinh, float1,
+ "float webgl_asinh_emu(in float x) {\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpAsinh, float2,
+ "float2 webgl_asinh_emu(in float2 x) {\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpAsinh, float3,
+ "float3 webgl_asinh_emu(in float3 x) {\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpAsinh, float4,
+ "float4 webgl_asinh_emu(in float4 x) {\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n");
+
+ emu->addEmulatedFunction(EOpAcosh, float1,
+ "float webgl_acosh_emu(in float x) {\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpAcosh, float2,
+ "float2 webgl_acosh_emu(in float2 x) {\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpAcosh, float3,
+ "float3 webgl_acosh_emu(in float3 x) {\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpAcosh, float4,
+ "float4 webgl_acosh_emu(in float4 x) {\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n");
+
+ emu->addEmulatedFunction(EOpAtanh, float1,
+ "float webgl_atanh_emu(in float x) {\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpAtanh, float2,
+ "float2 webgl_atanh_emu(in float2 x) {\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpAtanh, float3,
+ "float3 webgl_atanh_emu(in float3 x) {\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpAtanh, float4,
+ "float4 webgl_atanh_emu(in float4 x) {\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n");
+
+ emu->addEmulatedFunction(EOpRoundEven, float1,
+ "float webgl_roundEven_emu(in float x) {\n"
+ " return (frac(x) == 0.5 && trunc(x) % 2.0 == 0.0) ? trunc(x) : round(x);\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpRoundEven, float2,
+ "float2 webgl_roundEven_emu(in float2 x) {\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");
+ emu->addEmulatedFunction(EOpRoundEven, float3,
+ "float3 webgl_roundEven_emu(in float3 x) {\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");
+ emu->addEmulatedFunction(EOpRoundEven, float4,
+ "float4 webgl_roundEven_emu(in float4 x) {\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");
+
+ emu->addEmulatedFunction(EOpPackSnorm2x16, float2,
+ "int webgl_toSnorm(in float x) {\n"
+ " return int(round(clamp(x, -1.0, 1.0) * 32767.0));\n"
+ "}\n"
+ "\n"
+ "uint webgl_packSnorm2x16_emu(in float2 v) {\n"
+ " int x = webgl_toSnorm(v.x);\n"
+ " int y = webgl_toSnorm(v.y);\n"
+ " return (asuint(y) << 16) | (asuint(x) & 0xffffu);\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpPackUnorm2x16, float2,
+ "uint webgl_toUnorm(in float x) {\n"
+ " return uint(round(clamp(x, 0.0, 1.0) * 65535.0));\n"
+ "}\n"
+ "\n"
+ "uint webgl_packUnorm2x16_emu(in float2 v) {\n"
+ " uint x = webgl_toUnorm(v.x);\n"
+ " uint y = webgl_toUnorm(v.y);\n"
+ " return (y << 16) | x;\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpPackHalf2x16, float2,
+ "uint webgl_packHalf2x16_emu(in float2 v) {\n"
+ " uint x = f32tof16(v.x);\n"
+ " uint y = f32tof16(v.y);\n"
+ " return (y << 16) | x;\n"
+ "}\n");
+
+ TType uint1(EbtUInt);
+
+ emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1,
+ "float webgl_fromSnorm(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"
+ "\n"
+ "float2 webgl_unpackSnorm2x16_emu(in uint u) {\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u;\n"
+ " return float2(webgl_fromSnorm(x), webgl_fromSnorm(y));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1,
+ "float webgl_fromUnorm(in uint x) {\n"
+ " return float(x) / 65535.0;\n"
+ "}\n"
+ "\n"
+ "float2 webgl_unpackUnorm2x16_emu(in uint u) {\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u & 0xffffu;\n"
+ " return float2(webgl_fromUnorm(x), webgl_fromUnorm(y));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpUnpackHalf2x16, uint1,
+ "float2 webgl_unpackHalf2x16_emu(in uint u) {\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u & 0xffffu;\n"
+ " return float2(f16tof32(x), f16tof32(y));\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.
+ emu->addEmulatedFunction(EOpOuterProduct, float2, float2,
+ "float2x2 webgl_outerProduct_emu(in float2 c, in float2 r) {\n"
+ " return mul(float2x1(r), float1x2(c));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpOuterProduct, float3, float3,
+ "float3x3 webgl_outerProduct_emu(in float3 c, in float3 r) {\n"
+ " return mul(float3x1(r), float1x3(c));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpOuterProduct, float4, float4,
+ "float4x4 webgl_outerProduct_emu(in float4 c, in float4 r) {\n"
+ " return mul(float4x1(r), float1x4(c));\n"
+ "}\n");
+
+ emu->addEmulatedFunction(EOpOuterProduct, float3, float2,
+ "float2x3 webgl_outerProduct_emu(in float3 c, in float2 r) {\n"
+ " return mul(float2x1(r), float1x3(c));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpOuterProduct, float2, float3,
+ "float3x2 webgl_outerProduct_emu(in float2 c, in float3 r) {\n"
+ " return mul(float3x1(r), float1x2(c));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpOuterProduct, float4, float2,
+ "float2x4 webgl_outerProduct_emu(in float4 c, in float2 r) {\n"
+ " return mul(float2x1(r), float1x4(c));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpOuterProduct, float2, float4,
+ "float4x2 webgl_outerProduct_emu(in float2 c, in float4 r) {\n"
+ " return mul(float4x1(r), float1x2(c));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpOuterProduct, float4, float3,
+ "float3x4 webgl_outerProduct_emu(in float4 c, in float3 r) {\n"
+ " return mul(float3x1(r), float1x4(c));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpOuterProduct, float3, float4,
+ "float4x3 webgl_outerProduct_emu(in float3 c, in float4 r) {\n"
+ " return mul(float4x1(r), float1x3(c));\n"
+ "}\n");
+
+ TType mat2(EbtFloat, 2, 2);
+ TType mat3(EbtFloat, 3, 3);
+ TType mat4(EbtFloat, 4, 4);
+
+ // 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.
+
+ emu->addEmulatedFunction(EOpInverse, mat2,
+ "float2x2 webgl_inverse_emu(in float2x2 m) {\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.
+
+ emu->addEmulatedFunction(EOpInverse, mat3,
+ "float3x3 webgl_inverse_emu(in float3x3 m) {\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");
+
+ emu->addEmulatedFunction(EOpInverse, mat4,
+ "float4x4 webgl_inverse_emu(in float4x4 m) {\n"
+ " float cof00 = m[1][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3]"
+ " - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] - m[3][1] * m[2][2] * 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] * m[1][2] * m[2][3]"
+ " - m[1][0] * m[3][2] * m[2][3] - m[2][0] * m[1][2] * m[3][3] - m[3][0] * m[2][2] * 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] * m[1][1] * m[2][3]"
+ " - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] - m[3][0] * m[2][1] * 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] * m[1][1] * m[2][2]"
+ " - m[1][0] * m[3][1] * m[2][2] - m[2][0] * m[1][1] * m[3][2] - m[3][0] * m[2][1] * 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] * m[0][2] * m[2][3]"
+ " - m[0][1] * m[3][2] * m[2][3] - m[2][1] * m[0][2] * m[3][3] - m[3][1] * m[2][2] * 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] * m[0][2] * m[2][3]"
+ " - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] - m[3][0] * m[2][2] * 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] * m[0][1] * m[2][3]"
+ " - m[0][0] * m[3][1] * m[2][3] - m[2][0] * m[0][1] * m[3][3] - m[3][0] * m[2][1] * 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] * m[0][1] * m[2][2]"
+ " - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] - m[3][0] * m[2][1] * 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] * m[0][2] * m[1][3]"
+ " - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] - m[3][1] * m[1][2] * 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] * m[0][2] * m[1][3]"
+ " - m[0][0] * m[3][2] * m[1][3] - m[1][0] * m[0][2] * m[3][3] - m[3][0] * m[1][2] * 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] * m[0][1] * m[1][3]"
+ " - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] - m[3][0] * m[1][1] * 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] * m[0][1] * m[1][2]"
+ " - m[0][0] * m[3][1] * m[1][2] - m[1][0] * m[0][1] * m[3][2] - m[3][0] * m[1][1] * 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] * m[0][2] * m[1][3]"
+ " - m[0][1] * m[2][2] * m[1][3] - m[1][1] * m[0][2] * m[2][3] - m[2][1] * m[1][2] * 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] * m[0][2] * m[1][3]"
+ " - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] - m[2][0] * m[1][2] * 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] * m[0][1] * m[1][3]"
+ " - m[0][0] * m[2][1] * m[1][3] - m[1][0] * m[0][1] * m[2][3] - m[2][0] * m[1][1] * 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] * m[0][1] * m[1][2]"
+ " - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] - m[2][0] * m[1][1] * m[0][2];\n"
+ " float4x4 cof = { cof00, cof10, cof20, cof30, cof01, cof11, cof21, cof31,"
+ " cof02, cof12, cof22, cof32, cof03, cof13, cof23, cof33 };\n"
+ " return cof / determinant(transpose(m));\n"
+ "}\n");
+}
diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h
new file mode 100644
index 0000000000..4c45a93dc4
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h
@@ -0,0 +1,16 @@
+//
+// Copyright (c) 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"
+
+class BuiltInFunctionEmulator;
+
+void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu);
+
+#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/CodeGen.cpp b/src/3rdparty/angle/src/compiler/translator/CodeGen.cpp
index 71056f4297..5e3eb1cc05 100644
--- a/src/3rdparty/angle/src/compiler/translator/CodeGen.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/CodeGen.cpp
@@ -6,7 +6,9 @@
#include "compiler/translator/TranslatorESSL.h"
#include "compiler/translator/TranslatorGLSL.h"
+#ifdef ANGLE_ENABLE_HLSL
#include "compiler/translator/TranslatorHLSL.h"
+#endif // ANGLE_ENABLE_HLSL
//
// This function must be provided to create the actual
@@ -17,14 +19,22 @@ TCompiler* ConstructCompiler(
sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
{
switch (output) {
- case SH_ESSL_OUTPUT:
+ case SH_ESSL_OUTPUT:
return new TranslatorESSL(type, spec);
- case SH_GLSL_OUTPUT:
- return new TranslatorGLSL(type, spec);
- case SH_HLSL9_OUTPUT:
- case SH_HLSL11_OUTPUT:
+ case SH_GLSL_CORE_OUTPUT:
+ case SH_GLSL_COMPATIBILITY_OUTPUT:
+ return new TranslatorGLSL(type, spec, output);
+ case SH_HLSL9_OUTPUT:
+ case SH_HLSL11_OUTPUT:
+#ifdef ANGLE_ENABLE_HLSL
return new TranslatorHLSL(type, spec, output);
- default:
+#else
+ // This compiler is not supported in this
+ // configuration. Return NULL per the ShConstructCompiler API.
+ return NULL;
+#endif // ANGLE_ENABLE_HLSL
+ default:
+ // Unknown format. Return NULL per the ShConstructCompiler API.
return NULL;
}
}
diff --git a/src/3rdparty/angle/src/compiler/translator/Common.h b/src/3rdparty/angle/src/compiler/translator/Common.h
index 1e4503e340..ac1aef0f4c 100644
--- a/src/3rdparty/angle/src/compiler/translator/Common.h
+++ b/src/3rdparty/angle/src/compiler/translator/Common.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef _COMMON_INCLUDED_
-#define _COMMON_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_COMMON_H_
+#define COMPILER_TRANSLATOR_COMMON_H_
#include <map>
#include <sstream>
@@ -89,4 +89,4 @@ inline TString str(T i)
return buffer;
}
-#endif // _COMMON_INCLUDED_
+#endif // COMPILER_TRANSLATOR_COMMON_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/Compiler.cpp b/src/3rdparty/angle/src/compiler/translator/Compiler.cpp
index 5c62a64d10..534861ca70 100644
--- a/src/3rdparty/angle/src/compiler/translator/Compiler.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/Compiler.cpp
@@ -4,7 +4,6 @@
// found in the LICENSE file.
//
-#include "compiler/translator/BuiltInFunctionEmulator.h"
#include "compiler/translator/Compiler.h"
#include "compiler/translator/DetectCallDepth.h"
#include "compiler/translator/ForLoopUnroll.h"
@@ -126,7 +125,8 @@ TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
maxCallStackDepth(0),
fragmentPrecisionHigh(false),
clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
- builtInFunctionEmulator(type)
+ builtInFunctionEmulator(),
+ mSourcePath(NULL)
{
}
@@ -159,33 +159,41 @@ bool TCompiler::Init(const ShBuiltInResources& resources)
return true;
}
-bool TCompiler::compile(const char* const shaderStrings[],
- size_t numStrings,
- int compileOptions)
+TIntermNode *TCompiler::compileTreeForTesting(const char* const shaderStrings[],
+ size_t numStrings, int compileOptions)
+{
+ return compileTreeImpl(shaderStrings, numStrings, compileOptions);
+}
+
+TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[],
+ size_t numStrings, int compileOptions)
{
- TScopedPoolAllocator scopedAlloc(&allocator);
clearResults();
- if (numStrings == 0)
- return true;
+ ASSERT(numStrings > 0);
+ ASSERT(GetGlobalPoolAllocator());
+
+ // Reset the extension behavior for each compilation unit.
+ ResetExtensionBehavior(extensionBehavior);
// If compiling for WebGL, validate loop and indexing as well.
if (IsWebGLBasedSpec(shaderSpec))
compileOptions |= SH_VALIDATE_LOOP_INDEXING;
// First string is path of source file if flag is set. The actual source follows.
- const char* sourcePath = NULL;
size_t firstSource = 0;
if (compileOptions & SH_SOURCE_PATH)
{
- sourcePath = shaderStrings[0];
+ mSourcePath = shaderStrings[0];
++firstSource;
}
+ bool debugShaderPrecision = getResources().WEBGL_debug_shader_precision == 1;
TIntermediate intermediate(infoSink);
TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
shaderType, shaderSpec, compileOptions, true,
- sourcePath, infoSink);
+ infoSink, debugShaderPrecision);
+
parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
SetGlobalParseContext(&parseContext);
@@ -206,6 +214,8 @@ bool TCompiler::compile(const char* const shaderStrings[],
success = false;
}
+ TIntermNode *root = NULL;
+
if (success)
{
mPragma = parseContext.pragma();
@@ -214,7 +224,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
symbolTable.setGlobalInvariant();
}
- TIntermNode* root = parseContext.treeRoot;
+ root = parseContext.treeRoot;
success = intermediate.postProcess(root);
// Disallow expressions deemed too complex.
@@ -255,8 +265,11 @@ bool TCompiler::compile(const char* const shaderStrings[],
}
// Built-in function emulation needs to happen after validateLimitations pass.
- if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
+ if (success)
+ {
+ initBuiltInFunctionEmulator(&builtInFunctionEmulator, compileOptions);
builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
+ }
// Clamping uniform array bounds needs to happen after validateLimitations pass.
if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
@@ -301,18 +314,37 @@ bool TCompiler::compile(const char* const shaderStrings[],
RegenerateStructNames gen(symbolTable, shaderVersion);
root->traverse(&gen);
}
-
- if (success && (compileOptions & SH_INTERMEDIATE_TREE))
- intermediate.outputTree(root);
-
- if (success && (compileOptions & SH_OBJECT_CODE))
- translate(root);
}
- // Cleanup memory.
- intermediate.remove(parseContext.treeRoot);
SetGlobalParseContext(NULL);
- return success;
+ if (success)
+ return root;
+
+ return NULL;
+}
+
+bool TCompiler::compile(const char* const shaderStrings[],
+ size_t numStrings, int compileOptions)
+{
+ if (numStrings == 0)
+ return true;
+
+ TScopedPoolAllocator scopedAlloc(&allocator);
+ TIntermNode *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
+
+ if (root)
+ {
+ if (compileOptions & SH_INTERMEDIATE_TREE)
+ TIntermediate::outputTree(root, infoSink.info);
+
+ if (compileOptions & SH_OBJECT_CODE)
+ translate(root, compileOptions);
+
+ // 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)
@@ -390,11 +422,15 @@ void TCompiler::setResourceString()
<< ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
<< ":EXT_frag_depth:" << compileResources.EXT_frag_depth
<< ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
+ << ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
+ << ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
+ << ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
<< ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
- << ":NV_draw_buffers:" << compileResources.NV_draw_buffers;
+ << ":NV_draw_buffers:" << compileResources.NV_draw_buffers
+ << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision;
builtInResourcesString = strstream.str();
}
@@ -416,27 +452,29 @@ void TCompiler::clearResults()
builtInFunctionEmulator.Cleanup();
nameMap.clear();
+
+ mSourcePath = NULL;
}
-bool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth)
+bool TCompiler::detectCallDepth(TIntermNode* inputRoot, TInfoSink& inputInfoSink, bool limitCallStackDepth)
{
- DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth);
- root->traverse(&detect);
+ DetectCallDepth detect(inputInfoSink, limitCallStackDepth, maxCallStackDepth);
+ inputRoot->traverse(&detect);
switch (detect.detectCallDepth())
{
case DetectCallDepth::kErrorNone:
return true;
case DetectCallDepth::kErrorMissingMain:
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "Missing main()";
+ inputInfoSink.info.prefix(EPrefixError);
+ inputInfoSink.info << "Missing main()";
return false;
case DetectCallDepth::kErrorRecursion:
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "Function recursion detected";
+ inputInfoSink.info.prefix(EPrefixError);
+ inputInfoSink.info << "Function recursion detected";
return false;
case DetectCallDepth::kErrorMaxDepthExceeded:
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "Function call stack too deep";
+ inputInfoSink.info.prefix(EPrefixError);
+ inputInfoSink.info << "Function call stack too deep";
return false;
default:
UNREACHABLE();
@@ -594,6 +632,11 @@ const TExtensionBehavior& TCompiler::getExtensionBehavior() const
return extensionBehavior;
}
+const char *TCompiler::getSourcePath() const
+{
+ return mSourcePath;
+}
+
const ShBuiltInResources& TCompiler::getResources() const
{
return compileResources;
diff --git a/src/3rdparty/angle/src/compiler/translator/Compiler.h b/src/3rdparty/angle/src/compiler/translator/Compiler.h
index b6c9d13ed0..bcdb0d4c9d 100644
--- a/src/3rdparty/angle/src/compiler/translator/Compiler.h
+++ b/src/3rdparty/angle/src/compiler/translator/Compiler.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef _SHHANDLE_INCLUDED_
-#define _SHHANDLE_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_COMPILER_H_
+#define COMPILER_TRANSLATOR_COMPILER_H_
//
// Machine independent part of the compiler private objects
@@ -25,7 +25,9 @@
class TCompiler;
class TDependencyGraph;
+#ifdef ANGLE_ENABLE_HLSL
class TranslatorHLSL;
+#endif // ANGLE_ENABLE_HLSL
//
// Helper function to identify specs that are based on the WebGL spec,
@@ -41,7 +43,9 @@ public:
TShHandleBase();
virtual ~TShHandleBase();
virtual TCompiler* getAsCompiler() { return 0; }
+#ifdef ANGLE_ENABLE_HLSL
virtual TranslatorHLSL* getAsTranslatorHLSL() { return 0; }
+#endif // ANGLE_ENABLE_HLSL
protected:
// Memory allocator. Allocates and tracks memory required by the compiler.
@@ -61,9 +65,15 @@ class TCompiler : public TShHandleBase
virtual TCompiler* getAsCompiler() { 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 NULL whenever there are compilation errors.
+ TIntermNode *compileTreeForTesting(const char* const shaderStrings[],
+ size_t numStrings, int compileOptions);
+
bool compile(const char* const shaderStrings[],
- size_t numStrings,
- int compileOptions);
+ size_t numStrings, int compileOptions);
// Get results of the last compilation.
int getShaderVersion() const { return shaderVersion; }
@@ -104,8 +114,10 @@ class TCompiler : public TShHandleBase
bool validateLimitations(TIntermNode* root);
// Collect info for all attribs, uniforms, varyings.
void collectVariables(TIntermNode* root);
+ // Add emulated functions to the built-in function emulator.
+ virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) {};
// Translate to object code.
- virtual void translate(TIntermNode* root) = 0;
+ virtual void translate(TIntermNode *root, int compileOptions) = 0;
// Returns true if, after applying the packing rules in the GLSL 1.017 spec
// Appendix A, section 7, the shader does not use too many uniforms.
bool enforcePackingRestrictions();
@@ -130,6 +142,7 @@ class TCompiler : public TShHandleBase
bool limitExpressionComplexity(TIntermNode* root);
// Get built-in extensions with default behavior.
const TExtensionBehavior& getExtensionBehavior() const;
+ const char *getSourcePath() const;
const TPragma& getPragma() const { return mPragma; }
void writePragma();
@@ -145,6 +158,9 @@ class TCompiler : public TShHandleBase
std::vector<sh::InterfaceBlock> interfaceBlocks;
private:
+ TIntermNode *compileTreeImpl(const char* const shaderStrings[],
+ size_t numStrings, int compileOptions);
+
sh::GLenum shaderType;
ShShaderSpec shaderSpec;
ShShaderOutput outputType;
@@ -170,6 +186,7 @@ class TCompiler : public TShHandleBase
// Results of compilation.
int shaderVersion;
TInfoSink infoSink; // Output sink.
+ const char *mSourcePath; // Path of source file or NULL
// name hashing.
ShHashFunction64 hashFunction;
@@ -191,4 +208,4 @@ TCompiler* ConstructCompiler(
sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
void DeleteCompiler(TCompiler*);
-#endif // _SHHANDLE_INCLUDED_
+#endif // COMPILER_TRANSLATOR_COMPILER_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/ConstantUnion.h b/src/3rdparty/angle/src/compiler/translator/ConstantUnion.h
index 5e86c64805..31ff2ccfa7 100644
--- a/src/3rdparty/angle/src/compiler/translator/ConstantUnion.h
+++ b/src/3rdparty/angle/src/compiler/translator/ConstantUnion.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef _CONSTANT_UNION_INCLUDED_
-#define _CONSTANT_UNION_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_CONSTANTUNION_H_
+#define COMPILER_TRANSLATOR_CONSTANTUNION_H_
#include <assert.h>
@@ -254,7 +254,10 @@ public:
ConstantUnion operator<<(const ConstantUnion& constant) const
{
ConstantUnion returnValue;
- assert(type == constant.type);
+ // The signedness of the second parameter might be different, but we
+ // don't care, since the result is undefined if the second parameter is
+ // negative, and aliasing should not be a problem with unions.
+ assert(constant.type == EbtInt || constant.type == EbtUInt);
switch (type) {
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break;
@@ -267,7 +270,7 @@ public:
ConstantUnion operator&(const ConstantUnion& constant) const
{
ConstantUnion returnValue;
- assert(type == constant.type);
+ 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;
@@ -340,4 +343,4 @@ private:
TBasicType type;
};
-#endif // _CONSTANT_UNION_INCLUDED_
+#endif // COMPILER_TRANSLATOR_CONSTANTUNION_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.cpp b/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.cpp
index bfc1d5852f..0dc5d22709 100644
--- a/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.cpp
@@ -33,7 +33,7 @@ int DetectCallDepth::FunctionNode::detectCallDepth(DetectCallDepth* detectCallDe
ASSERT(visit == PreVisit);
ASSERT(detectCallDepth);
- int maxDepth = depth;
+ int retMaxDepth = depth;
visit = InVisit;
for (size_t i = 0; i < callees.size(); ++i) {
switch (callees[i]->visit) {
@@ -52,7 +52,7 @@ int DetectCallDepth::FunctionNode::detectCallDepth(DetectCallDepth* detectCallDe
detectCallDepth->getInfoSink().info << "<-" << callees[i]->getName();
return callDepth;
}
- maxDepth = std::max(callDepth, maxDepth);
+ retMaxDepth = std::max(callDepth, retMaxDepth);
break;
}
default:
@@ -61,7 +61,7 @@ int DetectCallDepth::FunctionNode::detectCallDepth(DetectCallDepth* detectCallDe
}
}
visit = PostVisit;
- return maxDepth;
+ return retMaxDepth;
}
void DetectCallDepth::FunctionNode::reset()
diff --git a/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.h b/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.h
index 86810650dc..8dd1391e67 100644
--- a/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.h
+++ b/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_DETECT_RECURSION_H_
-#define COMPILER_DETECT_RECURSION_H_
+#ifndef COMPILER_TRANSLATOR_DETECTCALLDEPTH_H_
+#define COMPILER_TRANSLATOR_DETECTCALLDEPTH_H_
#include <limits.h>
#include "compiler/translator/IntermNode.h"
@@ -75,4 +75,4 @@ private:
void operator=(const DetectCallDepth&);
};
-#endif // COMPILER_DETECT_RECURSION_H_
+#endif // COMPILER_TRANSLATOR_DETECTCALLDEPTH_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h
index 67e37be398..623be13533 100644
--- a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h
+++ b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h
@@ -8,8 +8,8 @@
// gradients of functions with discontinuities.
//
-#ifndef COMPILER_DETECTDISCONTINUITY_H_
-#define COMPILER_DETECTDISCONTINUITY_H_
+#ifndef COMPILER_TRANSLATOR_DETECTDISCONTINUITY_H_
+#define COMPILER_TRANSLATOR_DETECTDISCONTINUITY_H_
#include "compiler/translator/IntermNode.h"
@@ -68,4 +68,4 @@ bool containsGradientOperation(TIntermNode *node);
}
-#endif // COMPILER_DETECTDISCONTINUITY_H_
+#endif // COMPILER_TRANSLATOR_DETECTDISCONTINUITY_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/Diagnostics.h b/src/3rdparty/angle/src/compiler/translator/Diagnostics.h
index 664da7803b..078bc97772 100644
--- a/src/3rdparty/angle/src/compiler/translator/Diagnostics.h
+++ b/src/3rdparty/angle/src/compiler/translator/Diagnostics.h
@@ -4,14 +4,15 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_DIAGNOSTICS_H_
-#define COMPILER_DIAGNOSTICS_H_
+#ifndef COMPILER_TRANSLATOR_DIAGNOSTICS_H_
+#define COMPILER_TRANSLATOR_DIAGNOSTICS_H_
+#include "common/angleutils.h"
#include "compiler/preprocessor/DiagnosticsBase.h"
class TInfoSink;
-class TDiagnostics : public pp::Diagnostics
+class TDiagnostics : public pp::Diagnostics, angle::NonCopyable
{
public:
TDiagnostics(TInfoSink& infoSink);
@@ -41,4 +42,4 @@ class TDiagnostics : public pp::Diagnostics
int mNumWarnings;
};
-#endif // COMPILER_DIAGNOSTICS_H_
+#endif // COMPILER_TRANSLATOR_DIAGNOSTICS_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp
index f67a03aa93..936c00a56c 100644
--- a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp
@@ -27,10 +27,12 @@ static TBehavior getBehavior(const std::string& str)
TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
TDiagnostics& diagnostics,
- int& shaderVersion)
+ int& shaderVersion,
+ bool debugShaderPrecisionSupported)
: mExtensionBehavior(extBehavior),
mDiagnostics(diagnostics),
- mShaderVersion(shaderVersion)
+ mShaderVersion(shaderVersion),
+ mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
{
}
@@ -65,6 +67,7 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
{
const char kOptimize[] = "optimize";
const char kDebug[] = "debug";
+ const char kDebugShaderPrecision[] = "webgl_debug_shader_precision";
const char kOn[] = "on";
const char kOff[] = "off";
@@ -81,6 +84,12 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
else if (value == kOff) mPragma.debug = false;
else invalidValue = true;
}
+ else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported)
+ {
+ if (value == kOn) mPragma.debugShaderPrecision = true;
+ else if (value == kOff) mPragma.debugShaderPrecision = false;
+ else invalidValue = true;
+ }
else
{
mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
diff --git a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h
index 0433c3bf89..2a81ee5707 100644
--- a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h
+++ b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h
@@ -4,21 +4,23 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_DIRECTIVE_HANDLER_H_
-#define COMPILER_DIRECTIVE_HANDLER_H_
+#ifndef COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
+#define COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
+#include "common/angleutils.h"
#include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/Pragma.h"
#include "compiler/preprocessor/DirectiveHandlerBase.h"
class TDiagnostics;
-class TDirectiveHandler : public pp::DirectiveHandler
+class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable
{
public:
TDirectiveHandler(TExtensionBehavior& extBehavior,
TDiagnostics& diagnostics,
- int& shaderVersion);
+ int& shaderVersion,
+ bool debugShaderPrecisionSupported);
virtual ~TDirectiveHandler();
const TPragma& pragma() const { return mPragma; }
@@ -44,6 +46,7 @@ class TDirectiveHandler : public pp::DirectiveHandler
TExtensionBehavior& mExtensionBehavior;
TDiagnostics& mDiagnostics;
int& mShaderVersion;
+ bool mDebugShaderPrecisionSupported;
};
-#endif // COMPILER_DIRECTIVE_HANDLER_H_
+#endif // COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.cpp b/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.cpp
new file mode 100644
index 0000000000..697e042954
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.cpp
@@ -0,0 +1,528 @@
+//
+// Copyright (c) 2002-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/EmulatePrecision.h"
+
+namespace
+{
+
+static void writeVectorPrecisionEmulationHelpers(
+ TInfoSinkBase& sink, ShShaderOutput outputLanguage, unsigned int size)
+{
+ std::stringstream vecTypeStrStr;
+ if (outputLanguage == SH_ESSL_OUTPUT)
+ vecTypeStrStr << "highp ";
+ vecTypeStrStr << "vec" << size;
+ std::string vecType = vecTypeStrStr.str();
+
+ sink <<
+ vecType << " angle_frm(in " << vecType << " v) {\n"
+ " v = clamp(v, -65504.0, 65504.0);\n"
+ " " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n"
+ " bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n"
+ " v = v * exp2(-exponent);\n"
+ " v = sign(v) * floor(abs(v));\n"
+ " return v * exp2(exponent) * vec" << size << "(isNonZero);\n"
+ "}\n";
+
+ sink <<
+ vecType << " angle_frl(in " << vecType << " v) {\n"
+ " v = clamp(v, -2.0, 2.0);\n"
+ " v = v * 256.0;\n"
+ " v = sign(v) * floor(abs(v));\n"
+ " return v * 0.00390625;\n"
+ "}\n";
+}
+
+static void writeMatrixPrecisionEmulationHelper(
+ TInfoSinkBase& sink, ShShaderOutput outputLanguage, unsigned int size, const char *functionName)
+{
+ std::stringstream matTypeStrStr;
+ if (outputLanguage == SH_ESSL_OUTPUT)
+ matTypeStrStr << "highp ";
+ matTypeStrStr << "mat" << size;
+ std::string matType = matTypeStrStr.str();
+
+ sink << matType << " " << functionName << "(in " << matType << " m) {\n"
+ " " << matType << " rounded;\n";
+
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ sink << " rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n";
+ }
+
+ sink << " return rounded;\n"
+ "}\n";
+}
+
+static void writeCommonPrecisionEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage)
+{
+ // Write the angle_frm functions that round floating point numbers to
+ // half precision, and angle_frl functions that round them to minimum lowp
+ // precision.
+
+ // Unoptimized version of angle_frm for single floats:
+ //
+ // int webgl_maxNormalExponent(in int exponentBits) {
+ // int possibleExponents = int(exp2(float(exponentBits)));
+ // int exponentBias = possibleExponents / 2 - 1;
+ // int allExponentBitsOne = possibleExponents - 1;
+ // return (allExponentBitsOne - 1) - exponentBias;
+ // }
+ //
+ // float angle_frm(in float x) {
+ // int mantissaBits = 10;
+ // int exponentBits = 5;
+ // float possibleMantissas = exp2(float(mantissaBits));
+ // float mantissaMax = 2.0 - 1.0 / possibleMantissas;
+ // int maxNE = webgl_maxNormalExponent(exponentBits);
+ // float max = exp2(float(maxNE)) * mantissaMax;
+ // if (x > max) {
+ // return max;
+ // }
+ // if (x < -max) {
+ // return -max;
+ // }
+ // float exponent = floor(log2(abs(x)));
+ // if (abs(x) == 0.0 || exponent < -float(maxNE)) {
+ // return 0.0 * sign(x)
+ // }
+ // x = x * exp2(-(exponent - float(mantissaBits)));
+ // x = sign(x) * floor(abs(x));
+ // return x * exp2(exponent - float(mantissaBits));
+ // }
+
+ // All numbers with a magnitude less than 2^-15 are subnormal, and are
+ // flushed to zero.
+
+ // Note the constant numbers below:
+ // a) 65504 is the maximum possible mantissa (1.1111111111 in binary) times
+ // 2^15, the maximum normal exponent.
+ // b) 10.0 is the number of mantissa bits.
+ // c) -25.0 is the minimum normal half-float exponent -15.0 minus the number
+ // of mantissa bits.
+ // d) + 1e-30 is to make sure the argument of log2() won't be zero. It can
+ // only affect the result of log2 on x where abs(x) < 1e-22. Since these
+ // numbers will be flushed to zero either way (2^-15 is the smallest
+ // normal positive number), this does not introduce any error.
+
+ std::string floatType = "float";
+ if (outputLanguage == SH_ESSL_OUTPUT)
+ floatType = "highp float";
+
+ sink <<
+ floatType << " angle_frm(in " << floatType << " x) {\n"
+ " x = clamp(x, -65504.0, 65504.0);\n"
+ " " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n"
+ " bool isNonZero = (exponent >= -25.0);\n"
+ " x = x * exp2(-exponent);\n"
+ " x = sign(x) * floor(abs(x));\n"
+ " return x * exp2(exponent) * float(isNonZero);\n"
+ "}\n";
+
+ sink <<
+ floatType << " angle_frl(in " << floatType << " x) {\n"
+ " x = clamp(x, -2.0, 2.0);\n"
+ " x = x * 256.0;\n"
+ " x = sign(x) * floor(abs(x));\n"
+ " return x * 0.00390625;\n"
+ "}\n";
+
+ writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 2);
+ writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 3);
+ writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 4);
+ for (unsigned int size = 2; size <= 4; ++size)
+ {
+ writeMatrixPrecisionEmulationHelper(sink, outputLanguage, size, "angle_frm");
+ writeMatrixPrecisionEmulationHelper(sink, outputLanguage, size, "angle_frl");
+ }
+}
+
+static void writeCompoundAssignmentPrecisionEmulation(
+ TInfoSinkBase& sink, ShShaderOutput outputLanguage,
+ const char *lType, const char *rType, const char *opStr, const char *opNameStr)
+{
+ std::string lTypeStr = lType;
+ std::string rTypeStr = rType;
+ if (outputLanguage == SH_ESSL_OUTPUT)
+ {
+ std::stringstream lTypeStrStr;
+ lTypeStrStr << "highp " << lType;
+ lTypeStr = lTypeStrStr.str();
+ std::stringstream rTypeStrStr;
+ rTypeStrStr << "highp " << rType;
+ rTypeStr = rTypeStrStr.str();
+ }
+
+ // Note that y should be passed through angle_frm at the function call site,
+ // but x can't be passed through angle_frm there since it is an inout parameter.
+ // So only pass x and the result through angle_frm here.
+ sink <<
+ lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
+ " x = angle_frm(angle_frm(x) " << opStr << " y);\n"
+ " return x;\n"
+ "}\n";
+ sink <<
+ lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n"
+ " x = angle_frl(angle_frm(x) " << opStr << " y);\n"
+ " return x;\n"
+ "}\n";
+}
+
+const char *getFloatTypeStr(const TType& type)
+{
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "float";
+ case 2:
+ return type.getSecondarySize() > 1 ? "mat2" : "vec2";
+ case 3:
+ return type.getSecondarySize() > 1 ? "mat3" : "vec3";
+ case 4:
+ return type.getSecondarySize() > 1 ? "mat4" : "vec4";
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+bool canRoundFloat(const TType &type)
+{
+ return type.getBasicType() == EbtFloat && !type.isNonSquareMatrix() && !type.isArray() &&
+ (type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium);
+}
+
+TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *child)
+{
+ TIntermAggregate *callNode = new TIntermAggregate();
+ callNode->setOp(EOpInternalFunctionCall);
+ callNode->setName(name);
+ callNode->getSequence()->push_back(child);
+ return callNode;
+}
+
+TIntermAggregate *createRoundingFunctionCallNode(TIntermTyped *roundedChild)
+{
+ TString roundFunctionName;
+ if (roundedChild->getPrecision() == EbpMedium)
+ roundFunctionName = "angle_frm";
+ else
+ roundFunctionName = "angle_frl";
+ return createInternalFunctionCallNode(roundFunctionName, roundedChild);
+}
+
+TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left, TIntermTyped *right, const char *opNameStr)
+{
+ std::stringstream strstr;
+ if (left->getPrecision() == EbpMedium)
+ strstr << "angle_compound_" << opNameStr << "_frm";
+ else
+ strstr << "angle_compound_" << opNameStr << "_frl";
+ TString functionName = strstr.str().c_str();
+ TIntermAggregate *callNode = createInternalFunctionCallNode(functionName, left);
+ callNode->getSequence()->push_back(right);
+ return callNode;
+}
+
+bool parentUsesResult(TIntermNode* parent, TIntermNode* node)
+{
+ if (!parent)
+ {
+ return false;
+ }
+
+ TIntermAggregate *aggParent = parent->getAsAggregate();
+ // If the parent's op is EOpSequence, the result is not assigned anywhere,
+ // so rounding it is not needed. In particular, this can avoid a lot of
+ // unnecessary rounding of unused return values of assignment.
+ if (aggParent && aggParent->getOp() == EOpSequence)
+ {
+ return false;
+ }
+ if (aggParent && aggParent->getOp() == EOpComma && (aggParent->getSequence()->back() != node))
+ {
+ return false;
+ }
+ return true;
+}
+
+} // namespace anonymous
+
+EmulatePrecision::EmulatePrecision()
+ : TIntermTraverser(true, true, true),
+ mDeclaringVariables(false),
+ mInLValue(false),
+ mInFunctionCallOutParameter(false)
+{}
+
+void EmulatePrecision::visitSymbol(TIntermSymbol *node)
+{
+ if (canRoundFloat(node->getType()) &&
+ !mDeclaringVariables && !mInLValue && !mInFunctionCallOutParameter)
+ {
+ TIntermNode *parent = getParentNode();
+ TIntermNode *replacement = createRoundingFunctionCallNode(node);
+ mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
+ }
+}
+
+
+bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node)
+{
+ bool visitChildren = true;
+
+ if (node->isAssignment())
+ {
+ if (visit == PreVisit)
+ mInLValue = true;
+ else if (visit == InVisit)
+ mInLValue = false;
+ }
+
+ TOperator op = node->getOp();
+
+ // RHS of initialize is not being declared.
+ if (op == EOpInitialize && visit == InVisit)
+ mDeclaringVariables = false;
+
+ if ((op == EOpIndexDirectStruct || op == EOpVectorSwizzle) && visit == InVisit)
+ visitChildren = false;
+
+ if (visit != PreVisit)
+ return visitChildren;
+
+ const TType& type = node->getType();
+ bool roundFloat = canRoundFloat(type);
+
+ if (roundFloat) {
+ switch (op) {
+ // Math operators that can result in a float may need to apply rounding to the return
+ // value. Note that in the case of assignment, the rounding is applied to its return
+ // value here, not the value being assigned.
+ case EOpAssign:
+ case EOpAdd:
+ case EOpSub:
+ case EOpMul:
+ case EOpDiv:
+ case EOpVectorTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpMatrixTimesMatrix:
+ {
+ TIntermNode *parent = getParentNode();
+ if (!parentUsesResult(parent, node))
+ {
+ break;
+ }
+ TIntermNode *replacement = createRoundingFunctionCallNode(node);
+ mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
+ break;
+ }
+
+ // Compound assignment cases need to replace the operator with a function call.
+ case EOpAddAssign:
+ {
+ mEmulateCompoundAdd.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType())));
+ TIntermNode *parent = getParentNode();
+ TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "add");
+ mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
+ break;
+ }
+ case EOpSubAssign:
+ {
+ mEmulateCompoundSub.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType())));
+ TIntermNode *parent = getParentNode();
+ TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "sub");
+ mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
+ break;
+ }
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+ {
+ mEmulateCompoundMul.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType())));
+ TIntermNode *parent = getParentNode();
+ TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "mul");
+ mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
+ break;
+ }
+ case EOpDivAssign:
+ {
+ mEmulateCompoundDiv.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType())));
+ TIntermNode *parent = getParentNode();
+ TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "div");
+ mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
+ break;
+ }
+ default:
+ // The rest of the binary operations should not need precision emulation.
+ break;
+ }
+ }
+ return visitChildren;
+}
+
+bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ bool visitChildren = true;
+ switch (node->getOp())
+ {
+ case EOpSequence:
+ case EOpConstructStruct:
+ // No special handling
+ break;
+ case EOpFunction:
+ if (visit == PreVisit)
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ TIntermSequence::const_iterator seqIter = sequence.begin();
+ TIntermAggregate *params = (*seqIter)->getAsAggregate();
+ ASSERT(params != NULL);
+ ASSERT(params->getOp() == EOpParameters);
+ mFunctionMap[node->getName()] = params->getSequence();
+ }
+ break;
+ case EOpPrototype:
+ if (visit == PreVisit)
+ mFunctionMap[node->getName()] = node->getSequence();
+ visitChildren = false;
+ break;
+ case EOpParameters:
+ visitChildren = false;
+ break;
+ case EOpInvariantDeclaration:
+ visitChildren = false;
+ break;
+ case EOpDeclaration:
+ // Variable declaration.
+ if (visit == PreVisit)
+ {
+ mDeclaringVariables = true;
+ }
+ else if (visit == InVisit)
+ {
+ mDeclaringVariables = true;
+ }
+ else
+ {
+ mDeclaringVariables = false;
+ }
+ break;
+ case EOpFunctionCall:
+ {
+ // Function call.
+ bool inFunctionMap = (mFunctionMap.find(node->getName()) != mFunctionMap.end());
+ if (visit == PreVisit)
+ {
+ // User-defined function return values are not rounded, this relies on that
+ // calculations producing the value were rounded.
+ TIntermNode *parent = getParentNode();
+ if (canRoundFloat(node->getType()) && !inFunctionMap && parentUsesResult(parent, node))
+ {
+ TIntermNode *replacement = createRoundingFunctionCallNode(node);
+ mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
+ }
+
+ if (inFunctionMap)
+ {
+ mSeqIterStack.push_back(mFunctionMap[node->getName()]->begin());
+ if (mSeqIterStack.back() != mFunctionMap[node->getName()]->end())
+ {
+ TQualifier qualifier = (*mSeqIterStack.back())->getAsTyped()->getQualifier();
+ mInFunctionCallOutParameter = (qualifier == EvqOut || qualifier == EvqInOut);
+ }
+ }
+ else
+ {
+ // The function is not user-defined - it is likely built-in texture function.
+ // Assume that those do not have out parameters.
+ mInFunctionCallOutParameter = false;
+ }
+ }
+ else if (visit == InVisit)
+ {
+ if (inFunctionMap)
+ {
+ ++mSeqIterStack.back();
+ TQualifier qualifier = (*mSeqIterStack.back())->getAsTyped()->getQualifier();
+ mInFunctionCallOutParameter = (qualifier == EvqOut || qualifier == EvqInOut);
+ }
+ }
+ else
+ {
+ if (inFunctionMap)
+ {
+ mSeqIterStack.pop_back();
+ mInFunctionCallOutParameter = false;
+ }
+ }
+ break;
+ }
+ default:
+ TIntermNode *parent = getParentNode();
+ if (canRoundFloat(node->getType()) && visit == PreVisit && parentUsesResult(parent, node))
+ {
+ TIntermNode *replacement = createRoundingFunctionCallNode(node);
+ mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
+ }
+ break;
+ }
+ return visitChildren;
+}
+
+bool EmulatePrecision::visitUnary(Visit visit, TIntermUnary *node)
+{
+ switch (node->getOp())
+ {
+ case EOpNegative:
+ case EOpVectorLogicalNot:
+ case EOpLogicalNot:
+ break;
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+ if (visit == PreVisit)
+ mInLValue = true;
+ else if (visit == PostVisit)
+ mInLValue = false;
+ break;
+ default:
+ if (canRoundFloat(node->getType()) && visit == PreVisit)
+ {
+ TIntermNode *parent = getParentNode();
+ TIntermNode *replacement = createRoundingFunctionCallNode(node);
+ mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
+ }
+ break;
+ }
+
+ return true;
+}
+
+void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage)
+{
+ // Other languages not yet supported
+ ASSERT(outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT ||
+ outputLanguage == SH_GLSL_CORE_OUTPUT ||
+ outputLanguage == SH_ESSL_OUTPUT);
+ writeCommonPrecisionEmulationHelpers(sink, outputLanguage);
+
+ EmulationSet::const_iterator it;
+ for (it = mEmulateCompoundAdd.begin(); it != mEmulateCompoundAdd.end(); it++)
+ writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "+", "add");
+ for (it = mEmulateCompoundSub.begin(); it != mEmulateCompoundSub.end(); it++)
+ writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "-", "sub");
+ for (it = mEmulateCompoundDiv.begin(); it != mEmulateCompoundDiv.end(); it++)
+ writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "/", "div");
+ for (it = mEmulateCompoundMul.begin(); it != mEmulateCompoundMul.end(); it++)
+ writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "*", "mul");
+}
+
diff --git a/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.h b/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.h
new file mode 100644
index 0000000000..f1f560aa85
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.h
@@ -0,0 +1,74 @@
+//
+// Copyright (c) 2002-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_EMULATE_PRECISION_H_
+#define COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/IntermNode.h"
+#include "GLSLANG/ShaderLang.h"
+
+// This class gathers all compound assignments from the AST and can then write
+// the functions required for their precision emulation. This way there is no
+// need to write a huge number of variations of the emulated compound assignment
+// to every translated shader with emulation enabled.
+
+class EmulatePrecision : public TIntermTraverser
+{
+ public:
+ EmulatePrecision();
+
+ virtual void visitSymbol(TIntermSymbol *node);
+ virtual bool visitBinary(Visit visit, TIntermBinary *node);
+ virtual bool visitUnary(Visit visit, TIntermUnary *node);
+ virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
+
+ void writeEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage);
+
+ private:
+ struct TypePair
+ {
+ TypePair(const char *l, const char *r)
+ : lType(l), rType(r) { }
+
+ const char *lType;
+ const char *rType;
+ };
+
+ struct TypePairComparator
+ {
+ bool operator() (const TypePair& l, const TypePair& r) const
+ {
+ if (l.lType == r.lType)
+ return l.rType < r.rType;
+ return l.lType < r.lType;
+ }
+ };
+
+ typedef std::set<TypePair, TypePairComparator> EmulationSet;
+ EmulationSet mEmulateCompoundAdd;
+ EmulationSet mEmulateCompoundSub;
+ EmulationSet mEmulateCompoundMul;
+ EmulationSet mEmulateCompoundDiv;
+
+ // Stack of function call parameter iterators
+ std::vector<TIntermSequence::const_iterator> mSeqIterStack;
+
+ bool mDeclaringVariables;
+ bool mInLValue;
+ bool mInFunctionCallOutParameter;
+
+ struct TStringComparator
+ {
+ bool operator() (const TString& a, const TString& b) const { return a.compare(b) < 0; }
+ };
+
+ // Map from function names to their parameter sequences
+ std::map<TString, TIntermSequence*, TStringComparator> mFunctionMap;
+};
+
+#endif // COMPILER_TRANSLATOR_EMULATE_PRECISION_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.h b/src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.h
index 5c1595fb21..cf4d7fba31 100644
--- a/src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.h
+++ b/src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef _EXTENSION_BEHAVIOR_INCLUDED_
-#define _EXTENSION_BEHAVIOR_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
+#define COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
#include <map>
#include <string>
@@ -34,4 +34,4 @@ inline const char* getBehaviorString(TBehavior b)
// Mapping between extension name and behavior.
typedef std::map<std::string, TBehavior> TExtensionBehavior;
-#endif // _EXTENSION_TABLE_INCLUDED_
+#endif // COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.h b/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.h
index c93a6f808e..07b9a72c5c 100644
--- a/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.h
+++ b/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_FLAGSTD140STRUCTS_H_
-#define COMPILER_FLAGSTD140STRUCTS_H_
+#ifndef COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
+#define COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
#include "compiler/translator/IntermNode.h"
@@ -34,4 +34,4 @@ std::vector<TIntermTyped *> FlagStd140ValueStructs(TIntermNode *node);
}
-#endif // COMPILER_FLAGSTD140STRUCTS_H_
+#endif // COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.h b/src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.h
index a820d2a20d..c8787d55a0 100644
--- a/src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.h
+++ b/src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_FORLOOPUNROLL_H_
-#define COMPILER_FORLOOPUNROLL_H_
+#ifndef COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
+#define COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
#include "compiler/translator/LoopInfo.h"
@@ -47,4 +47,4 @@ class ForLoopUnrollMarker : public TIntermTraverser
bool mVisitSamplerArrayIndexNodeInsideLoop;
};
-#endif
+#endif // COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/HashNames.h b/src/3rdparty/angle/src/compiler/translator/HashNames.h
index 26546a3e7b..09c959f9da 100644
--- a/src/3rdparty/angle/src/compiler/translator/HashNames.h
+++ b/src/3rdparty/angle/src/compiler/translator/HashNames.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_HASH_NAMES_H_
-#define COMPILER_HASH_NAMES_H_
+#ifndef COMPILER_TRANSLATOR_HASHNAMES_H_
+#define COMPILER_TRANSLATOR_HASHNAMES_H_
#include <map>
@@ -15,4 +15,4 @@
typedef std::map<TPersistString, TPersistString> NameMap;
-#endif // COMPILER_HASH_NAMES_H_
+#endif // COMPILER_TRANSLATOR_HASHNAMES_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/InfoSink.h b/src/3rdparty/angle/src/compiler/translator/InfoSink.h
index 698a8b454b..f47fafa8ee 100644
--- a/src/3rdparty/angle/src/compiler/translator/InfoSink.h
+++ b/src/3rdparty/angle/src/compiler/translator/InfoSink.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef _INFOSINK_INCLUDED_
-#define _INFOSINK_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_INFOSINK_H_
+#define COMPILER_TRANSLATOR_INFOSINK_H_
#include <math.h>
#include <stdlib.h>
@@ -113,4 +113,4 @@ public:
TInfoSinkBase obj;
};
-#endif // _INFOSINK_INCLUDED_
+#endif // COMPILER_TRANSLATOR_INFOSINK_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/Initialize.cpp b/src/3rdparty/angle/src/compiler/translator/Initialize.cpp
index 10b21e6d28..9e11405758 100644
--- a/src/3rdparty/angle/src/compiler/translator/Initialize.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/Initialize.cpp
@@ -21,307 +21,208 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
TType *float2 = new TType(EbtFloat, 2);
TType *float3 = new TType(EbtFloat, 3);
TType *float4 = new TType(EbtFloat, 4);
-
TType *int1 = new TType(EbtInt);
TType *int2 = new TType(EbtInt, 2);
TType *int3 = new TType(EbtInt, 3);
- TType *int4 = new TType(EbtInt, 4);
+ TType *uint1 = new TType(EbtUInt);
+ TType *bool1 = new TType(EbtBool);
+ TType *genType = new TType(EbtGenType);
+ TType *genIType = new TType(EbtGenIType);
+ TType *genUType = new TType(EbtGenUType);
+ TType *genBType = new TType(EbtGenBType);
//
// Angle and Trigonometric Functions.
//
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "radians", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "radians", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "radians", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "radians", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "degrees", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "degrees", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "degrees", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "degrees", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "sin", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "sin", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "sin", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "sin", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "cos", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "cos", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "cos", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "cos", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "tan", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "tan", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "tan", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "tan", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "asin", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "asin", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "asin", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "asin", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "acos", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "acos", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "acos", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "acos", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "atan", float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "atan", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "atan", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "atan", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "atan", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "atan", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "atan", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "atan", float4);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpRadians, genType, "radians", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDegrees, genType, "degrees", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSin, genType, "sin", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCos, genType, "cos", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpTan, genType, "tan", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAsin, genType, "asin", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAcos, genType, "acos", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAtan, genType, "atan", genType, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAtan, genType, "atan", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpSinh, genType, "sinh", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpCosh, genType, "cosh", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTanh, genType, "tanh", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAsinh, genType, "asinh", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAcosh, genType, "acosh", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAtanh, genType, "atanh", genType);
//
// Exponential Functions.
//
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "pow", float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "pow", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "pow", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "pow", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "exp", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "exp", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "exp", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "exp", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "log", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "log", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "log", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "log", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "exp2", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "exp2", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "exp2", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "exp2", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "log2", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "log2", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "log2", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "log2", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "sqrt", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "sqrt", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "sqrt", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "sqrt", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "inversesqrt", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "inversesqrt", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "inversesqrt", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "inversesqrt", float4);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpPow, genType, "pow", genType, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpExp, genType, "exp", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLog, genType, "log", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpExp2, genType, "exp2", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLog2, genType, "log2", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSqrt, genType, "sqrt", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpInverseSqrt, genType, "inversesqrt", genType);
//
// Common Functions.
//
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "abs", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "abs", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "abs", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "abs", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "sign", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "sign", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "sign", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "sign", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "floor", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "floor", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "floor", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "floor", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "ceil", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "ceil", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "ceil", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "ceil", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "fract", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "fract", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "fract", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "fract", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "mod", float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mod", float2, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mod", float3, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mod", float4, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mod", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mod", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mod", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "min", float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "min", float2, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "min", float3, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "min", float4, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "min", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "min", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "min", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "max", float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "max", float2, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "max", float3, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "max", float4, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "max", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "max", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "max", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "clamp", float1, float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "clamp", float2, float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "clamp", float3, float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "clamp", float4, float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "clamp", float2, float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "clamp", float3, float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "clamp", float4, float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "mix", float1, float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mix", float2, float2, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mix", float3, float3, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mix", float4, float4, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "mix", float2, float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "mix", float3, float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "mix", float4, float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "step", float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "step", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "step", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "step", float4, float4);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "step", float1, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "step", float1, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "step", float1, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "smoothstep", float1, float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "smoothstep", float2, float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "smoothstep", float3, float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "smoothstep", float4, float4, float4);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "smoothstep", float1, float1, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "smoothstep", float1, float1, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "smoothstep", float1, float1, float4);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAbs, genType, "abs", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAbs, genIType, "abs", genIType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSign, genType, "sign", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpSign, genIType, "sign", genIType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFloor, genType, "floor", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTrunc, genType, "trunc", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRound, genType, "round", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRoundEven, genType, "roundEven", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCeil, genType, "ceil", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFract, genType, "fract", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMod, genType, "mod", genType, float1);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMod, genType, "mod", genType, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMin, genType, "min", genType, float1);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMin, genType, "min", genType, genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genIType, "min", genIType, genIType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genIType, "min", genIType, int1);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genUType, "min", genUType, genUType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genUType, "min", genUType, uint1);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMax, genType, "max", genType, float1);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMax, genType, "max", genType, genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genIType, "max", genIType, genIType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genIType, "max", genIType, int1);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genUType, "max", genUType, genUType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genUType, "max", genUType, uint1);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpClamp, genType, "clamp", genType, float1, float1);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpClamp, genType, "clamp", genType, genType, genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genIType, "clamp", genIType, int1, int1);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genIType, "clamp", genIType, genIType, genIType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, uint1, uint1);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, genUType, genUType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, float1);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", genType, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", float1, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", genType, genType, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", float1, float1, genType);
+
+ TType *outFloat1 = new TType(EbtFloat);
+ TType *outFloat2 = new TType(EbtFloat, 2);
+ TType *outFloat3 = new TType(EbtFloat, 3);
+ TType *outFloat4 = new TType(EbtFloat, 4);
+ outFloat1->setQualifier(EvqOut);
+ outFloat2->setQualifier(EvqOut);
+ outFloat3->setQualifier(EvqOut);
+ outFloat4->setQualifier(EvqOut);
+
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float1, "modf", float1, outFloat1);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float2, "modf", float2, outFloat2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float3, "modf", float3, outFloat3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float4, "modf", float4, outFloat4);
+
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsNan, genBType, "isnan", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsInf, genBType, "isinf", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, "floatBitsToInt", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFloatBitsToUint, genUType, "floatBitsToUint", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIntBitsToFloat, genType, "intBitsToFloat", genIType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUintBitsToFloat, genType, "uintBitsToFloat", genUType);
+
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackSnorm2x16, uint1, "packSnorm2x16", float2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackUnorm2x16, uint1, "packUnorm2x16", float2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackHalf2x16, uint1, "packHalf2x16", float2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackSnorm2x16, float2, "unpackSnorm2x16", uint1);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, "unpackUnorm2x16", uint1);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, "unpackHalf2x16", uint1);
//
// Geometric Functions.
//
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "length", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "distance", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "dot", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "cross", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "normalize", float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "normalize", float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "normalize", float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "normalize", float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "faceforward", float1, float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "faceforward", float2, float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "faceforward", float3, float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "faceforward", float4, float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "reflect", float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "reflect", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "reflect", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "reflect", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float1, "refract", float1, float1, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float2, "refract", float2, float2, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float3, "refract", float3, float3, float1);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, float4, "refract", float4, float4, float1);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLength, float1, "length", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDistance, float1, "distance", genType, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDot, float1, "dot", genType, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCross, float3, "cross", float3, float3);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpNormalize, genType, "normalize", genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFaceForward, genType, "faceforward", genType, genType, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpReflect, genType, "reflect", genType, genType);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpRefract, genType, "refract", genType, genType, float1);
TType *mat2 = new TType(EbtFloat, 2, 2);
TType *mat3 = new TType(EbtFloat, 3, 3);
TType *mat4 = new TType(EbtFloat, 4, 4);
+ TType *mat2x3 = new TType(EbtFloat, 2, 3);
+ TType *mat3x2 = new TType(EbtFloat, 3, 2);
+ TType *mat2x4 = new TType(EbtFloat, 2, 4);
+ TType *mat4x2 = new TType(EbtFloat, 4, 2);
+ TType *mat3x4 = new TType(EbtFloat, 3, 4);
+ TType *mat4x3 = new TType(EbtFloat, 4, 3);
//
// Matrix Functions.
//
- symbolTable.insertBuiltIn(COMMON_BUILTINS, mat2, "matrixCompMult", mat2, mat2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, mat3, "matrixCompMult", mat3, mat3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, mat4, "matrixCompMult", mat4, mat4);
-
- TType *bool1 = new TType(EbtBool);
- TType *bool2 = new TType(EbtBool, 2);
- TType *bool3 = new TType(EbtBool, 3);
- TType *bool4 = new TType(EbtBool, 4);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat2, "matrixCompMult", mat2, mat2);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat3, "matrixCompMult", mat3, mat3);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat4, "matrixCompMult", mat4, mat4);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat2x3, "matrixCompMult", mat2x3, mat2x3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat3x2, "matrixCompMult", mat3x2, mat3x2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat2x4, "matrixCompMult", mat2x4, mat2x4);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat4x2, "matrixCompMult", mat4x2, mat4x2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat3x4, "matrixCompMult", mat3x4, mat3x4);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat4x3, "matrixCompMult", mat4x3, mat4x3);
+
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2, "outerProduct", float2, float2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3, "outerProduct", float3, float3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4, "outerProduct", float4, float4);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2x3, "outerProduct", float3, float2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3x2, "outerProduct", float2, float3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2x4, "outerProduct", float4, float2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4x2, "outerProduct", float2, float4);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3x4, "outerProduct", float4, float3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4x3, "outerProduct", float3, float4);
+
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2, "transpose", mat2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3, "transpose", mat3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4, "transpose", mat4);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2x3, "transpose", mat3x2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3x2, "transpose", mat2x3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2x4, "transpose", mat4x2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4x2, "transpose", mat2x4);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3x4, "transpose", mat4x3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4x3, "transpose", mat3x4);
+
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat4);
+
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat2, "inverse", mat2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat3, "inverse", mat3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat4, "inverse", mat4);
+
+ TType *vec = new TType(EbtVec);
+ TType *ivec = new TType(EbtIVec);
+ TType *uvec = new TType(EbtUVec);
+ TType *bvec = new TType(EbtBVec);
//
// Vector relational functions.
//
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThan", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThan", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThan", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThan", int2, int2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThan", int3, int3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThan", int4, int4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThanEqual", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThanEqual", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThanEqual", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "lessThanEqual", int2, int2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "lessThanEqual", int3, int3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "lessThanEqual", int4, int4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThan", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThan", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThan", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThan", int2, int2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThan", int3, int3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThan", int4, int4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThanEqual", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThanEqual", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThanEqual", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "greaterThanEqual", int2, int2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "greaterThanEqual", int3, int3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "greaterThanEqual", int4, int4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "equal", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "equal", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "equal", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "equal", int2, int2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "equal", int3, int3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "equal", int4, int4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "equal", bool2, bool2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "equal", bool3, bool3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "equal", bool4, bool4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "notEqual", float2, float2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "notEqual", float3, float3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "notEqual", float4, float4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "notEqual", int2, int2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "notEqual", int3, int3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "notEqual", int4, int4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "notEqual", bool2, bool2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "notEqual", bool3, bool3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "notEqual", bool4, bool4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "any", bool2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "any", bool3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "any", bool4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "all", bool2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "all", bool3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool1, "all", bool4);
-
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool2, "not", bool2);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool3, "not", bool3);
- symbolTable.insertBuiltIn(COMMON_BUILTINS, bool4, "not", bool4);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThan, bvec, "lessThan", vec, vec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThan, bvec, "lessThan", ivec, ivec);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpLessThan, bvec, "lessThan", uvec, uvec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", vec, vec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", ivec, ivec);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", uvec, uvec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThan, bvec, "greaterThan", vec, vec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThan, bvec, "greaterThan", ivec, ivec);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpGreaterThan, bvec, "greaterThan", uvec, uvec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", vec, vec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", ivec, ivec);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", uvec, uvec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", vec, vec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", ivec, ivec);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpVectorEqual, bvec, "equal", uvec, uvec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", bvec, bvec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", vec, vec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", ivec, ivec);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", uvec, uvec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", bvec, bvec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAny, bool1, "any", bvec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAll, bool1, "all", bvec);
+ symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorLogicalNot, bvec, "not", bvec);
TType *sampler2D = new TType(EbtSampler2D);
TType *samplerCube = new TType(EbtSamplerCube);
@@ -357,10 +258,10 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
/* The *Grad* variants are new to both vertex and fragment shaders; the fragment
* shader specific pieces are added separately below.
*/
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DGradEXT", sampler2D, float2, float2, float2);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjGradEXT", sampler2D, float3, float2, float2);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjGradEXT", sampler2D, float4, float2, float2);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeGradEXT", samplerCube, float3, float3, float3);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DGradEXT", sampler2D, float2, float2, float2);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjGradEXT", sampler2D, float3, float2, float2);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjGradEXT", sampler2D, float4, float2, float2);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "textureCubeGradEXT", samplerCube, float3, float3, float3);
}
if (type == GL_FRAGMENT_SHADER)
@@ -372,32 +273,21 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
if (resources.OES_standard_derivatives)
{
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float1, "dFdx", float1);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float2, "dFdx", float2);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float3, "dFdx", float3);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "dFdx", float4);
-
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float1, "dFdy", float1);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float2, "dFdy", float2);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float3, "dFdy", float3);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "dFdy", float4);
-
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float1, "fwidth", float1);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float2, "fwidth", float2);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float3, "fwidth", float3);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "fwidth", float4);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, EOpDFdx, "GL_OES_standard_derivatives", genType, "dFdx", genType);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, EOpDFdy, "GL_OES_standard_derivatives", genType, "dFdy", genType);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, EOpFwidth, "GL_OES_standard_derivatives", genType, "fwidth", genType);
}
if (resources.EXT_shader_texture_lod)
{
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLodEXT", sampler2D, float2, float1);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLodEXT", sampler2D, float3, float1);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLodEXT", sampler2D, float4, float1);
- symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLodEXT", samplerCube, float3, float1);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DLodEXT", sampler2D, float2, float1);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjLodEXT", sampler2D, float3, float1);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjLodEXT", sampler2D, float4, float1);
+ symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "textureCubeLodEXT", samplerCube, float3, float1);
}
}
- if(type == GL_VERTEX_SHADER)
+ if (type == GL_VERTEX_SHADER)
{
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLod", sampler2D, float2, float1);
symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float3, float1);
@@ -463,22 +353,11 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1);
- if(type == GL_FRAGMENT_SHADER)
+ if (type == GL_FRAGMENT_SHADER)
{
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "dFdx", float1);
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float2, "dFdx", float2);
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float3, "dFdx", float3);
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "dFdx", float4);
-
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "dFdy", float1);
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float2, "dFdy", float2);
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float3, "dFdy", float3);
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "dFdy", float4);
-
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "fwidth", float1);
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float2, "fwidth", float2);
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float3, "fwidth", float3);
- symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "fwidth", float4);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDFdx, genType, "dFdx", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDFdy, genType, "dFdy", genType);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFwidth, genType, "fwidth", genType);
}
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2);
@@ -486,7 +365,7 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2);
- if(type == GL_FRAGMENT_SHADER)
+ if (type == GL_FRAGMENT_SHADER)
{
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3, float1);
@@ -499,7 +378,7 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2);
- if(type == GL_FRAGMENT_SHADER)
+ if (type == GL_FRAGMENT_SHADER)
{
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2, float1);
@@ -600,146 +479,84 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
TSymbolTable &symbolTable)
{
//
- // First, insert some special built-in variables that are not in
+ // Insert some special built-in variables that are not in
// the built-in header files.
//
- switch(type) {
- case GL_FRAGMENT_SHADER:
- symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
- symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
- symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
+ switch (type)
+ {
+ case GL_FRAGMENT_SHADER:
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"),
+ TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"),
+ TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"),
+ TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
//
// In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available.
// Instead, css_MixColor and css_ColorMatrix are available.
//
- if (spec != SH_CSS_SHADERS_SPEC) {
- symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
- symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4)));
- if (resources.EXT_frag_depth) {
- symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragDepthEXT"), TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
- symbolTable.relateToExtension(ESSL1_BUILTINS, "gl_FragDepthEXT", "GL_EXT_frag_depth");
- }
- } else {
- symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_MixColor"), TType(EbtFloat, EbpMedium, EvqGlobal, 4)));
- symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_ColorMatrix"), TType(EbtFloat, EbpMedium, EvqGlobal, 4, 4)));
- }
-
- break;
-
- case GL_VERTEX_SHADER:
- symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4)));
- symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
- break;
-
- default: assert(false && "Language not supported");
- }
-
- //
- // Next, identify which built-ins from the already loaded headers have
- // a mapping to an operator. Those that are not identified as such are
- // expected to be resolved through a library of functions, versus as
- // operations.
- //
- symbolTable.relateToOperator(COMMON_BUILTINS, "matrixCompMult", EOpMul);
-
- symbolTable.relateToOperator(COMMON_BUILTINS, "equal", EOpVectorEqual);
- symbolTable.relateToOperator(COMMON_BUILTINS, "notEqual", EOpVectorNotEqual);
- symbolTable.relateToOperator(COMMON_BUILTINS, "lessThan", EOpLessThan);
- symbolTable.relateToOperator(COMMON_BUILTINS, "greaterThan", EOpGreaterThan);
- symbolTable.relateToOperator(COMMON_BUILTINS, "lessThanEqual", EOpLessThanEqual);
- symbolTable.relateToOperator(COMMON_BUILTINS, "greaterThanEqual", EOpGreaterThanEqual);
-
- symbolTable.relateToOperator(COMMON_BUILTINS, "radians", EOpRadians);
- symbolTable.relateToOperator(COMMON_BUILTINS, "degrees", EOpDegrees);
- symbolTable.relateToOperator(COMMON_BUILTINS, "sin", EOpSin);
- symbolTable.relateToOperator(COMMON_BUILTINS, "cos", EOpCos);
- symbolTable.relateToOperator(COMMON_BUILTINS, "tan", EOpTan);
- symbolTable.relateToOperator(COMMON_BUILTINS, "asin", EOpAsin);
- symbolTable.relateToOperator(COMMON_BUILTINS, "acos", EOpAcos);
- symbolTable.relateToOperator(COMMON_BUILTINS, "atan", EOpAtan);
-
- symbolTable.relateToOperator(COMMON_BUILTINS, "pow", EOpPow);
- symbolTable.relateToOperator(COMMON_BUILTINS, "exp2", EOpExp2);
- symbolTable.relateToOperator(COMMON_BUILTINS, "log", EOpLog);
- symbolTable.relateToOperator(COMMON_BUILTINS, "exp", EOpExp);
- symbolTable.relateToOperator(COMMON_BUILTINS, "log2", EOpLog2);
- symbolTable.relateToOperator(COMMON_BUILTINS, "sqrt", EOpSqrt);
- symbolTable.relateToOperator(COMMON_BUILTINS, "inversesqrt", EOpInverseSqrt);
-
- symbolTable.relateToOperator(COMMON_BUILTINS, "abs", EOpAbs);
- symbolTable.relateToOperator(COMMON_BUILTINS, "sign", EOpSign);
- symbolTable.relateToOperator(COMMON_BUILTINS, "floor", EOpFloor);
- symbolTable.relateToOperator(COMMON_BUILTINS, "ceil", EOpCeil);
- symbolTable.relateToOperator(COMMON_BUILTINS, "fract", EOpFract);
- symbolTable.relateToOperator(COMMON_BUILTINS, "mod", EOpMod);
- symbolTable.relateToOperator(COMMON_BUILTINS, "min", EOpMin);
- symbolTable.relateToOperator(COMMON_BUILTINS, "max", EOpMax);
- symbolTable.relateToOperator(COMMON_BUILTINS, "clamp", EOpClamp);
- symbolTable.relateToOperator(COMMON_BUILTINS, "mix", EOpMix);
- symbolTable.relateToOperator(COMMON_BUILTINS, "step", EOpStep);
- symbolTable.relateToOperator(COMMON_BUILTINS, "smoothstep", EOpSmoothStep);
-
- symbolTable.relateToOperator(COMMON_BUILTINS, "length", EOpLength);
- symbolTable.relateToOperator(COMMON_BUILTINS, "distance", EOpDistance);
- symbolTable.relateToOperator(COMMON_BUILTINS, "dot", EOpDot);
- symbolTable.relateToOperator(COMMON_BUILTINS, "cross", EOpCross);
- symbolTable.relateToOperator(COMMON_BUILTINS, "normalize", EOpNormalize);
- symbolTable.relateToOperator(COMMON_BUILTINS, "faceforward", EOpFaceForward);
- symbolTable.relateToOperator(COMMON_BUILTINS, "reflect", EOpReflect);
- symbolTable.relateToOperator(COMMON_BUILTINS, "refract", EOpRefract);
-
- symbolTable.relateToOperator(COMMON_BUILTINS, "any", EOpAny);
- symbolTable.relateToOperator(COMMON_BUILTINS, "all", EOpAll);
- symbolTable.relateToOperator(COMMON_BUILTINS, "not", EOpVectorLogicalNot);
-
- // Map language-specific operators.
- switch(type) {
- case GL_VERTEX_SHADER:
- break;
- case GL_FRAGMENT_SHADER:
- if (resources.OES_standard_derivatives)
+ if (spec != SH_CSS_SHADERS_SPEC)
{
- symbolTable.relateToOperator(ESSL1_BUILTINS, "dFdx", EOpDFdx);
- symbolTable.relateToOperator(ESSL1_BUILTINS, "dFdy", EOpDFdy);
- symbolTable.relateToOperator(ESSL1_BUILTINS, "fwidth", EOpFwidth);
+ symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"),
+ TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
+ TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
+ fragData.setArraySize(resources.MaxDrawBuffers);
+ symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
+
+ if (resources.EXT_frag_depth)
+ {
+ symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_frag_depth", new TVariable(NewPoolTString("gl_FragDepthEXT"),
+ TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
+ }
- symbolTable.relateToExtension(ESSL1_BUILTINS, "dFdx", "GL_OES_standard_derivatives");
- symbolTable.relateToExtension(ESSL1_BUILTINS, "dFdy", "GL_OES_standard_derivatives");
- symbolTable.relateToExtension(ESSL1_BUILTINS, "fwidth", "GL_OES_standard_derivatives");
+ if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
+ {
+ TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true);
+ lastFragData.setArraySize(resources.MaxDrawBuffers);
+
+ if (resources.EXT_shader_framebuffer_fetch)
+ {
+ symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_shader_framebuffer_fetch",
+ new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
+ }
+ else if (resources.NV_shader_framebuffer_fetch)
+ {
+ symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
+ new TVariable(NewPoolTString("gl_LastFragColor"),
+ TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
+ symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch",
+ new TVariable(NewPoolTString("gl_LastFragData"), lastFragData));
+ }
+ }
+ else if (resources.ARM_shader_framebuffer_fetch)
+ {
+ symbolTable.insert(ESSL1_BUILTINS, "GL_ARM_shader_framebuffer_fetch",
+ new TVariable(NewPoolTString("gl_LastFragColorARM"),
+ TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)));
+ }
}
- if (resources.EXT_shader_texture_lod)
+ else
{
- symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DLodEXT", "GL_EXT_shader_texture_lod");
- symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DProjLodEXT", "GL_EXT_shader_texture_lod");
- symbolTable.relateToExtension(ESSL1_BUILTINS, "textureCubeLodEXT", "GL_EXT_shader_texture_lod");
+ symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_MixColor"),
+ TType(EbtFloat, EbpMedium, EvqGlobal, 4)));
+ symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_ColorMatrix"),
+ TType(EbtFloat, EbpMedium, EvqGlobal, 4, 4)));
}
- break;
- default: break;
- }
- symbolTable.relateToOperator(ESSL3_BUILTINS, "dFdx", EOpDFdx);
- symbolTable.relateToOperator(ESSL3_BUILTINS, "dFdy", EOpDFdy);
- symbolTable.relateToOperator(ESSL3_BUILTINS, "fwidth", EOpFwidth);
-
- if (resources.EXT_shader_texture_lod)
- {
- symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DGradEXT", "GL_EXT_shader_texture_lod");
- symbolTable.relateToExtension(ESSL1_BUILTINS, "texture2DProjGradEXT", "GL_EXT_shader_texture_lod");
- symbolTable.relateToExtension(ESSL1_BUILTINS, "textureCubeGradEXT", "GL_EXT_shader_texture_lod");
- }
+ break;
- // Finally add resource-specific variables.
- switch(type) {
- case GL_FRAGMENT_SHADER:
- if (spec != SH_CSS_SHADERS_SPEC) {
- // Set up gl_FragData. The array size.
- TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
- fragData.setArraySize(resources.MaxDrawBuffers);
- symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
- }
+ case GL_VERTEX_SHADER:
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_Position"),
+ TType(EbtFloat, EbpHigh, EvqPosition, 4)));
+ symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointSize"),
+ TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
+ symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_InstanceID"),
+ TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
break;
- default: break;
+
+ default:
+ assert(false && "Language not supported");
}
}
@@ -758,4 +575,20 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
extBehavior["GL_EXT_frag_depth"] = EBhUndefined;
if (resources.EXT_shader_texture_lod)
extBehavior["GL_EXT_shader_texture_lod"] = EBhUndefined;
+ if (resources.EXT_shader_framebuffer_fetch)
+ extBehavior["GL_EXT_shader_framebuffer_fetch"] = EBhUndefined;
+ if (resources.NV_shader_framebuffer_fetch)
+ extBehavior["GL_NV_shader_framebuffer_fetch"] = EBhUndefined;
+ if (resources.ARM_shader_framebuffer_fetch)
+ extBehavior["GL_ARM_shader_framebuffer_fetch"] = EBhUndefined;
+}
+
+void ResetExtensionBehavior(TExtensionBehavior &extBehavior)
+{
+ for (auto ext_iter = extBehavior.begin();
+ ext_iter != extBehavior.end();
+ ++ext_iter)
+ {
+ ext_iter->second = EBhUndefined;
+ }
}
diff --git a/src/3rdparty/angle/src/compiler/translator/Initialize.h b/src/3rdparty/angle/src/compiler/translator/Initialize.h
index cc1862c90e..c43ce3417a 100644
--- a/src/3rdparty/angle/src/compiler/translator/Initialize.h
+++ b/src/3rdparty/angle/src/compiler/translator/Initialize.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef _INITIALIZE_INCLUDED_
-#define _INITIALIZE_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_INITIALIZE_H_
+#define COMPILER_TRANSLATOR_INITIALIZE_H_
#include "compiler/translator/Common.h"
#include "compiler/translator/Compiler.h"
@@ -20,4 +20,10 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
void InitExtensionBehavior(const ShBuiltInResources& resources,
TExtensionBehavior& extensionBehavior);
-#endif // _INITIALIZE_INCLUDED_
+// 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(TExtensionBehavior &extensionBehavior);
+
+#endif // COMPILER_TRANSLATOR_INITIALIZE_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/InitializeDll.h b/src/3rdparty/angle/src/compiler/translator/InitializeDll.h
index 43070cc3ff..4c400760f6 100644
--- a/src/3rdparty/angle/src/compiler/translator/InitializeDll.h
+++ b/src/3rdparty/angle/src/compiler/translator/InitializeDll.h
@@ -3,11 +3,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-#ifndef __INITIALIZEDLL_H
-#define __INITIALIZEDLL_H
+#ifndef COMPILER_TRANSLATOR_INITIALIZEDLL_H_
+#define COMPILER_TRANSLATOR_INITIALIZEDLL_H_
bool InitProcess();
void DetachProcess();
-#endif // __INITIALIZEDLL_H
+#endif // COMPILER_TRANSLATOR_INITIALIZEDLL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/InitializeGlobals.h b/src/3rdparty/angle/src/compiler/translator/InitializeGlobals.h
index 0715941424..8c65cb28da 100644
--- a/src/3rdparty/angle/src/compiler/translator/InitializeGlobals.h
+++ b/src/3rdparty/angle/src/compiler/translator/InitializeGlobals.h
@@ -4,10 +4,10 @@
// found in the LICENSE file.
//
-#ifndef __INITIALIZE_GLOBALS_INCLUDED_
-#define __INITIALIZE_GLOBALS_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_
+#define COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_
bool InitializePoolIndex();
void FreePoolIndex();
-#endif // __INITIALIZE_GLOBALS_INCLUDED_
+#endif // COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/InitializeParseContext.h b/src/3rdparty/angle/src/compiler/translator/InitializeParseContext.h
index bffbab87d0..fa9b885e80 100644
--- a/src/3rdparty/angle/src/compiler/translator/InitializeParseContext.h
+++ b/src/3rdparty/angle/src/compiler/translator/InitializeParseContext.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef __INITIALIZE_PARSE_CONTEXT_INCLUDED_
-#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
+#define COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
bool InitializeParseContextIndex();
void FreeParseContextIndex();
@@ -14,4 +14,4 @@ struct TParseContext;
extern void SetGlobalParseContext(TParseContext* context);
extern TParseContext* GetGlobalParseContext();
-#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
+#endif // COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/InitializeVariables.h b/src/3rdparty/angle/src/compiler/translator/InitializeVariables.h
index 59c3ea0a39..4a81266498 100644
--- a/src/3rdparty/angle/src/compiler/translator/InitializeVariables.h
+++ b/src/3rdparty/angle/src/compiler/translator/InitializeVariables.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_INITIALIZE_VARIABLES_H_
-#define COMPILER_INITIALIZE_VARIABLES_H_
+#ifndef COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
+#define COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
#include "compiler/translator/IntermNode.h"
@@ -47,4 +47,4 @@ class InitializeVariables : public TIntermTraverser
bool mCodeInserted;
};
-#endif // COMPILER_INITIALIZE_VARIABLES_H_
+#endif // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp b/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp
index aa0f31d170..266e3c8e3d 100644
--- a/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp
@@ -157,26 +157,6 @@ bool TIntermLoop::replaceChildNode(
return false;
}
-void TIntermLoop::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
-{
- if (mInit)
- {
- nodeQueue->push(mInit);
- }
- if (mCond)
- {
- nodeQueue->push(mCond);
- }
- if (mExpr)
- {
- nodeQueue->push(mExpr);
- }
- if (mBody)
- {
- nodeQueue->push(mBody);
- }
-}
-
bool TIntermBranch::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -184,14 +164,6 @@ bool TIntermBranch::replaceChildNode(
return false;
}
-void TIntermBranch::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
-{
- if (mExpression)
- {
- nodeQueue->push(mExpression);
- }
-}
-
bool TIntermBinary::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -200,18 +172,6 @@ bool TIntermBinary::replaceChildNode(
return false;
}
-void TIntermBinary::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
-{
- if (mLeft)
- {
- nodeQueue->push(mLeft);
- }
- if (mRight)
- {
- nodeQueue->push(mRight);
- }
-}
-
bool TIntermUnary::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -219,14 +179,6 @@ bool TIntermUnary::replaceChildNode(
return false;
}
-void TIntermUnary::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
-{
- if (mOperand)
- {
- nodeQueue->push(mOperand);
- }
-}
-
bool TIntermAggregate::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -237,14 +189,6 @@ bool TIntermAggregate::replaceChildNode(
return false;
}
-void TIntermAggregate::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
-{
- for (size_t childIndex = 0; childIndex < mSequence.size(); childIndex++)
- {
- nodeQueue->push(mSequence[childIndex]);
- }
-}
-
void TIntermAggregate::setPrecisionFromChildren()
{
if (getBasicType() == EbtBool)
@@ -300,20 +244,19 @@ bool TIntermSelection::replaceChildNode(
return false;
}
-void TIntermSelection::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const
+bool TIntermSwitch::replaceChildNode(
+ TIntermNode *original, TIntermNode *replacement)
{
- if (mCondition)
- {
- nodeQueue->push(mCondition);
- }
- if (mTrueBlock)
- {
- nodeQueue->push(mTrueBlock);
- }
- if (mFalseBlock)
- {
- nodeQueue->push(mFalseBlock);
- }
+ REPLACE_IF_IS(mInit, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mStatementList, TIntermAggregate, original, replacement);
+ return false;
+}
+
+bool TIntermCase::replaceChildNode(
+ TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
+ return false;
}
//
@@ -336,6 +279,12 @@ bool TIntermOperator::isAssignment() const
case EOpMatrixTimesScalarAssign:
case EOpMatrixTimesMatrixAssign:
case EOpDivAssign:
+ case EOpIModAssign:
+ case EOpBitShiftLeftAssign:
+ case EOpBitShiftRightAssign:
+ case EOpBitwiseAndAssign:
+ case EOpBitwiseXorAssign:
+ case EOpBitwiseOrAssign:
return true;
default:
return false;
@@ -379,65 +328,55 @@ bool TIntermOperator::isConstructor() const
// Make sure the type of a unary operator is appropriate for its
// combination of operation and operand type.
//
-// Returns false in nothing makes sense.
-//
-bool TIntermUnary::promote(TInfoSink &)
+void TIntermUnary::promote(const TType *funcReturnType)
{
switch (mOp)
{
- case EOpLogicalNot:
- if (mOperand->getBasicType() != EbtBool)
- return false;
+ case EOpFloatBitsToInt:
+ case EOpFloatBitsToUint:
+ case EOpIntBitsToFloat:
+ case EOpUintBitsToFloat:
+ case EOpPackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackUnorm2x16:
+ mType.setPrecision(EbpHigh);
break;
- case EOpNegative:
- case EOpPositive:
- case EOpPostIncrement:
- case EOpPostDecrement:
- case EOpPreIncrement:
- case EOpPreDecrement:
- if (mOperand->getBasicType() == EbtBool)
- return false;
+ case EOpUnpackHalf2x16:
+ mType.setPrecision(EbpMedium);
break;
-
- // operators for built-ins are already type checked against their prototype
- case EOpAny:
- case EOpAll:
- case EOpVectorLogicalNot:
- return true;
-
default:
- if (mOperand->getBasicType() != EbtFloat)
- return false;
+ setType(mOperand->getType());
}
- setType(mOperand->getType());
- mType.setQualifier(EvqTemporary);
+ if (funcReturnType != nullptr)
+ {
+ if (funcReturnType->getBasicType() == EbtBool)
+ {
+ // Bool types should not have precision.
+ setType(*funcReturnType);
+ }
+ else
+ {
+ // Precision of the node has been set based on the operand.
+ setTypePreservePrecision(*funcReturnType);
+ }
+ }
- return true;
+ mType.setQualifier(EvqTemporary);
}
//
// Establishes the type of the resultant operation, as well as
// makes the operator the correct one for the operands.
//
-// Returns false if operator can't work on operands.
+// For lots of operations it should already be established that the operand
+// combination is valid, but returns false if operator can't work on operands.
//
bool TIntermBinary::promote(TInfoSink &infoSink)
{
- // This function only handles scalars, vectors, and matrices.
- if (mLeft->isArray() || mRight->isArray())
- {
- infoSink.info.message(EPrefixInternalError, getLine(),
- "Invalid operation for arrays");
- return false;
- }
-
- // GLSL ES 2.0 does not support implicit type casting.
- // So the basic type should always match.
- if (mLeft->getBasicType() != mRight->getBasicType())
- {
- return false;
- }
+ ASSERT(mLeft->isArray() == mRight->isArray());
//
// Base assumption: just make the type the same as the left
@@ -483,12 +422,9 @@ bool TIntermBinary::promote(TInfoSink &infoSink)
// And and Or operate on conditionals
//
case EOpLogicalAnd:
+ case EOpLogicalXor:
case EOpLogicalOr:
- // Both operands must be of type bool.
- if (mLeft->getBasicType() != EbtBool || mRight->getBasicType() != EbtBool)
- {
- return false;
- }
+ ASSERT(mLeft->getBasicType() == EbtBool && mRight->getBasicType() == EbtBool);
setType(TType(EbtBool, EbpUndefined));
break;
@@ -625,12 +561,28 @@ bool TIntermBinary::promote(TInfoSink &infoSink)
case EOpAssign:
case EOpInitialize:
+ // No more additional checks are needed.
+ ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) &&
+ (mLeft->getSecondarySize() == mRight->getSecondarySize()));
+ break;
case EOpAdd:
case EOpSub:
case EOpDiv:
+ case EOpIMod:
+ case EOpBitShiftLeft:
+ case EOpBitShiftRight:
+ case EOpBitwiseAnd:
+ case EOpBitwiseXor:
+ case EOpBitwiseOr:
case EOpAddAssign:
case EOpSubAssign:
case EOpDivAssign:
+ case EOpIModAssign:
+ case EOpBitShiftLeftAssign:
+ case EOpBitShiftRightAssign:
+ case EOpBitwiseAndAssign:
+ case EOpBitwiseXorAssign:
+ case EOpBitwiseOrAssign:
if ((mLeft->isMatrix() && mRight->isVector()) ||
(mLeft->isVector() && mRight->isMatrix()))
{
@@ -641,13 +593,19 @@ bool TIntermBinary::promote(TInfoSink &infoSink)
if (mLeft->getNominalSize() != mRight->getNominalSize() ||
mLeft->getSecondarySize() != mRight->getSecondarySize())
{
- // If the nominal size of operands do not match:
- // One of them must be scalar.
+ // If the nominal sizes of operands do not match:
+ // One of them must be a scalar.
if (!mLeft->isScalar() && !mRight->isScalar())
return false;
- // Operator cannot be of type pure assignment.
- if (mOp == EOpAssign || mOp == EOpInitialize)
+ // In the case of compound assignment other than multiply-assign,
+ // the right side needs to be a scalar. Otherwise a vector/matrix
+ // would be assigned to a scalar. A scalar can't be shifted by a
+ // vector either.
+ if (!mRight->isScalar() &&
+ (isAssignment() ||
+ mOp == EOpBitShiftLeft ||
+ mOp == EOpBitShiftRight))
return false;
}
@@ -656,6 +614,11 @@ bool TIntermBinary::promote(TInfoSink &infoSink)
mLeft->getSecondarySize(), mRight->getSecondarySize());
setType(TType(basicType, higherPrecision, EvqTemporary,
nominalSize, secondarySize));
+ if (mLeft->isArray())
+ {
+ ASSERT(mLeft->getArraySize() == mRight->getArraySize());
+ mType.setArraySize(mLeft->getArraySize());
+ }
}
break;
@@ -665,11 +628,8 @@ bool TIntermBinary::promote(TInfoSink &infoSink)
case EOpGreaterThan:
case EOpLessThanEqual:
case EOpGreaterThanEqual:
- if ((mLeft->getNominalSize() != mRight->getNominalSize()) ||
- (mLeft->getSecondarySize() != mRight->getSecondarySize()))
- {
- return false;
- }
+ ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) &&
+ (mLeft->getSecondarySize() == mRight->getSecondarySize()));
setType(TType(EbtBool, EbpUndefined));
break;
@@ -793,6 +753,7 @@ TIntermTyped *TIntermConstantUnion::fold(
break;
case EOpDiv:
+ case EOpIMod:
{
tempConstArray = new ConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; i++)
@@ -810,6 +771,7 @@ TIntermTyped *TIntermConstantUnion::fold(
}
else
{
+ ASSERT(op == EOpDiv);
tempConstArray[i].setFConst(
unionArray[i].getFConst() /
rightUnionArray[i].getFConst());
@@ -826,9 +788,19 @@ TIntermTyped *TIntermConstantUnion::fold(
}
else
{
- tempConstArray[i].setIConst(
- unionArray[i].getIConst() /
- rightUnionArray[i].getIConst());
+ if (op == EOpDiv)
+ {
+ tempConstArray[i].setIConst(
+ unionArray[i].getIConst() /
+ rightUnionArray[i].getIConst());
+ }
+ else
+ {
+ ASSERT(op == EOpIMod);
+ tempConstArray[i].setIConst(
+ unionArray[i].getIConst() %
+ rightUnionArray[i].getIConst());
+ }
}
break;
@@ -842,9 +814,19 @@ TIntermTyped *TIntermConstantUnion::fold(
}
else
{
- tempConstArray[i].setUConst(
- unionArray[i].getUConst() /
- rightUnionArray[i].getUConst());
+ if (op == EOpDiv)
+ {
+ tempConstArray[i].setUConst(
+ unionArray[i].getUConst() /
+ rightUnionArray[i].getUConst());
+ }
+ else
+ {
+ ASSERT(op == EOpIMod);
+ tempConstArray[i].setUConst(
+ unionArray[i].getUConst() %
+ rightUnionArray[i].getUConst());
+ }
}
break;
@@ -968,6 +950,32 @@ TIntermTyped *TIntermConstantUnion::fold(
}
break;
+ case EOpBitwiseAnd:
+ tempConstArray = new ConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ tempConstArray[i] = unionArray[i] & rightUnionArray[i];
+ break;
+ case EOpBitwiseXor:
+ tempConstArray = new ConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ tempConstArray[i] = unionArray[i] ^ rightUnionArray[i];
+ break;
+ case EOpBitwiseOr:
+ tempConstArray = new ConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ tempConstArray[i] = unionArray[i] | rightUnionArray[i];
+ break;
+ case EOpBitShiftLeft:
+ tempConstArray = new ConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ tempConstArray[i] = unionArray[i] << rightUnionArray[i];
+ break;
+ case EOpBitShiftRight:
+ tempConstArray = new ConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ tempConstArray[i] = unionArray[i] >> rightUnionArray[i];
+ break;
+
case EOpLessThan:
ASSERT(objectSize == 1);
tempConstArray = new ConstantUnion[1];
@@ -1160,6 +1168,23 @@ TIntermTyped *TIntermConstantUnion::fold(
}
break;
+ case EOpBitwiseNot:
+ switch (getType().getBasicType())
+ {
+ case EbtInt:
+ tempConstArray[i].setIConst(~unionArray[i].getIConst());
+ break;
+ case EbtUInt:
+ tempConstArray[i].setUConst(~unionArray[i].getUConst());
+ break;
+ default:
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return NULL;
+ }
+ break;
+
default:
return NULL;
}
@@ -1181,3 +1206,29 @@ TString TIntermTraverser::hash(const TString &name, ShHashFunction64 hashFunctio
TString hashedName = stream.str();
return hashedName;
}
+
+void TIntermTraverser::updateTree()
+{
+ for (size_t ii = 0; ii < mReplacements.size(); ++ii)
+ {
+ const NodeUpdateEntry& entry = mReplacements[ii];
+ ASSERT(entry.parent);
+ bool replaced = entry.parent->replaceChildNode(
+ entry.original, entry.replacement);
+ ASSERT(replaced);
+
+ if (!entry.originalBecomesChildOfReplacement)
+ {
+ // In AST traversing, a parent is visited before its children.
+ // After we replace a node, if an 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& entry2 = mReplacements[jj];
+ if (entry2.parent == entry.original)
+ entry2.parent = entry.replacement;
+ }
+ }
+ }
+}
diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode.h b/src/3rdparty/angle/src/compiler/translator/IntermNode.h
index 32c70f4671..9f732cbb00 100644
--- a/src/3rdparty/angle/src/compiler/translator/IntermNode.h
+++ b/src/3rdparty/angle/src/compiler/translator/IntermNode.h
@@ -13,182 +13,19 @@
// each node can have it's own type of list of children.
//
-#ifndef COMPILER_TRANSLATOR_INTERMEDIATE_H_
-#define COMPILER_TRANSLATOR_INTERMEDIATE_H_
+#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/Types.h"
#include "compiler/translator/ConstantUnion.h"
-
-//
-// Operators used by the high-level (parse tree) representation.
-//
-enum TOperator
-{
- EOpNull, // if in a node, should only mean a node is still being built
- EOpSequence, // denotes a list of statements, or parameters, etc.
- EOpFunctionCall,
- EOpFunction, // For function definition
- EOpParameters, // an aggregate listing the parameters to a function
-
- EOpDeclaration,
- EOpInvariantDeclaration, // Specialized declarations for attributing invariance
- EOpPrototype,
-
- //
- // Unary operators
- //
-
- EOpNegative,
- EOpPositive,
- EOpLogicalNot,
- EOpVectorLogicalNot,
-
- EOpPostIncrement,
- EOpPostDecrement,
- EOpPreIncrement,
- EOpPreDecrement,
-
- //
- // binary operations
- //
-
- EOpAdd,
- EOpSub,
- EOpMul,
- EOpDiv,
- EOpEqual,
- EOpNotEqual,
- EOpVectorEqual,
- EOpVectorNotEqual,
- EOpLessThan,
- EOpGreaterThan,
- EOpLessThanEqual,
- EOpGreaterThanEqual,
- EOpComma,
-
- EOpVectorTimesScalar,
- EOpVectorTimesMatrix,
- EOpMatrixTimesVector,
- EOpMatrixTimesScalar,
-
- EOpLogicalOr,
- EOpLogicalXor,
- EOpLogicalAnd,
-
- EOpIndexDirect,
- EOpIndexIndirect,
- EOpIndexDirectStruct,
- EOpIndexDirectInterfaceBlock,
-
- EOpVectorSwizzle,
-
- //
- // Built-in functions potentially mapped to operators
- //
-
- EOpRadians,
- EOpDegrees,
- EOpSin,
- EOpCos,
- EOpTan,
- EOpAsin,
- EOpAcos,
- EOpAtan,
-
- EOpPow,
- EOpExp,
- EOpLog,
- EOpExp2,
- EOpLog2,
- EOpSqrt,
- EOpInverseSqrt,
-
- EOpAbs,
- EOpSign,
- EOpFloor,
- EOpCeil,
- EOpFract,
- EOpMod,
- EOpMin,
- EOpMax,
- EOpClamp,
- EOpMix,
- EOpStep,
- EOpSmoothStep,
-
- EOpLength,
- EOpDistance,
- EOpDot,
- EOpCross,
- EOpNormalize,
- EOpFaceForward,
- EOpReflect,
- EOpRefract,
-
- EOpDFdx, // Fragment only, OES_standard_derivatives extension
- EOpDFdy, // Fragment only, OES_standard_derivatives extension
- EOpFwidth, // Fragment only, OES_standard_derivatives extension
-
- EOpMatrixTimesMatrix,
-
- EOpAny,
- EOpAll,
-
- //
- // Branch
- //
-
- EOpKill, // Fragment only
- EOpReturn,
- EOpBreak,
- EOpContinue,
-
- //
- // Constructors
- //
-
- EOpConstructInt,
- EOpConstructUInt,
- EOpConstructBool,
- EOpConstructFloat,
- EOpConstructVec2,
- EOpConstructVec3,
- EOpConstructVec4,
- EOpConstructBVec2,
- EOpConstructBVec3,
- EOpConstructBVec4,
- EOpConstructIVec2,
- EOpConstructIVec3,
- EOpConstructIVec4,
- EOpConstructUVec2,
- EOpConstructUVec3,
- EOpConstructUVec4,
- EOpConstructMat2,
- EOpConstructMat3,
- EOpConstructMat4,
- EOpConstructStruct,
-
- //
- // moves
- //
-
- EOpAssign,
- EOpInitialize,
- EOpAddAssign,
- EOpSubAssign,
- EOpMulAssign,
- EOpVectorTimesMatrixAssign,
- EOpVectorTimesScalarAssign,
- EOpMatrixTimesScalarAssign,
- EOpMatrixTimesMatrixAssign,
- EOpDivAssign
-};
+#include "compiler/translator/Operator.h"
class TIntermTraverser;
class TIntermAggregate;
@@ -196,10 +33,13 @@ class TIntermBinary;
class TIntermUnary;
class TIntermConstantUnion;
class TIntermSelection;
+class TIntermSwitch;
+class TIntermCase;
class TIntermTyped;
class TIntermSymbol;
class TIntermLoop;
class TInfoSink;
+class TInfoSinkBase;
class TIntermRaw;
//
@@ -228,6 +68,8 @@ class TIntermNode
virtual TIntermBinary *getAsBinaryNode() { return 0; }
virtual TIntermUnary *getAsUnaryNode() { return 0; }
virtual TIntermSelection *getAsSelectionNode() { return 0; }
+ virtual TIntermSwitch *getAsSwitchNode() { return 0; }
+ virtual TIntermCase *getAsCaseNode() { return 0; }
virtual TIntermSymbol *getAsSymbolNode() { return 0; }
virtual TIntermLoop *getAsLoopNode() { return 0; }
virtual TIntermRaw *getAsRawNode() { return 0; }
@@ -237,10 +79,6 @@ class TIntermNode
virtual bool replaceChildNode(
TIntermNode *original, TIntermNode *replacement) = 0;
- // For traversing a tree in no particular order, but using
- // heap memory.
- virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const = 0;
-
protected:
TSourceLoc mLine;
};
@@ -331,8 +169,6 @@ class TIntermLoop : public TIntermNode
void setUnrollFlag(bool flag) { mUnrollFlag = flag; }
bool getUnrollFlag() const { return mUnrollFlag; }
- virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
-
protected:
TLoopType mType;
TIntermNode *mInit; // for-loop initialization
@@ -360,8 +196,6 @@ class TIntermBranch : public TIntermNode
TOperator getFlowOp() { return mFlowOp; }
TIntermTyped* getExpression() { return mExpression; }
- virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
-
protected:
TOperator mFlowOp;
TIntermTyped *mExpression; // non-zero except for "return exp;" statements
@@ -394,8 +228,6 @@ class TIntermSymbol : public TIntermTyped
virtual TIntermSymbol *getAsSymbolNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
- virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
-
protected:
int mId;
TString mSymbol;
@@ -419,7 +251,6 @@ class TIntermRaw : public TIntermTyped
virtual TIntermRaw *getAsRawNode() { return this; }
virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
- virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
protected:
TString mRawText;
@@ -459,8 +290,6 @@ class TIntermConstantUnion : public TIntermTyped
TIntermTyped *fold(TOperator, TIntermTyped *, TInfoSink &);
- virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const {}
-
protected:
ConstantUnion *mUnionArrayPointer;
};
@@ -519,8 +348,6 @@ class TIntermBinary : public TIntermOperator
void setAddIndexClamp() { mAddIndexClamp = true; }
bool getAddIndexClamp() { return mAddIndexClamp; }
- virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
-
protected:
TIntermTyped* mLeft;
TIntermTyped* mRight;
@@ -556,13 +383,11 @@ class TIntermUnary : public TIntermOperator
void setOperand(TIntermTyped *operand) { mOperand = operand; }
TIntermTyped *getOperand() { return mOperand; }
- bool promote(TInfoSink &);
+ void promote(const TType *funcReturnType);
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
- virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
-
protected:
TIntermTyped *mOperand;
@@ -613,8 +438,6 @@ class TIntermAggregate : public TIntermOperator
void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
- virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
-
void setPrecisionFromChildren();
void setBuiltInFunctionPrecision();
@@ -634,7 +457,7 @@ class TIntermAggregate : public TIntermOperator
};
//
-// For if tests. Simplified since there is no switch statement.
+// For if tests.
//
class TIntermSelection : public TIntermTyped
{
@@ -664,14 +487,64 @@ class TIntermSelection : public TIntermTyped
TIntermNode *getFalseBlock() const { return mFalseBlock; }
TIntermSelection *getAsSelectionNode() { return this; }
- virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
-
protected:
TIntermTyped *mCondition;
TIntermNode *mTrueBlock;
TIntermNode *mFalseBlock;
};
+//
+// Switch statement.
+//
+class TIntermSwitch : public TIntermNode
+{
+ public:
+ TIntermSwitch(TIntermTyped *init, TIntermAggregate *statementList)
+ : TIntermNode(),
+ mInit(init),
+ mStatementList(statementList)
+ {
+ }
+
+ void traverse(TIntermTraverser *it) override;
+ bool replaceChildNode(
+ TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermSwitch *getAsSwitchNode() override { return this; }
+
+ TIntermAggregate *getStatementList() { return mStatementList; }
+ void setStatementList(TIntermAggregate *statementList) { mStatementList = statementList; }
+
+ protected:
+ TIntermTyped *mInit;
+ TIntermAggregate *mStatementList;
+};
+
+//
+// Case label.
+//
+class TIntermCase : public TIntermNode
+{
+ public:
+ TIntermCase(TIntermTyped *condition)
+ : TIntermNode(),
+ mCondition(condition)
+ {
+ }
+
+ void traverse(TIntermTraverser *it) override;
+ bool replaceChildNode(
+ TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermCase *getAsCaseNode() override { return this; }
+
+ bool hasCondition() const { return mCondition != nullptr; }
+ TIntermTyped *getCondition() const { return mCondition; }
+
+ protected:
+ TIntermTyped *mCondition;
+};
+
enum Visit
{
PreVisit,
@@ -687,7 +560,7 @@ enum Visit
// 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.
//
-class TIntermTraverser
+class TIntermTraverser : angle::NonCopyable
{
public:
POOL_ALLOCATOR_NEW_DELETE();
@@ -708,6 +581,8 @@ class TIntermTraverser
virtual bool visitBinary(Visit, TIntermBinary *) { return true; }
virtual bool visitUnary(Visit, TIntermUnary *) { return true; }
virtual bool visitSelection(Visit, TIntermSelection *) { return true; }
+ virtual bool visitSwitch(Visit, TIntermSwitch *) { return true; }
+ virtual bool visitCase(Visit, TIntermCase *) { return true; }
virtual bool visitAggregate(Visit, TIntermAggregate *) { return true; }
virtual bool visitLoop(Visit, TIntermLoop *) { return true; }
virtual bool visitBranch(Visit, TIntermBranch *) { return true; }
@@ -741,12 +616,38 @@ class TIntermTraverser
const bool postVisit;
const bool rightToLeft;
+ // If traversers need to replace nodes, they can add the replacements in
+ // mReplacements during traversal and the user of the traverser should call
+ // this function after traversal to perform them.
+ void updateTree();
+
protected:
int mDepth;
int mMaxDepth;
// All the nodes from root to the current node's parent during traversing.
TVector<TIntermNode *> mPath;
+
+ 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;
+ };
+
+ // During traversing, save all the changes that need to happen into
+ // mReplacements, then do them by calling updateTree().
+ std::vector<NodeUpdateEntry> mReplacements;
};
//
@@ -768,10 +669,10 @@ class TMaxDepthTraverser : public TIntermTraverser
virtual bool visitLoop(Visit, TIntermLoop *) { return depthCheck(); }
virtual bool visitBranch(Visit, TIntermBranch *) { return depthCheck(); }
-protected:
+ protected:
bool depthCheck() const { return mMaxDepth < mDepthLimit; }
int mDepthLimit;
};
-#endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_
+#endif // COMPILER_TRANSLATOR_INTERMNODE_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/IntermTraverse.cpp b/src/3rdparty/angle/src/compiler/translator/IntermTraverse.cpp
index 72b2033fb3..7a7efb71f5 100644
--- a/src/3rdparty/angle/src/compiler/translator/IntermTraverse.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/IntermTraverse.cpp
@@ -194,6 +194,60 @@ void TIntermSelection::traverse(TIntermTraverser *it)
}
//
+// Traverse a switch node. Same comments in binary node apply here.
+//
+void TIntermSwitch::traverse(TIntermTraverser *it)
+{
+ bool visit = true;
+
+ if (it->preVisit)
+ visit = it->visitSwitch(PreVisit, this);
+
+ if (visit)
+ {
+ it->incrementDepth(this);
+ if (it->rightToLeft)
+ {
+ if (mStatementList)
+ mStatementList->traverse(it);
+ if (it->inVisit)
+ visit = it->visitSwitch(InVisit, this);
+ if (visit)
+ mInit->traverse(it);
+ }
+ else
+ {
+ mInit->traverse(it);
+ if (it->inVisit)
+ visit = it->visitSwitch(InVisit, this);
+ if (visit && mStatementList)
+ mStatementList->traverse(it);
+ }
+ it->decrementDepth();
+ }
+
+ if (visit && it->postVisit)
+ it->visitSwitch(PostVisit, this);
+}
+
+//
+// Traverse a switch node. Same comments in binary node apply here.
+//
+void TIntermCase::traverse(TIntermTraverser *it)
+{
+ bool visit = true;
+
+ if (it->preVisit)
+ visit = it->visitCase(PreVisit, this);
+
+ if (visit && mCondition)
+ mCondition->traverse(it);
+
+ if (visit && it->postVisit)
+ it->visitCase(PostVisit, this);
+}
+
+//
// Traverse a loop node. Same comments in binary node apply here.
//
void TIntermLoop::traverse(TIntermTraverser *it)
diff --git a/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp b/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp
index e558683c55..320056f8ce 100644
--- a/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp
@@ -13,7 +13,6 @@
#include <algorithm>
#include "compiler/translator/Intermediate.h"
-#include "compiler/translator/RemoveTree.h"
#include "compiler/translator/SymbolTable.h"
////////////////////////////////////////////////////////////////////////////
@@ -46,47 +45,6 @@ TIntermSymbol *TIntermediate::addSymbol(
TIntermTyped *TIntermediate::addBinaryMath(
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line)
{
- switch (op)
- {
- case EOpEqual:
- case EOpNotEqual:
- if (left->isArray())
- return NULL;
- break;
- case EOpLessThan:
- case EOpGreaterThan:
- case EOpLessThanEqual:
- case EOpGreaterThanEqual:
- if (left->isMatrix() || left->isArray() || left->isVector() ||
- left->getBasicType() == EbtStruct)
- {
- return NULL;
- }
- break;
- case EOpLogicalOr:
- case EOpLogicalXor:
- case EOpLogicalAnd:
- if (left->getBasicType() != EbtBool ||
- left->isMatrix() || left->isArray() || left->isVector())
- {
- return NULL;
- }
- break;
- case EOpAdd:
- case EOpSub:
- case EOpDiv:
- case EOpMul:
- if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
- return NULL;
- default:
- break;
- }
-
- if (left->getBasicType() != right->getBasicType())
- {
- return NULL;
- }
-
//
// Need a new node holding things together then. Make
// one and promote it to the right type.
@@ -169,45 +127,8 @@ TIntermTyped *TIntermediate::addIndex(
// Returns the added node.
//
TIntermTyped *TIntermediate::addUnaryMath(
- TOperator op, TIntermNode *childNode, const TSourceLoc &line)
+ TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType)
{
- TIntermUnary *node;
- TIntermTyped *child = childNode->getAsTyped();
-
- if (child == NULL)
- {
- mInfoSink.info.message(EPrefixInternalError, line,
- "Bad type in AddUnaryMath");
- return NULL;
- }
-
- switch (op)
- {
- case EOpLogicalNot:
- if (child->getType().getBasicType() != EbtBool ||
- child->getType().isMatrix() ||
- child->getType().isArray() ||
- child->getType().isVector())
- {
- return NULL;
- }
- break;
-
- case EOpPostIncrement:
- case EOpPreIncrement:
- case EOpPostDecrement:
- case EOpPreDecrement:
- case EOpNegative:
- case EOpPositive:
- if (child->getType().getBasicType() == EbtStruct ||
- child->getType().isArray())
- {
- return NULL;
- }
- default:
- break;
- }
-
TIntermConstantUnion *childTempConstant = 0;
if (child->getAsConstantUnion())
childTempConstant = child->getAsConstantUnion();
@@ -215,12 +136,10 @@ TIntermTyped *TIntermediate::addUnaryMath(
//
// Make a new node for the operator.
//
- node = new TIntermUnary(op);
+ TIntermUnary *node = new TIntermUnary(op);
node->setLine(line);
node->setOperand(child);
-
- if (!node->promote(mInfoSink))
- return 0;
+ node->promote(funcReturnType);
if (childTempConstant)
{
@@ -423,6 +342,24 @@ TIntermTyped *TIntermediate::addSelection(
return node;
}
+TIntermSwitch *TIntermediate::addSwitch(
+ TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line)
+{
+ TIntermSwitch *node = new TIntermSwitch(init, statementList);
+ node->setLine(line);
+
+ return node;
+}
+
+TIntermCase *TIntermediate::addCase(
+ TIntermTyped *condition, const TSourceLoc &line)
+{
+ TIntermCase *node = new TIntermCase(condition);
+ node->setLine(line);
+
+ return node;
+}
+
//
// Constant terminal nodes. Has a union that contains bool, float or int constants
//
@@ -510,12 +447,3 @@ bool TIntermediate::postProcess(TIntermNode *root)
return true;
}
-
-//
-// This deletes the tree.
-//
-void TIntermediate::remove(TIntermNode *root)
-{
- if (root)
- RemoveAllTreeNodes(root);
-}
diff --git a/src/3rdparty/angle/src/compiler/translator/intermediate.h b/src/3rdparty/angle/src/compiler/translator/Intermediate.h
index 3b7e7bd802..ec73e22834 100644
--- a/src/3rdparty/angle/src/compiler/translator/intermediate.h
+++ b/src/3rdparty/angle/src/compiler/translator/Intermediate.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
-#define COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
+#ifndef COMPILER_TRANSLATOR_INTERMEDIATE_H_
+#define COMPILER_TRANSLATOR_INTERMEDIATE_H_
#include "compiler/translator/IntermNode.h"
@@ -35,7 +35,7 @@ class TIntermediate
TIntermTyped *addIndex(
TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &);
TIntermTyped *addUnaryMath(
- TOperator op, TIntermNode *child, const TSourceLoc &);
+ TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType);
TIntermAggregate *growAggregate(
TIntermNode *left, TIntermNode *right, const TSourceLoc &);
TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &);
@@ -43,6 +43,10 @@ class TIntermediate
TIntermNode *addSelection(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &);
TIntermTyped *addSelection(
TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &);
+ TIntermSwitch *addSwitch(
+ TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line);
+ TIntermCase *addCase(
+ TIntermTyped *condition, const TSourceLoc &line);
TIntermTyped *addComma(
TIntermTyped *left, TIntermTyped *right, const TSourceLoc &);
TIntermConstantUnion *addConstantUnion(ConstantUnion *, const TType &, const TSourceLoc &);
@@ -55,8 +59,8 @@ class TIntermediate
TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &);
TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &);
bool postProcess(TIntermNode *);
- void remove(TIntermNode *);
- void outputTree(TIntermNode *);
+
+ static void outputTree(TIntermNode *, TInfoSinkBase &);
private:
void operator=(TIntermediate &); // prevent assignments
@@ -64,4 +68,4 @@ class TIntermediate
TInfoSink & mInfoSink;
};
-#endif // COMPILER_TRANSLATOR_LOCAL_INTERMEDIATE_H_
+#endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/LoopInfo.h b/src/3rdparty/angle/src/compiler/translator/LoopInfo.h
index 5f72a6e944..ec73fd0fa5 100644
--- a/src/3rdparty/angle/src/compiler/translator/LoopInfo.h
+++ b/src/3rdparty/angle/src/compiler/translator/LoopInfo.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_TRANSLATOR_LOOP_INFO_H_
-#define COMPILER_TRANSLATOR_LOOP_INFO_H_
+#ifndef COMPILER_TRANSLATOR_LOOPINFO_H_
+#define COMPILER_TRANSLATOR_LOOPINFO_H_
#include "compiler/translator/IntermNode.h"
@@ -76,5 +76,5 @@ class TLoopStack : public TVector<TLoopInfo>
void pop();
};
-#endif // COMPILER_TRANSLATOR_LOOP_INDEX_H_
+#endif // COMPILER_TRANSLATOR_LOOPINFO_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/MMap.h b/src/3rdparty/angle/src/compiler/translator/MMap.h
index a308671514..fca843992b 100644
--- a/src/3rdparty/angle/src/compiler/translator/MMap.h
+++ b/src/3rdparty/angle/src/compiler/translator/MMap.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef _MMAP_INCLUDED_
-#define _MMAP_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_MMAP_H_
+#define COMPILER_TRANSLATOR_MMAP_H_
//
// Encapsulate memory mapped files
@@ -53,4 +53,4 @@ private:
char* fBuff; // the actual data;
};
-#endif // _MMAP_INCLUDED_
+#endif // COMPILER_TRANSLATOR_MMAP_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/NodeSearch.h b/src/3rdparty/angle/src/compiler/translator/NodeSearch.h
index 60070c9d33..8ffed614c3 100644
--- a/src/3rdparty/angle/src/compiler/translator/NodeSearch.h
+++ b/src/3rdparty/angle/src/compiler/translator/NodeSearch.h
@@ -6,8 +6,8 @@
// NodeSearch.h: Utilities for searching translator node graphs
//
-#ifndef TRANSLATOR_NODESEARCH_H_
-#define TRANSLATOR_NODESEARCH_H_
+#ifndef COMPILER_TRANSLATOR_NODESEARCH_H_
+#define COMPILER_TRANSLATOR_NODESEARCH_H_
#include "compiler/translator/IntermNode.h"
@@ -77,4 +77,4 @@ class FindSideEffectRewriting : public NodeSearchTraverser<FindSideEffectRewriti
}
-#endif // TRANSLATOR_NODESEARCH_H_
+#endif // COMPILER_TRANSLATOR_NODESEARCH_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/Operator.cpp b/src/3rdparty/angle/src/compiler/translator/Operator.cpp
new file mode 100644
index 0000000000..ae4512bd44
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/Operator.cpp
@@ -0,0 +1,195 @@
+//
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/Operator.h"
+
+const char *GetOperatorString(TOperator op)
+{
+ switch (op)
+ {
+ // Note: ops from EOpNull to EOpPrototype can't be handled here.
+
+ case EOpNegative: return "-";
+ case EOpPositive: return "+";
+ case EOpLogicalNot: return "!";
+ case EOpVectorLogicalNot: return "not";
+ case EOpBitwiseNot: return "~";
+
+ case EOpPostIncrement: return "++";
+ case EOpPostDecrement: return "--";
+ case EOpPreIncrement: return "++";
+ case EOpPreDecrement: return "--";
+
+ case EOpAdd: return "+";
+ case EOpSub: return "-";
+ case EOpMul: return "*";
+ case EOpDiv: return "/";
+ case EOpIMod: return "%";
+ case EOpEqual: return "==";
+ case EOpNotEqual: return "!=";
+ case EOpVectorEqual: return "equal";
+ case EOpVectorNotEqual: return "notEqual";
+ 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: 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 EOpVectorSwizzle: return ".";
+
+ case EOpRadians: return "radians";
+ case EOpDegrees: return "degrees";
+ case EOpSin: return "sin";
+ case EOpCos: return "cos";
+ case EOpTan: return "tan";
+ case EOpAsin: return "asin";
+ case EOpAcos: return "acos";
+ case EOpAtan: return "atan";
+
+ case EOpSinh: return "sinh";
+ case EOpCosh: return "cosh";
+ case EOpTanh: return "tanh";
+ case EOpAsinh: return "asinh";
+ case EOpAcosh: return "acosh";
+ case EOpAtanh: return "atanh";
+
+ case EOpPow: return "pow";
+ case EOpExp: return "exp";
+ case EOpLog: return "log";
+ case EOpExp2: return "exp2";
+ case EOpLog2: return "log2";
+ case EOpSqrt: return "sqrt";
+ case EOpInverseSqrt: return "inversesqrt";
+
+ case EOpAbs: return "abs";
+ case EOpSign: return "sign";
+ case EOpFloor: return "floor";
+ case EOpTrunc: return "trunc";
+ case EOpRound: return "round";
+ case EOpRoundEven: return "roundEven";
+ case EOpCeil: return "ceil";
+ case EOpFract: return "fract";
+ case EOpMod: return "mod";
+ case EOpModf: return "modf";
+ case EOpMin: return "min";
+ case EOpMax: return "max";
+ case EOpClamp: return "clamp";
+ case EOpMix: return "mix";
+ case EOpStep: return "step";
+ case EOpSmoothStep: return "smoothstep";
+ case EOpIsNan: return "isnan";
+ case EOpIsInf: return "isinf";
+
+ case EOpFloatBitsToInt: return "floatBitsToInt";
+ case EOpFloatBitsToUint: return "floatBitsToUint";
+ case EOpIntBitsToFloat: return "intBitsToFloat";
+ case EOpUintBitsToFloat: return "uintBitsToFloat";
+
+ case EOpPackSnorm2x16: return "packSnorm2x16";
+ case EOpPackUnorm2x16: return "packUnorm2x16";
+ case EOpPackHalf2x16: return "packHalf2x16";
+ case EOpUnpackSnorm2x16: return "unpackSnorm2x16";
+ case EOpUnpackUnorm2x16: return "unpackUnorm2x16";
+ case EOpUnpackHalf2x16: return "unpackHalf2x16";
+
+ case EOpLength: return "length";
+ case EOpDistance: return "distance";
+ case EOpDot: return "dot";
+ case EOpCross: return "cross";
+ case EOpNormalize: return "normalize";
+ case EOpFaceForward: return "faceforward";
+ case EOpReflect: return "reflect";
+ case EOpRefract: return "refract";
+
+ case EOpDFdx: return "dFdx";
+ case EOpDFdy: return "dFdy";
+ case EOpFwidth: return "fwidth";
+
+ case EOpMatrixTimesMatrix: return "*";
+
+ case EOpOuterProduct: return "outerProduct";
+ case EOpTranspose: return "transpose";
+ case EOpDeterminant: return "determinant";
+ case EOpInverse: return "inverse";
+
+ case EOpAny: return "any";
+ case EOpAll: return "all";
+
+ case EOpKill: return "kill";
+ case EOpReturn: return "return";
+ case EOpBreak: return "break";
+ case EOpContinue: return "continue";
+
+ case EOpConstructInt: return "int";
+ case EOpConstructUInt: return "uint";
+ case EOpConstructBool: return "bool";
+ case EOpConstructFloat: return "float";
+ case EOpConstructVec2: return "vec2";
+ case EOpConstructVec3: return "vec3";
+ case EOpConstructVec4: return "vec4";
+ case EOpConstructBVec2: return "bvec2";
+ case EOpConstructBVec3: return "bvec3";
+ case EOpConstructBVec4: return "bvec4";
+ case EOpConstructIVec2: return "ivec2";
+ case EOpConstructIVec3: return "ivec3";
+ case EOpConstructIVec4: return "ivec4";
+ case EOpConstructUVec2: return "uvec2";
+ case EOpConstructUVec3: return "uvec3";
+ case EOpConstructUVec4: return "uvec4";
+ case EOpConstructMat2: return "mat2";
+ case EOpConstructMat3: return "mat3";
+ case EOpConstructMat4: return "mat4";
+ // Note: EOpConstructStruct can't be handled here
+
+ case EOpAssign: return "=";
+ 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: break;
+ }
+ return "";
+}
+
diff --git a/src/3rdparty/angle/src/compiler/translator/Operator.h b/src/3rdparty/angle/src/compiler/translator/Operator.h
new file mode 100644
index 0000000000..8290f952fc
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/Operator.h
@@ -0,0 +1,226 @@
+//
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_OPERATOR_H_
+#define COMPILER_TRANSLATOR_OPERATOR_H_
+
+//
+// Operators used by the high-level (parse tree) representation.
+//
+enum TOperator
+{
+ EOpNull, // if in a node, should only mean a node is still being built
+ EOpSequence, // denotes a list of statements, or parameters, etc.
+ EOpFunctionCall,
+ EOpInternalFunctionCall, // Call to an internal helper function
+ EOpFunction, // For function definition
+ EOpParameters, // an aggregate listing the parameters to a function
+
+ EOpDeclaration,
+ EOpInvariantDeclaration, // Specialized declarations for attributing invariance
+ EOpPrototype,
+
+ //
+ // Unary operators
+ //
+
+ EOpNegative,
+ EOpPositive,
+ EOpLogicalNot,
+ EOpVectorLogicalNot,
+ EOpBitwiseNot,
+
+ EOpPostIncrement,
+ EOpPostDecrement,
+ EOpPreIncrement,
+ EOpPreDecrement,
+
+ //
+ // binary operations
+ //
+
+ EOpAdd,
+ EOpSub,
+ EOpMul,
+ EOpDiv,
+ EOpIMod,
+ EOpEqual,
+ EOpNotEqual,
+ EOpVectorEqual,
+ EOpVectorNotEqual,
+ EOpLessThan,
+ EOpGreaterThan,
+ EOpLessThanEqual,
+ EOpGreaterThanEqual,
+ EOpComma,
+
+ EOpVectorTimesScalar,
+ EOpVectorTimesMatrix,
+ EOpMatrixTimesVector,
+ EOpMatrixTimesScalar,
+
+ EOpLogicalOr,
+ EOpLogicalXor,
+ EOpLogicalAnd,
+
+ EOpBitShiftLeft,
+ EOpBitShiftRight,
+
+ EOpBitwiseAnd,
+ EOpBitwiseXor,
+ EOpBitwiseOr,
+
+ EOpIndexDirect,
+ EOpIndexIndirect,
+ EOpIndexDirectStruct,
+ EOpIndexDirectInterfaceBlock,
+
+ EOpVectorSwizzle,
+
+ //
+ // Built-in functions potentially mapped to operators
+ //
+
+ EOpRadians,
+ EOpDegrees,
+ EOpSin,
+ EOpCos,
+ EOpTan,
+ EOpAsin,
+ EOpAcos,
+ EOpAtan,
+
+ EOpSinh,
+ EOpCosh,
+ EOpTanh,
+ EOpAsinh,
+ EOpAcosh,
+ EOpAtanh,
+
+ EOpPow,
+ EOpExp,
+ EOpLog,
+ EOpExp2,
+ EOpLog2,
+ EOpSqrt,
+ EOpInverseSqrt,
+
+ EOpAbs,
+ EOpSign,
+ EOpFloor,
+ EOpTrunc,
+ EOpRound,
+ EOpRoundEven,
+ EOpCeil,
+ EOpFract,
+ EOpMod,
+ EOpModf,
+ EOpMin,
+ EOpMax,
+ EOpClamp,
+ EOpMix,
+ EOpStep,
+ EOpSmoothStep,
+ EOpIsNan,
+ EOpIsInf,
+
+ EOpFloatBitsToInt,
+ EOpFloatBitsToUint,
+ EOpIntBitsToFloat,
+ EOpUintBitsToFloat,
+
+ EOpPackSnorm2x16,
+ EOpPackUnorm2x16,
+ EOpPackHalf2x16,
+ EOpUnpackSnorm2x16,
+ EOpUnpackUnorm2x16,
+ EOpUnpackHalf2x16,
+
+ EOpLength,
+ EOpDistance,
+ EOpDot,
+ EOpCross,
+ EOpNormalize,
+ EOpFaceForward,
+ EOpReflect,
+ EOpRefract,
+
+ EOpDFdx, // Fragment only, OES_standard_derivatives extension
+ EOpDFdy, // Fragment only, OES_standard_derivatives extension
+ EOpFwidth, // Fragment only, OES_standard_derivatives extension
+
+ EOpMatrixTimesMatrix,
+
+ EOpOuterProduct,
+ EOpTranspose,
+ EOpDeterminant,
+ EOpInverse,
+
+ EOpAny,
+ EOpAll,
+
+ //
+ // Branch
+ //
+
+ EOpKill, // Fragment only
+ EOpReturn,
+ EOpBreak,
+ EOpContinue,
+
+ //
+ // Constructors
+ //
+
+ EOpConstructInt,
+ EOpConstructUInt,
+ EOpConstructBool,
+ EOpConstructFloat,
+ EOpConstructVec2,
+ EOpConstructVec3,
+ EOpConstructVec4,
+ EOpConstructBVec2,
+ EOpConstructBVec3,
+ EOpConstructBVec4,
+ EOpConstructIVec2,
+ EOpConstructIVec3,
+ EOpConstructIVec4,
+ EOpConstructUVec2,
+ EOpConstructUVec3,
+ EOpConstructUVec4,
+ EOpConstructMat2,
+ EOpConstructMat3,
+ EOpConstructMat4,
+ EOpConstructStruct,
+
+ //
+ // moves
+ //
+
+ EOpAssign,
+ EOpInitialize,
+ EOpAddAssign,
+ EOpSubAssign,
+
+ EOpMulAssign,
+ EOpVectorTimesMatrixAssign,
+ EOpVectorTimesScalarAssign,
+ EOpMatrixTimesScalarAssign,
+ EOpMatrixTimesMatrixAssign,
+
+ EOpDivAssign,
+ EOpIModAssign,
+ EOpBitShiftLeftAssign,
+ EOpBitShiftRightAssign,
+ EOpBitwiseAndAssign,
+ EOpBitwiseXorAssign,
+ EOpBitwiseOrAssign
+};
+
+// Returns the string corresponding to the operator in GLSL
+const char* GetOperatorString(TOperator op);
+
+#endif // COMPILER_TRANSLATOR_OPERATOR_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputESSL.cpp b/src/3rdparty/angle/src/compiler/translator/OutputESSL.cpp
index 65635af1ff..77e0a8fb37 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputESSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/OutputESSL.cpp
@@ -6,13 +6,21 @@
#include "compiler/translator/OutputESSL.h"
-TOutputESSL::TOutputESSL(TInfoSinkBase& objSink,
+TOutputESSL::TOutputESSL(TInfoSinkBase &objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
- NameMap& nameMap,
- TSymbolTable& symbolTable,
- int shaderVersion)
- : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable, shaderVersion)
+ NameMap &nameMap,
+ TSymbolTable &symbolTable,
+ int shaderVersion,
+ bool forceHighp)
+ : TOutputGLSLBase(objSink,
+ clampingStrategy,
+ hashFunction,
+ nameMap,
+ symbolTable,
+ shaderVersion,
+ SH_ESSL_OUTPUT),
+ mForceHighp(forceHighp)
{
}
@@ -22,6 +30,9 @@ bool TOutputESSL::writeVariablePrecision(TPrecision precision)
return false;
TInfoSinkBase& out = objSink();
- out << getPrecisionString(precision);
+ if (mForceHighp)
+ out << getPrecisionString(EbpHigh);
+ else
+ out << getPrecisionString(precision);
return true;
}
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputESSL.h b/src/3rdparty/angle/src/compiler/translator/OutputESSL.h
index 8a567fb8aa..813f1e944b 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputESSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/OutputESSL.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef CROSSCOMPILERGLSL_OUTPUTESSL_H_
-#define CROSSCOMPILERGLSL_OUTPUTESSL_H_
+#ifndef COMPILER_TRANSLATOR_OUTPUTESSL_H_
+#define COMPILER_TRANSLATOR_OUTPUTESSL_H_
#include "compiler/translator/OutputGLSLBase.h"
@@ -17,10 +17,13 @@ public:
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable,
- int shaderVersion);
+ int shaderVersion,
+ bool forceHighp);
protected:
virtual bool writeVariablePrecision(TPrecision precision);
+private:
+ bool mForceHighp;
};
-#endif // CROSSCOMPILERGLSL_OUTPUTESSL_H_
+#endif // COMPILER_TRANSLATOR_OUTPUTESSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/OutputGLSL.cpp
index eb7cbb4ae8..9badf0e2fc 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputGLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSL.cpp
@@ -11,8 +11,15 @@ TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable,
- int shaderVersion)
- : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable, shaderVersion)
+ int shaderVersion,
+ ShShaderOutput output)
+ : TOutputGLSLBase(objSink,
+ clampingStrategy,
+ hashFunction,
+ nameMap,
+ symbolTable,
+ shaderVersion,
+ output)
{
}
@@ -21,21 +28,30 @@ bool TOutputGLSL::writeVariablePrecision(TPrecision)
return false;
}
-void TOutputGLSL::visitSymbol(TIntermSymbol* node)
+void TOutputGLSL::visitSymbol(TIntermSymbol *node)
{
TInfoSinkBase& out = objSink();
- if (node->getSymbol() == "gl_FragDepthEXT")
+ const TString &symbol = node->getSymbol();
+ if (symbol == "gl_FragDepthEXT")
{
out << "gl_FragDepth";
}
+ else if (symbol == "gl_FragColor" && getShaderOutput() == SH_GLSL_CORE_OUTPUT)
+ {
+ out << "webgl_FragColor";
+ }
+ else if (symbol == "gl_FragData" && getShaderOutput() == SH_GLSL_CORE_OUTPUT)
+ {
+ out << "webgl_FragData";
+ }
else
{
TOutputGLSLBase::visitSymbol(node);
}
}
-TString TOutputGLSL::translateTextureFunction(TString& name)
+TString TOutputGLSL::translateTextureFunction(TString &name)
{
static const char *simpleRename[] = {
"texture2DLodEXT", "texture2DLod",
@@ -46,10 +62,30 @@ TString TOutputGLSL::translateTextureFunction(TString& name)
"textureCubeGradEXT", "textureCubeGradARB",
NULL, NULL
};
+ static const char *legacyToCoreRename[] = {
+ "texture2D", "texture",
+ "texture2DProj", "textureProj",
+ "texture2DLod", "textureLod",
+ "texture2DProjLod", "textureProjLod",
+ "textureCube", "texture",
+ "textureCubeLod", "textureLod",
+ // Extensions
+ "texture2DLodEXT", "textureLod",
+ "texture2DProjLodEXT", "textureProjLod",
+ "textureCubeLodEXT", "textureLod",
+ "texture2DGradEXT", "textureGrad",
+ "texture2DProjGradEXT", "textureProjGrad",
+ "textureCubeGradEXT", "textureGrad",
+ NULL, NULL
+ };
+ const char **mapping = (getShaderOutput() == SH_GLSL_CORE_OUTPUT) ?
+ legacyToCoreRename : simpleRename;
- for (int i = 0; simpleRename[i] != NULL; i += 2) {
- if (name == simpleRename[i]) {
- return simpleRename[i+1];
+ for (int i = 0; mapping[i] != NULL; i += 2)
+ {
+ if (name == mapping[i])
+ {
+ return mapping[i+1];
}
}
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSL.h b/src/3rdparty/angle/src/compiler/translator/OutputGLSL.h
index bceebe397d..21b2d079d3 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputGLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSL.h
@@ -4,25 +4,26 @@
// found in the LICENSE file.
//
-#ifndef CROSSCOMPILERGLSL_OUTPUTGLSL_H_
-#define CROSSCOMPILERGLSL_OUTPUTGLSL_H_
+#ifndef COMPILER_TRANSLATOR_OUTPUTGLSL_H_
+#define COMPILER_TRANSLATOR_OUTPUTGLSL_H_
#include "compiler/translator/OutputGLSLBase.h"
class TOutputGLSL : public TOutputGLSLBase
{
-public:
+ public:
TOutputGLSL(TInfoSinkBase& objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap& nameMap,
TSymbolTable& symbolTable,
- int shaderVersion);
+ int shaderVersion,
+ ShShaderOutput output);
-protected:
+ protected:
virtual bool writeVariablePrecision(TPrecision);
virtual void visitSymbol(TIntermSymbol* node);
virtual TString translateTextureFunction(TString& name);
};
-#endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_
+#endif // COMPILER_TRANSLATOR_OUTPUTGLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
index ed590967b1..4bb6305d05 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
@@ -36,8 +36,17 @@ bool isSingleStatement(TIntermNode *node)
{
return false;
}
+ else if (node->getAsSwitchNode())
+ {
+ return false;
+ }
+ else if (node->getAsCaseNode())
+ {
+ return false;
+ }
return true;
}
+
} // namespace
TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
@@ -45,7 +54,8 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
ShHashFunction64 hashFunction,
NameMap &nameMap,
TSymbolTable &symbolTable,
- int shaderVersion)
+ int shaderVersion,
+ ShShaderOutput output)
: TIntermTraverser(true, true, true),
mObjSink(objSink),
mDeclaringVariables(false),
@@ -53,7 +63,8 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
mHashFunction(hashFunction),
mNameMap(nameMap),
mSymbolTable(symbolTable),
- mShaderVersion(shaderVersion)
+ mShaderVersion(shaderVersion),
+ mOutput(output)
{
}
@@ -83,7 +94,34 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
TQualifier qualifier = type.getQualifier();
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
{
- out << type.getQualifierString() << " ";
+ if (mOutput == SH_GLSL_CORE_OUTPUT)
+ {
+ switch (qualifier)
+ {
+ case EvqAttribute:
+ out << "in" << " ";
+ break;
+ case EvqVaryingIn:
+ out << "in" << " ";
+ break;
+ case EvqVaryingOut:
+ out << "out" << " ";
+ break;
+ case EvqInvariantVaryingIn:
+ out << "invariant in" << " ";
+ break;
+ case EvqInvariantVaryingOut:
+ out << "invariant out" << " ";
+ break;
+ default:
+ out << type.getQualifierString() << " ";
+ break;
+ }
+ }
+ else
+ {
+ out << type.getQualifierString() << " ";
+ }
}
// Declare the struct if we have not done so already.
if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct()))
@@ -166,6 +204,9 @@ const ConstantUnion *TOutputGLSLBase::writeConstantUnion(
case EbtInt:
out << pConstUnion->getIConst();
break;
+ case EbtUInt:
+ out << pConstUnion->getUConst() << "u";
+ break;
case EbtBool:
out << pConstUnion->getBConst();
break;
@@ -223,6 +264,9 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
case EOpDivAssign:
writeTriplet(visit, "(", " /= ", ")");
break;
+ case EOpIModAssign:
+ writeTriplet(visit, "(", " %= ", ")");
+ break;
// Notice the fall-through.
case EOpMulAssign:
case EOpVectorTimesMatrixAssign:
@@ -231,6 +275,21 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
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:
writeTriplet(visit, NULL, "[", "]");
@@ -340,9 +399,25 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node)
case EOpDiv:
writeTriplet(visit, "(", " / ", ")");
break;
- case EOpMod:
- UNIMPLEMENTED();
+ 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;
@@ -398,6 +473,7 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
case EOpPositive: preString = "(+"; break;
case EOpVectorLogicalNot: preString = "not("; break;
case EOpLogicalNot: preString = "(!"; break;
+ case EOpBitwiseNot: preString = "(~"; break;
case EOpPostIncrement: preString = "("; postString = "++)"; break;
case EOpPostDecrement: preString = "("; postString = "--)"; break;
@@ -429,6 +505,25 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
preString = "atan(";
break;
+ case EOpSinh:
+ preString = "sinh(";
+ break;
+ case EOpCosh:
+ preString = "cosh(";
+ break;
+ case EOpTanh:
+ preString = "tanh(";
+ break;
+ case EOpAsinh:
+ preString = "asinh(";
+ break;
+ case EOpAcosh:
+ preString = "acosh(";
+ break;
+ case EOpAtanh:
+ preString = "atanh(";
+ break;
+
case EOpExp:
preString = "exp(";
break;
@@ -457,12 +552,59 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
case EOpFloor:
preString = "floor(";
break;
+ case EOpTrunc:
+ preString = "trunc(";
+ break;
+ case EOpRound:
+ preString = "round(";
+ break;
+ case EOpRoundEven:
+ preString = "roundEven(";
+ break;
case EOpCeil:
preString = "ceil(";
break;
case EOpFract:
preString = "fract(";
break;
+ case EOpIsNan:
+ preString = "isnan(";
+ break;
+ case EOpIsInf:
+ preString = "isinf(";
+ break;
+
+ case EOpFloatBitsToInt:
+ preString = "floatBitsToInt(";
+ break;
+ case EOpFloatBitsToUint:
+ preString = "floatBitsToUint(";
+ break;
+ case EOpIntBitsToFloat:
+ preString = "intBitsToFloat(";
+ break;
+ case EOpUintBitsToFloat:
+ preString = "uintBitsToFloat(";
+ break;
+
+ case EOpPackSnorm2x16:
+ preString = "packSnorm2x16(";
+ break;
+ case EOpPackUnorm2x16:
+ preString = "packUnorm2x16(";
+ break;
+ case EOpPackHalf2x16:
+ preString = "packHalf2x16(";
+ break;
+ case EOpUnpackSnorm2x16:
+ preString = "unpackSnorm2x16(";
+ break;
+ case EOpUnpackUnorm2x16:
+ preString = "unpackUnorm2x16(";
+ break;
+ case EOpUnpackHalf2x16:
+ preString = "unpackHalf2x16(";
+ break;
case EOpLength:
preString = "length(";
@@ -481,6 +623,16 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
preString = "fwidth(";
break;
+ case EOpTranspose:
+ preString = "transpose(";
+ break;
+ case EOpDeterminant:
+ preString = "determinant(";
+ break;
+ case EOpInverse:
+ preString = "inverse(";
+ break;
+
case EOpAny:
preString = "any(";
break;
@@ -536,6 +688,36 @@ bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection *node)
return false;
}
+bool TOutputGLSLBase::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ if (node->getStatementList())
+ {
+ writeTriplet(visit, "switch (", ") ", nullptr);
+ // The curly braces get written when visiting the statementList aggregate
+ }
+ else
+ {
+ // No statementList, so it won't output curly braces
+ writeTriplet(visit, "switch (", ") {", "}\n");
+ }
+ 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::visitAggregate(Visit visit, TIntermAggregate *node)
{
bool visitChildren = true;
@@ -555,11 +737,11 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
iter != node->getSequence()->end(); ++iter)
{
- TIntermNode *node = *iter;
- ASSERT(node != NULL);
- node->traverse(this);
+ TIntermNode *curNode = *iter;
+ ASSERT(curNode != NULL);
+ curNode->traverse(this);
- if (isSingleStatement(node))
+ if (isSingleStatement(curNode))
out << ";\n";
}
decrementDepth();
@@ -622,6 +804,15 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
else
out << ")";
break;
+ case EOpInternalFunctionCall:
+ // Function call to an internal helper function.
+ if (visit == PreVisit)
+ out << node->getName() << "(";
+ else if (visit == InVisit)
+ out << ", ";
+ else
+ out << ")";
+ break;
case EOpParameters:
// Function parameters.
ASSERT(visit == PreVisit);
@@ -724,6 +915,10 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
}
break;
+ case EOpOuterProduct:
+ writeBuiltInFunctionTriplet(visit, "outerProduct(", useEmulatedFunction);
+ break;
+
case EOpLessThan:
writeBuiltInFunctionTriplet(visit, "lessThan(", useEmulatedFunction);
break;
@@ -749,6 +944,9 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpMod:
writeBuiltInFunctionTriplet(visit, "mod(", useEmulatedFunction);
break;
+ case EOpModf:
+ writeBuiltInFunctionTriplet(visit, "modf(", useEmulatedFunction);
+ break;
case EOpPow:
writeBuiltInFunctionTriplet(visit, "pow(", useEmulatedFunction);
break;
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.h b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.h
index e5174f5660..4e66059c21 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.h
+++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
-#define CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
+#ifndef COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
+#define COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
#include <set>
@@ -21,7 +21,13 @@ class TOutputGLSLBase : public TIntermTraverser
ShHashFunction64 hashFunction,
NameMap &nameMap,
TSymbolTable& symbolTable,
- int shaderVersion);
+ int shaderVersion,
+ ShShaderOutput output);
+
+ ShShaderOutput getShaderOutput() const
+ {
+ return mOutput;
+ }
protected:
TInfoSinkBase &objSink() { return mObjSink; }
@@ -37,6 +43,8 @@ class TOutputGLSLBase : public TIntermTraverser
virtual bool visitBinary(Visit visit, TIntermBinary *node);
virtual bool visitUnary(Visit visit, TIntermUnary *node);
virtual bool visitSelection(Visit visit, TIntermSelection *node);
+ virtual bool visitSwitch(Visit visit, TIntermSwitch *node);
+ virtual bool visitCase(Visit visit, TIntermCase *node);
virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
virtual bool visitLoop(Visit visit, TIntermLoop *node);
virtual bool visitBranch(Visit visit, TIntermBranch *node);
@@ -78,6 +86,8 @@ class TOutputGLSLBase : public TIntermTraverser
TSymbolTable &mSymbolTable;
const int mShaderVersion;
+
+ ShShaderOutput mOutput;
};
-#endif // CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
+#endif // COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
index 30bbbff0f5..94225b81c4 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
@@ -6,26 +6,29 @@
#include "compiler/translator/OutputHLSL.h"
+#include <algorithm>
+#include <cfloat>
+#include <stdio.h>
+
#include "common/angleutils.h"
#include "common/utilities.h"
-#include "common/blocklayout.h"
-#include "compiler/translator/compilerdebug.h"
-#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
#include "compiler/translator/DetectDiscontinuity.h"
-#include "compiler/translator/SearchSymbol.h"
-#include "compiler/translator/UnfoldShortCircuit.h"
#include "compiler/translator/FlagStd140Structs.h"
+#include "compiler/translator/InfoSink.h"
#include "compiler/translator/NodeSearch.h"
+#include "compiler/translator/RemoveSwitchFallThrough.h"
#include "compiler/translator/RewriteElseBlocks.h"
-#include "compiler/translator/UtilsHLSL.h"
-#include "compiler/translator/util.h"
-#include "compiler/translator/UniformHLSL.h"
+#include "compiler/translator/SearchSymbol.h"
#include "compiler/translator/StructureHLSL.h"
#include "compiler/translator/TranslatorHLSL.h"
-
-#include <algorithm>
-#include <cfloat>
-#include <stdio.h>
+#include "compiler/translator/UnfoldShortCircuit.h"
+#include "compiler/translator/UniformHLSL.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/blocklayout.h"
+#include "compiler/translator/compilerdebug.h"
+#include "compiler/translator/util.h"
namespace sh
{
@@ -94,12 +97,21 @@ bool OutputHLSL::TextureFunction::operator<(const TextureFunction &rhs) const
return false;
}
-OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
+OutputHLSL::OutputHLSL(sh::GLenum shaderType, int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ const char *sourcePath, ShShaderOutput outputType,
+ int numRenderTargets, const std::vector<Uniform> &uniforms,
+ int compileOptions)
: TIntermTraverser(true, true, true),
- mContext(context),
- mOutputType(parentTranslator->getOutputType())
+ mShaderType(shaderType),
+ mShaderVersion(shaderVersion),
+ mExtensionBehavior(extensionBehavior),
+ mSourcePath(sourcePath),
+ mOutputType(outputType),
+ mNumRenderTargets(numRenderTargets),
+ mCompileOptions(compileOptions)
{
- mUnfoldShortCircuit = new UnfoldShortCircuit(context, this);
+ mUnfoldShortCircuit = new UnfoldShortCircuit(this);
mInsideFunction = false;
mUsesFragColor = false;
@@ -109,28 +121,12 @@ OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
mUsesPointCoord = false;
mUsesFrontFacing = false;
mUsesPointSize = false;
+ mUsesInstanceID = false;
mUsesFragDepth = false;
mUsesXor = false;
- mUsesMod1 = false;
- mUsesMod2v = false;
- mUsesMod2f = false;
- mUsesMod3v = false;
- mUsesMod3f = false;
- mUsesMod4v = false;
- mUsesMod4f = false;
- mUsesFaceforward1 = false;
- mUsesFaceforward2 = false;
- mUsesFaceforward3 = false;
- mUsesFaceforward4 = false;
- mUsesAtan2_1 = false;
- mUsesAtan2_2 = false;
- mUsesAtan2_3 = false;
- mUsesAtan2_4 = false;
mUsesDiscardRewriting = false;
mUsesNestedBreak = false;
-
- const ShBuiltInResources &resources = parentTranslator->getResources();
- mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
+ mRequiresIEEEStrictCompiling = false;
mUniqueIndex = 0;
@@ -143,20 +139,14 @@ OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
mExcessiveLoopIndex = NULL;
mStructureHLSL = new StructureHLSL;
- mUniformHLSL = new UniformHLSL(mStructureHLSL, parentTranslator);
+ mUniformHLSL = new UniformHLSL(mStructureHLSL, outputType, uniforms);
if (mOutputType == SH_HLSL9_OUTPUT)
{
- if (mContext.shaderType == GL_FRAGMENT_SHADER)
- {
- // Reserve registers for dx_DepthRange, dx_ViewCoords and dx_DepthFront
- mUniformHLSL->reserveUniformRegisters(3);
- }
- else
- {
- // Reserve registers for dx_DepthRange and dx_ViewAdjust
- mUniformHLSL->reserveUniformRegisters(2);
- }
+ // Fragment shaders need dx_DepthRange, dx_ViewCoords and dx_DepthFront.
+ // Vertex shaders need a slightly different set: dx_DepthRange, dx_ViewCoords and dx_ViewAdjust.
+ // In both cases total 3 uniform registers need to be reserved.
+ mUniformHLSL->reserveUniformRegisters(3);
}
// Reserve registers for the default uniform block and driver constants
@@ -168,27 +158,55 @@ OutputHLSL::~OutputHLSL()
SafeDelete(mUnfoldShortCircuit);
SafeDelete(mStructureHLSL);
SafeDelete(mUniformHLSL);
+ for (auto it = mStructEqualityFunctions.begin(); it != mStructEqualityFunctions.end(); ++it)
+ {
+ SafeDelete(*it);
+ }
+ for (auto it = mArrayEqualityFunctions.begin(); it != mArrayEqualityFunctions.end(); ++it)
+ {
+ SafeDelete(*it);
+ }
}
-void OutputHLSL::output()
+void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink)
{
- mContainsLoopDiscontinuity = mContext.shaderType == GL_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot);
- mContainsAnyLoop = containsAnyLoop(mContext.treeRoot);
- const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot);
+ mContainsLoopDiscontinuity = mShaderType == GL_FRAGMENT_SHADER && containsLoopDiscontinuity(treeRoot);
+ mContainsAnyLoop = containsAnyLoop(treeRoot);
+ const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(treeRoot);
makeFlaggedStructMaps(flaggedStructs);
// 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 (mOutputType == SH_HLSL9_OUTPUT && mContext.shaderType == GL_VERTEX_SHADER)
+ if (mOutputType == SH_HLSL9_OUTPUT && mShaderType == GL_VERTEX_SHADER)
+ {
+ RewriteElseBlocks(treeRoot);
+ }
+
+ BuiltInFunctionEmulator builtInFunctionEmulator;
+ InitBuiltInFunctionEmulatorForHLSL(&builtInFunctionEmulator);
+ builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(treeRoot);
+
+ // 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);
+ if (!mDeferredGlobalInitializers.empty())
{
- RewriteElseBlocks(mContext.treeRoot);
+ writeDeferredGlobalInitializers(mFooter);
}
+ mInfoSinkStack.pop();
+
+ mInfoSinkStack.push(&mHeader);
+ header(&builtInFunctionEmulator);
+ mInfoSinkStack.pop();
- mContext.treeRoot->traverse(this); // Output the body first to determine what has to go in the header
- header();
+ objSink << mHeader.c_str();
+ objSink << mBody.c_str();
+ objSink << mFooter.c_str();
- mContext.infoSink().obj << mHeader.c_str();
- mContext.infoSink().obj << mBody.c_str();
+ builtInFunctionEmulator.Cleanup();
}
void OutputHLSL::makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs)
@@ -197,10 +215,14 @@ void OutputHLSL::makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flagge
{
TIntermTyped *flaggedNode = flaggedStructs[structIndex];
+ TInfoSinkBase structInfoSink;
+ mInfoSinkStack.push(&structInfoSink);
+
// This will mark the necessary block elements as referenced
flaggedNode->traverse(this);
- TString structName(mBody.c_str());
- mBody.erase();
+
+ TString structName(structInfoSink.c_str());
+ mInfoSinkStack.pop();
mFlaggedStructOriginalNames[flaggedNode] = structName;
@@ -213,11 +235,6 @@ void OutputHLSL::makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flagge
}
}
-TInfoSinkBase &OutputHLSL::getBodyStream()
-{
- return mBody;
-}
-
const std::map<std::string, unsigned int> &OutputHLSL::getInterfaceBlockRegisterMap() const
{
return mUniformHLSL->getInterfaceBlockRegisterMap();
@@ -277,9 +294,9 @@ TString OutputHLSL::structInitializerString(int indent, const TStructure &struct
return init;
}
-void OutputHLSL::header()
+void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator)
{
- TInfoSinkBase &out = mHeader;
+ TInfoSinkBase &out = getInfoSink();
TString varyings;
TString attributes;
@@ -320,6 +337,23 @@ void OutputHLSL::header()
out << mUniformHLSL->uniformsHeader(mOutputType, mReferencedUniforms);
out << mUniformHLSL->interfaceBlocksHeader(mReferencedInterfaceBlocks);
+ if (!mEqualityFunctions.empty())
+ {
+ out << "\n// Equality functions\n\n";
+ for (auto it = mEqualityFunctions.cbegin(); it != mEqualityFunctions.cend(); ++it)
+ {
+ out << (*it)->functionDefinition << "\n";
+ }
+ }
+ if (!mArrayAssignmentFunctions.empty())
+ {
+ out << "\n// Assignment functions\n\n";
+ for (auto it = mArrayAssignmentFunctions.cbegin(); it != mArrayAssignmentFunctions.cend(); ++it)
+ {
+ out << it->functionDefinition << "\n";
+ }
+ }
+
if (mUsesDiscardRewriting)
{
out << "#define ANGLE_USES_DISCARD_REWRITING\n";
@@ -330,6 +364,11 @@ void OutputHLSL::header()
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"
@@ -338,16 +377,16 @@ void OutputHLSL::header()
"#define FLATTEN\n"
"#endif\n";
- if (mContext.shaderType == GL_FRAGMENT_SHADER)
+ if (mShaderType == GL_FRAGMENT_SHADER)
{
- TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
- const bool usingMRTExtension = (iter != mContext.extensionBehavior().end() && (iter->second == EBhEnable || iter->second == EBhRequire));
+ TExtensionBehavior::const_iterator iter = mExtensionBehavior.find("GL_EXT_draw_buffers");
+ const bool usingMRTExtension = (iter != mExtensionBehavior.end() && (iter->second == EBhEnable || iter->second == EBhRequire));
out << "// Varyings\n";
out << varyings;
out << "\n";
- if (mContext.getShaderVersion() >= 300)
+ if (mShaderVersion >= 300)
{
for (ReferencedSymbols::const_iterator outputVariableIt = mReferencedOutputVariables.begin(); outputVariableIt != mReferencedOutputVariables.end(); outputVariableIt++)
{
@@ -493,6 +532,11 @@ void OutputHLSL::header()
out << "static float gl_PointSize = float(1);\n";
}
+ if (mUsesInstanceID)
+ {
+ out << "static int gl_InstanceID;";
+ }
+
out << "\n"
"// Varyings\n";
out << varyings;
@@ -511,14 +555,22 @@ void OutputHLSL::header()
if (mOutputType == SH_HLSL11_OUTPUT)
{
+ out << "cbuffer DriverConstants : register(b1)\n"
+ "{\n";
+
if (mUsesDepthRange)
{
- out << "cbuffer DriverConstants : register(b1)\n"
- "{\n"
- " float3 dx_DepthRange : packoffset(c0);\n"
- "};\n"
- "\n";
+ 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 << "};\n"
+ "\n";
}
else
{
@@ -527,7 +579,8 @@ void OutputHLSL::header()
out << "uniform float3 dx_DepthRange : register(c0);\n";
}
- out << "uniform float4 dx_ViewAdjust : register(c1);\n"
+ out << "uniform float4 dx_ViewAdjust : register(c1);\n";
+ out << "uniform float2 dx_ViewCoords : register(c2);\n"
"\n";
}
@@ -980,7 +1033,15 @@ void OutputHLSL::header()
}
else if (IsShadowSampler(textureFunction->sampler))
{
- out << "x.SampleCmp(s, ";
+ switch(textureFunction->method)
+ {
+ case TextureFunction::IMPLICIT: out << "x.SampleCmp(s, "; break;
+ case TextureFunction::BIAS: out << "x.SampleCmp(s, "; break;
+ case TextureFunction::LOD: out << "x.SampleCmp(s, "; break;
+ case TextureFunction::LOD0: out << "x.SampleCmpLevelZero(s, "; break;
+ case TextureFunction::LOD0BIAS: out << "x.SampleCmpLevelZero(s, "; break;
+ default: UNREACHABLE();
+ }
}
else
{
@@ -1111,11 +1172,20 @@ void OutputHLSL::header()
else if (IsShadowSampler(textureFunction->sampler))
{
// Compare value
- switch(textureFunction->coords)
+ if (textureFunction->proj)
{
- case 3: out << "), t.z"; break;
- case 4: out << "), t.w"; break;
- default: UNREACHABLE();
+ // 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 << "), t.z" << proj;
+ }
+ else
+ {
+ switch(textureFunction->coords)
+ {
+ case 3: out << "), t.z"; break;
+ case 4: out << "), t.w"; break;
+ default: UNREACHABLE();
+ }
}
}
else
@@ -1131,11 +1201,20 @@ void OutputHLSL::header()
else if (IsShadowSampler(textureFunction->sampler))
{
// Compare value
- switch(textureFunction->coords)
+ if (textureFunction->proj)
{
- case 3: out << "), t.z"; break;
- case 4: out << "), t.w"; break;
- default: UNREACHABLE();
+ // 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 << "), t.z" << proj;
+ }
+ else
+ {
+ switch(textureFunction->coords)
+ {
+ case 3: out << "), t.z"; break;
+ case 4: out << "), t.w"; break;
+ default: UNREACHABLE();
+ }
}
}
else
@@ -1205,179 +1284,12 @@ void OutputHLSL::header()
"\n";
}
- if (mUsesMod1)
- {
- out << "float mod(float x, float y)\n"
- "{\n"
- " return x - y * floor(x / y);\n"
- "}\n"
- "\n";
- }
-
- if (mUsesMod2v)
- {
- out << "float2 mod(float2 x, float2 y)\n"
- "{\n"
- " return x - y * floor(x / y);\n"
- "}\n"
- "\n";
- }
-
- if (mUsesMod2f)
- {
- out << "float2 mod(float2 x, float y)\n"
- "{\n"
- " return x - y * floor(x / y);\n"
- "}\n"
- "\n";
- }
-
- if (mUsesMod3v)
- {
- out << "float3 mod(float3 x, float3 y)\n"
- "{\n"
- " return x - y * floor(x / y);\n"
- "}\n"
- "\n";
- }
-
- if (mUsesMod3f)
- {
- out << "float3 mod(float3 x, float y)\n"
- "{\n"
- " return x - y * floor(x / y);\n"
- "}\n"
- "\n";
- }
-
- if (mUsesMod4v)
- {
- out << "float4 mod(float4 x, float4 y)\n"
- "{\n"
- " return x - y * floor(x / y);\n"
- "}\n"
- "\n";
- }
-
- if (mUsesMod4f)
- {
- out << "float4 mod(float4 x, float y)\n"
- "{\n"
- " return x - y * floor(x / y);\n"
- "}\n"
- "\n";
- }
-
- if (mUsesFaceforward1)
- {
- out << "float faceforward(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"
- "\n";
- }
-
- if (mUsesFaceforward2)
- {
- out << "float2 faceforward(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"
- "\n";
- }
-
- if (mUsesFaceforward3)
- {
- out << "float3 faceforward(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"
- "\n";
- }
-
- if (mUsesFaceforward4)
- {
- out << "float4 faceforward(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"
- "\n";
- }
-
- if (mUsesAtan2_1)
- {
- out << "float atanyx(float y, float x)\n"
- "{\n"
- " if(x == 0 && y == 0) x = 1;\n" // Avoid producing a NaN
- " return atan2(y, x);\n"
- "}\n";
- }
-
- if (mUsesAtan2_2)
- {
- out << "float2 atanyx(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";
- }
-
- if (mUsesAtan2_3)
- {
- out << "float3 atanyx(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";
- }
-
- if (mUsesAtan2_4)
- {
- out << "float4 atanyx(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], x[2]), atan2(y[3], x[3]));\n"
- "}\n";
- }
+ builtInFunctionEmulator->OutputEmulatedFunctions(out);
}
void OutputHLSL::visitSymbol(TIntermSymbol *node)
{
- TInfoSinkBase &out = mBody;
+ TInfoSinkBase &out = getInfoSink();
// Handle accessing std140 structs by value
if (mFlaggedStructMappedNames.count(node) > 0)
@@ -1458,6 +1370,11 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
mUsesPointSize = true;
out << name;
}
+ else if (qualifier == EvqInstanceID)
+ {
+ mUsesInstanceID = true;
+ out << name;
+ }
else if (name == "gl_FragDepthEXT")
{
mUsesFragDepth = true;
@@ -1476,12 +1393,51 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
void OutputHLSL::visitRaw(TIntermRaw *node)
{
- mBody << node->getRawText();
+ getInfoSink() << node->getRawText();
+}
+
+void OutputHLSL::outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out)
+{
+ if (type.isScalar() && !type.isArray())
+ {
+ if (op == EOpEqual)
+ {
+ outputTriplet(visit, "(", " == ", ")", out);
+ }
+ else
+ {
+ outputTriplet(visit, "(", " != ", ")", out);
+ }
+ }
+ else
+ {
+ if (visit == PreVisit && op == EOpNotEqual)
+ {
+ out << "!";
+ }
+
+ if (type.isArray())
+ {
+ const TString &functionName = addArrayEqualityFunction(type);
+ outputTriplet(visit, (functionName + "(").c_str(), ", ", ")", out);
+ }
+ else if (type.getBasicType() == EbtStruct)
+ {
+ const TStructure &structure = *type.getStruct();
+ const TString &functionName = addStructEqualityFunction(structure);
+ outputTriplet(visit, (functionName + "(").c_str(), ", ", ")", out);
+ }
+ else
+ {
+ ASSERT(type.isMatrix() || type.isVector());
+ outputTriplet(visit, "all(", " == ", ")", out);
+ }
+ }
}
bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
{
- TInfoSinkBase &out = mBody;
+ TInfoSinkBase &out = getInfoSink();
// Handle accessing std140 structs by value
if (mFlaggedStructMappedNames.count(node) > 0)
@@ -1492,7 +1448,17 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
switch (node->getOp())
{
- case EOpAssign: outputTriplet(visit, "(", " = ", ")"); break;
+ case EOpAssign:
+ if (node->getLeft()->isArray())
+ {
+ const TString &functionName = addArrayAssignmentFunction(node->getType());
+ outputTriplet(visit, (functionName + "(").c_str(), ", ", ")");
+ }
+ else
+ {
+ outputTriplet(visit, "(", " = ", ")");
+ }
+ break;
case EOpInitialize:
if (visit == PreVisit)
{
@@ -1502,22 +1468,21 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
// this to "float t = x, x = t;".
TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode();
+ ASSERT(symbolNode);
TIntermTyped *expression = node->getRight();
- sh::SearchSymbol searchSymbol(symbolNode->getSymbol());
- expression->traverse(&searchSymbol);
- bool sameSymbol = searchSymbol.foundMatch();
-
- if (sameSymbol)
+ // TODO (jmadill): do a 'deep' scan to know if an expression is statically const
+ if (symbolNode->getQualifier() == EvqGlobal && expression->getQualifier() != EvqConst)
{
- // Type already printed
- out << "t" + str(mUniqueIndex) + " = ";
- expression->traverse(this);
- out << ", ";
- symbolNode->traverse(this);
- out << " = t" + str(mUniqueIndex);
-
- mUniqueIndex++;
+ // For variables which are not constant, defer their real initialization until
+ // after we initialize other globals: uniforms, attributes and varyings.
+ mDeferredGlobalInitializers.push_back(std::make_pair(symbolNode, expression));
+ const TString &initString = initializer(node->getType());
+ node->setRight(new TIntermRaw(node->getType(), initString));
+ }
+ else if (writeSameSymbolInitializer(out, symbolNode, expression))
+ {
+ // Skip initializing the rest of the expression
return false;
}
}
@@ -1554,16 +1519,22 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
}
else if (visit == InVisit)
{
- out << " = mul(";
+ out << " = transpose(mul(transpose(";
node->getLeft()->traverse(this);
- out << ", ";
+ out << "), transpose(";
}
else
{
- out << "))";
+ out << "))))";
}
break;
case EOpDivAssign: outputTriplet(visit, "(", " /= ", ")"); break;
+ case EOpIModAssign: outputTriplet(visit, "(", " %= ", ")"); break;
+ case EOpBitShiftLeftAssign: outputTriplet(visit, "(", " <<= ", ")"); break;
+ case EOpBitShiftRightAssign: outputTriplet(visit, "(", " >>= ", ")"); break;
+ case EOpBitwiseAndAssign: outputTriplet(visit, "(", " &= ", ")"); break;
+ case EOpBitwiseXorAssign: outputTriplet(visit, "(", " ^= ", ")"); break;
+ case EOpBitwiseOrAssign: outputTriplet(visit, "(", " |= ", ")"); break;
case EOpIndexDirect:
{
const TType& leftType = node->getLeft()->getType();
@@ -1651,65 +1622,15 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
case EOpSub: outputTriplet(visit, "(", " - ", ")"); break;
case EOpMul: outputTriplet(visit, "(", " * ", ")"); break;
case EOpDiv: outputTriplet(visit, "(", " / ", ")"); break;
+ case EOpIMod: outputTriplet(visit, "(", " % ", ")"); break;
+ case EOpBitShiftLeft: outputTriplet(visit, "(", " << ", ")"); break;
+ case EOpBitShiftRight: outputTriplet(visit, "(", " >> ", ")"); break;
+ case EOpBitwiseAnd: outputTriplet(visit, "(", " & ", ")"); break;
+ case EOpBitwiseXor: outputTriplet(visit, "(", " ^ ", ")"); break;
+ case EOpBitwiseOr: outputTriplet(visit, "(", " | ", ")"); break;
case EOpEqual:
case EOpNotEqual:
- if (node->getLeft()->isScalar())
- {
- if (node->getOp() == EOpEqual)
- {
- outputTriplet(visit, "(", " == ", ")");
- }
- else
- {
- outputTriplet(visit, "(", " != ", ")");
- }
- }
- else if (node->getLeft()->getBasicType() == EbtStruct)
- {
- if (node->getOp() == EOpEqual)
- {
- out << "(";
- }
- else
- {
- out << "!(";
- }
-
- const TStructure &structure = *node->getLeft()->getType().getStruct();
- const TFieldList &fields = structure.fields();
-
- for (size_t i = 0; i < fields.size(); i++)
- {
- const TField *field = fields[i];
-
- node->getLeft()->traverse(this);
- out << "." + DecorateField(field->name(), structure) + " == ";
- node->getRight()->traverse(this);
- out << "." + DecorateField(field->name(), structure);
-
- if (i < fields.size() - 1)
- {
- out << " && ";
- }
- }
-
- out << ")";
-
- return false;
- }
- else
- {
- ASSERT(node->getLeft()->isMatrix() || node->getLeft()->isVector());
-
- if (node->getOp() == EOpEqual)
- {
- outputTriplet(visit, "all(", " == ", ")");
- }
- else
- {
- outputTriplet(visit, "!all(", " == ", ")");
- }
- }
+ outputEqual(visit, node->getLeft()->getType(), node->getOp(), out);
break;
case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break;
case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break;
@@ -1760,6 +1681,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
case EOpPositive: outputTriplet(visit, "(+", "", ")"); break;
case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
+ case EOpBitwiseNot: outputTriplet(visit, "(~", "", ")"); break;
case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break;
case EOpPostDecrement: outputTriplet(visit, "(", "", "--)"); break;
case EOpPreIncrement: outputTriplet(visit, "(++", "", ")"); break;
@@ -1772,6 +1694,21 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
case EOpAsin: outputTriplet(visit, "asin(", "", ")"); break;
case EOpAcos: outputTriplet(visit, "acos(", "", ")"); break;
case EOpAtan: outputTriplet(visit, "atan(", "", ")"); break;
+ case EOpSinh: outputTriplet(visit, "sinh(", "", ")"); break;
+ case EOpCosh: outputTriplet(visit, "cosh(", "", ")"); break;
+ case EOpTanh: outputTriplet(visit, "tanh(", "", ")"); break;
+ case EOpAsinh:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "asinh(");
+ break;
+ case EOpAcosh:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "acosh(");
+ break;
+ case EOpAtanh:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "atanh(");
+ break;
case EOpExp: outputTriplet(visit, "exp(", "", ")"); break;
case EOpLog: outputTriplet(visit, "log(", "", ")"); break;
case EOpExp2: outputTriplet(visit, "exp2(", "", ")"); break;
@@ -1781,8 +1718,47 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
case EOpAbs: outputTriplet(visit, "abs(", "", ")"); break;
case EOpSign: outputTriplet(visit, "sign(", "", ")"); break;
case EOpFloor: outputTriplet(visit, "floor(", "", ")"); break;
+ case EOpTrunc: outputTriplet(visit, "trunc(", "", ")"); break;
+ case EOpRound: outputTriplet(visit, "round(", "", ")"); break;
+ case EOpRoundEven:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "roundEven(");
+ break;
case EOpCeil: outputTriplet(visit, "ceil(", "", ")"); break;
case EOpFract: outputTriplet(visit, "frac(", "", ")"); break;
+ case EOpIsNan:
+ outputTriplet(visit, "isnan(", "", ")");
+ mRequiresIEEEStrictCompiling = true;
+ break;
+ case EOpIsInf: outputTriplet(visit, "isinf(", "", ")"); break;
+ case EOpFloatBitsToInt: outputTriplet(visit, "asint(", "", ")"); break;
+ case EOpFloatBitsToUint: outputTriplet(visit, "asuint(", "", ")"); break;
+ case EOpIntBitsToFloat: outputTriplet(visit, "asfloat(", "", ")"); break;
+ case EOpUintBitsToFloat: outputTriplet(visit, "asfloat(", "", ")"); break;
+ case EOpPackSnorm2x16:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "packSnorm2x16(");
+ break;
+ case EOpPackUnorm2x16:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "packUnorm2x16(");
+ break;
+ case EOpPackHalf2x16:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "packHalf2x16(");
+ break;
+ case EOpUnpackSnorm2x16:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "unpackSnorm2x16(");
+ break;
+ case EOpUnpackUnorm2x16:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "unpackUnorm2x16(");
+ break;
+ case EOpUnpackHalf2x16:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "unpackHalf2x16(");
+ break;
case EOpLength: outputTriplet(visit, "length(", "", ")"); break;
case EOpNormalize: outputTriplet(visit, "normalize(", "", ")"); break;
case EOpDFdx:
@@ -1815,6 +1791,13 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
outputTriplet(visit, "fwidth(", "", ")");
}
break;
+ case EOpTranspose: outputTriplet(visit, "transpose(", "", ")"); break;
+ case EOpDeterminant: outputTriplet(visit, "determinant(transpose(", "", "))"); break;
+ case EOpInverse:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "inverse(");
+ break;
+
case EOpAny: outputTriplet(visit, "any(", "", ")"); break;
case EOpAll: outputTriplet(visit, "all(", "", ")"); break;
default: UNREACHABLE();
@@ -1825,7 +1808,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
- TInfoSinkBase &out = mBody;
+ TInfoSinkBase &out = getInfoSink();
switch (node->getOp())
{
@@ -1843,7 +1826,11 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
traverseStatements(*sit);
- out << ";\n";
+ // 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.
+ if ((*sit)->getAsCaseNode() == nullptr)
+ out << ";\n";
}
if (mInsideFunction)
@@ -1871,11 +1858,12 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
{
- for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
+ for (auto it = sequence->cbegin(); it != sequence->cend(); ++it)
{
- if (isSingleStatement(*sit))
+ const auto &seqElement = *it;
+ if (isSingleStatement(seqElement))
{
- mUnfoldShortCircuit->traverse(*sit);
+ mUnfoldShortCircuit->traverse(seqElement);
}
if (!mInsideFunction)
@@ -1885,7 +1873,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
out << TypeString(variable->getType()) + " ";
- TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
+ TIntermSymbol *symbol = seqElement->getAsSymbolNode();
if (symbol)
{
@@ -1895,10 +1883,10 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
}
else
{
- (*sit)->traverse(this);
+ seqElement->traverse(this);
}
- if (*sit != sequence->back())
+ if (seqElement != sequence->back())
{
out << ";\n";
}
@@ -2149,7 +2137,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
bool bias = (arguments->size() > mandatoryArgumentCount); // Bias argument is optional
- if (lod0 || mContext.shaderType == GL_VERTEX_SHADER)
+ if (lod0 || mShaderType == GL_VERTEX_SHADER)
{
if (bias)
{
@@ -2217,7 +2205,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
const TString &structName = StructNameString(*node->getType().getStruct());
mStructureHLSL->addConstructor(node->getType(), structName, node->getSequence());
- outputTriplet(visit, structName + "_ctor(", ", ", ")");
+ outputTriplet(visit, (structName + "_ctor(").c_str(), ", ", ")");
}
break;
case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break;
@@ -2227,37 +2215,15 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpVectorEqual: outputTriplet(visit, "(", " == ", ")"); break;
case EOpVectorNotEqual: outputTriplet(visit, "(", " != ", ")"); break;
case EOpMod:
- {
- // We need to look at the number of components in both arguments
- const int modValue = (*node->getSequence())[0]->getAsTyped()->getNominalSize() * 10 +
- (*node->getSequence())[1]->getAsTyped()->getNominalSize();
- switch (modValue)
- {
- case 11: mUsesMod1 = true; break;
- case 22: mUsesMod2v = true; break;
- case 21: mUsesMod2f = true; break;
- case 33: mUsesMod3v = true; break;
- case 31: mUsesMod3f = true; break;
- case 44: mUsesMod4v = true; break;
- case 41: mUsesMod4f = true; break;
- default: UNREACHABLE();
- }
-
- outputTriplet(visit, "mod(", ", ", ")");
- }
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "mod(");
break;
+ case EOpModf: outputTriplet(visit, "modf(", ", ", ")"); break;
case EOpPow: outputTriplet(visit, "pow(", ", ", ")"); break;
case EOpAtan:
ASSERT(node->getSequence()->size() == 2); // atan(x) is a unary operator
- switch ((*node->getSequence())[0]->getAsTyped()->getNominalSize())
- {
- case 1: mUsesAtan2_1 = true; break;
- case 2: mUsesAtan2_2 = true; break;
- case 3: mUsesAtan2_3 = true; break;
- case 4: mUsesAtan2_4 = true; break;
- default: UNREACHABLE();
- }
- outputTriplet(visit, "atanyx(", ", ", ")");
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "atan(");
break;
case EOpMin: outputTriplet(visit, "min(", ", ", ")"); break;
case EOpMax: outputTriplet(visit, "max(", ", ", ")"); break;
@@ -2269,21 +2235,15 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpDot: outputTriplet(visit, "dot(", ", ", ")"); break;
case EOpCross: outputTriplet(visit, "cross(", ", ", ")"); break;
case EOpFaceForward:
- {
- switch ((*node->getSequence())[0]->getAsTyped()->getNominalSize()) // Number of components in the first argument
- {
- case 1: mUsesFaceforward1 = true; break;
- case 2: mUsesFaceforward2 = true; break;
- case 3: mUsesFaceforward3 = true; break;
- case 4: mUsesFaceforward4 = true; break;
- default: UNREACHABLE();
- }
-
- outputTriplet(visit, "faceforward(", ", ", ")");
- }
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "faceforward(");
break;
case EOpReflect: outputTriplet(visit, "reflect(", ", ", ")"); break;
case EOpRefract: outputTriplet(visit, "refract(", ", ", ")"); break;
+ case EOpOuterProduct:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(visit, "outerProduct(");
+ break;
case EOpMul: outputTriplet(visit, "(", " * ", ")"); break;
default: UNREACHABLE();
}
@@ -2293,7 +2253,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
{
- TInfoSinkBase &out = mBody;
+ TInfoSinkBase &out = getInfoSink();
if (node->usesTernaryOperator())
{
@@ -2307,7 +2267,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
// however flattening all the ifs in branch heavy shaders made D3D error too.
// As a temporary workaround we flatten the ifs only if there is at least a loop
// present somewhere in the shader.
- if (mContext.shaderType == GL_FRAGMENT_SHADER && mContainsAnyLoop)
+ if (mShaderType == GL_FRAGMENT_SHADER && mContainsAnyLoop)
{
out << "FLATTEN ";
}
@@ -2361,6 +2321,37 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
return false;
}
+bool OutputHLSL::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ if (node->getStatementList())
+ {
+ node->setStatementList(RemoveSwitchFallThrough::removeFallThrough(node->getStatementList()));
+ outputTriplet(visit, "switch (", ") ", "");
+ // The curly braces get written when visiting the statementList aggregate
+ }
+ else
+ {
+ // No statementList, so it won't output curly braces
+ outputTriplet(visit, "switch (", ") {", "}\n");
+ }
+ return true;
+}
+
+bool OutputHLSL::visitCase(Visit visit, TIntermCase *node)
+{
+ if (node->hasCondition())
+ {
+ outputTriplet(visit, "case (", "", "):\n");
+ return true;
+ }
+ else
+ {
+ TInfoSinkBase &out = getInfoSink();
+ out << "default:\n";
+ return false;
+ }
+}
+
void OutputHLSL::visitConstantUnion(TIntermConstantUnion *node)
{
writeConstantUnion(node->getType(), node->getUnionArrayPointer());
@@ -2388,7 +2379,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
}
}
- TInfoSinkBase &out = mBody;
+ TInfoSinkBase &out = getInfoSink();
if (node->getType() == ELoopDoWhile)
{
@@ -2454,7 +2445,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node)
{
- TInfoSinkBase &out = mBody;
+ TInfoSinkBase &out = getInfoSink();
switch (node->getFlowOp())
{
@@ -2556,7 +2547,7 @@ bool OutputHLSL::isSingleStatement(TIntermNode *node)
bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
{
const int MAX_LOOP_ITERATIONS = 254;
- TInfoSinkBase &out = mBody;
+ TInfoSinkBase &out = getInfoSink();
// Parse loops of the form:
// for(int index = initial; index [comparator] limit; index += increment)
@@ -2756,10 +2747,8 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
return false; // Not handled as an excessive loop
}
-void OutputHLSL::outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString)
+void OutputHLSL::outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString, TInfoSinkBase &out)
{
- TInfoSinkBase &out = mBody;
-
if (visit == PreVisit)
{
out << preString;
@@ -2774,19 +2763,26 @@ void OutputHLSL::outputTriplet(Visit visit, const TString &preString, const TStr
}
}
+void OutputHLSL::outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString)
+{
+ outputTriplet(visit, preString, inString, postString, getInfoSink());
+}
+
void OutputHLSL::outputLineDirective(int line)
{
- if ((mContext.compileOptions & SH_LINE_DIRECTIVES) && (line > 0))
+ if ((mCompileOptions & SH_LINE_DIRECTIVES) && (line > 0))
{
- mBody << "\n";
- mBody << "#line " << line;
+ TInfoSinkBase &out = getInfoSink();
+
+ out << "\n";
+ out << "#line " << line;
- if (mContext.sourcePath)
+ if (mSourcePath)
{
- mBody << " \"" << mContext.sourcePath << "\"";
+ out << " \"" << mSourcePath << "\"";
}
- mBody << "\n";
+ out << "\n";
}
}
@@ -2832,15 +2828,15 @@ TString OutputHLSL::initializer(const TType &type)
return "{" + string + "}";
}
-void OutputHLSL::outputConstructor(Visit visit, const TType &type, const TString &name, const TIntermSequence *parameters)
+void OutputHLSL::outputConstructor(Visit visit, const TType &type, const char *name, const TIntermSequence *parameters)
{
- TInfoSinkBase &out = mBody;
+ TInfoSinkBase &out = getInfoSink();
if (visit == PreVisit)
{
mStructureHLSL->addConstructor(type, name, parameters);
- out << name + "(";
+ out << name << "(";
}
else if (visit == InVisit)
{
@@ -2854,7 +2850,7 @@ void OutputHLSL::outputConstructor(Visit visit, const TType &type, const TString
const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const ConstantUnion *constUnion)
{
- TInfoSinkBase &out = mBody;
+ TInfoSinkBase &out = getInfoSink();
const TStructure* structure = type.getStruct();
if (structure)
@@ -2912,4 +2908,209 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
return constUnion;
}
+void OutputHLSL::writeEmulatedFunctionTriplet(Visit visit, const char *preStr)
+{
+ TString preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preStr);
+ outputTriplet(visit, preString.c_str(), ", ", ")");
+}
+
+bool OutputHLSL::writeSameSymbolInitializer(TInfoSinkBase &out, TIntermSymbol *symbolNode, TIntermTyped *expression)
+{
+ sh::SearchSymbol searchSymbol(symbolNode->getSymbol());
+ expression->traverse(&searchSymbol);
+
+ if (searchSymbol.foundMatch())
+ {
+ // Type already printed
+ out << "t" + str(mUniqueIndex) + " = ";
+ expression->traverse(this);
+ out << ", ";
+ symbolNode->traverse(this);
+ out << " = t" + str(mUniqueIndex);
+
+ mUniqueIndex++;
+ return true;
+ }
+
+ return false;
+}
+
+void OutputHLSL::writeDeferredGlobalInitializers(TInfoSinkBase &out)
+{
+ out << "#define ANGLE_USES_DEFERRED_INIT\n"
+ << "\n"
+ << "void initializeDeferredGlobals()\n"
+ << "{\n";
+
+ for (auto it = mDeferredGlobalInitializers.cbegin(); it != mDeferredGlobalInitializers.cend(); ++it)
+ {
+ const auto &deferredGlobal = *it;
+ TIntermSymbol *symbol = deferredGlobal.first;
+ TIntermTyped *expression = deferredGlobal.second;
+ ASSERT(symbol);
+ ASSERT(symbol->getQualifier() == EvqGlobal && expression->getQualifier() != EvqConst);
+
+ out << " " << Decorate(symbol->getSymbol()) << " = ";
+
+ if (!writeSameSymbolInitializer(out, symbol, expression))
+ {
+ ASSERT(mInfoSinkStack.top() == &out);
+ expression->traverse(this);
+ }
+
+ out << ";\n";
+ }
+
+ out << "}\n"
+ << "\n";
+}
+
+TString OutputHLSL::addStructEqualityFunction(const TStructure &structure)
+{
+ const TFieldList &fields = structure.fields();
+
+ for (auto it = mStructEqualityFunctions.cbegin(); it != mStructEqualityFunctions.cend(); ++it)
+ {
+ auto *eqFunction = *it;
+ 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 (auto it = mArrayEqualityFunctions.cbegin(); it != mArrayEqualityFunctions.cend(); ++it)
+ {
+ const auto &eqFunction = *it;
+ if (eqFunction->type == type)
+ {
+ return eqFunction->functionName;
+ }
+ }
+
+ const TString &typeName = TypeString(type);
+
+ ArrayHelperFunction *function = new ArrayHelperFunction();
+ function->type = type;
+
+ TInfoSinkBase fnNameOut;
+ fnNameOut << "angle_eq_" << type.getArraySize() << "_" << typeName;
+ function->functionName = fnNameOut.c_str();
+
+ TType nonArrayType = type;
+ nonArrayType.clearArrayness();
+
+ TInfoSinkBase fnOut;
+
+ fnOut << "bool " << function->functionName << "("
+ << typeName << " a[" << type.getArraySize() << "], "
+ << typeName << " b[" << type.getArraySize() << "])\n"
+ << "{\n"
+ " for (int i = 0; i < " << type.getArraySize() << "; ++i)\n"
+ " {\n"
+ " if (";
+
+ outputEqual(PreVisit, nonArrayType, EOpNotEqual, fnOut);
+ fnOut << "a[i]";
+ outputEqual(InVisit, nonArrayType, EOpNotEqual, fnOut);
+ fnOut << "b[i]";
+ outputEqual(PostVisit, nonArrayType, 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 (auto it = mArrayAssignmentFunctions.cbegin(); it != mArrayAssignmentFunctions.cend(); ++it)
+ {
+ const auto &assignFunction = *it;
+ if (assignFunction.type == type)
+ {
+ return assignFunction.functionName;
+ }
+ }
+
+ const TString &typeName = TypeString(type);
+
+ ArrayHelperFunction function;
+ function.type = type;
+
+ TInfoSinkBase fnNameOut;
+ fnNameOut << "angle_assign_" << type.getArraySize() << "_" << typeName;
+ function.functionName = fnNameOut.c_str();
+
+ TInfoSinkBase fnOut;
+
+ fnOut << "void " << function.functionName << "(out "
+ << typeName << " a[" << type.getArraySize() << "], "
+ << typeName << " b[" << type.getArraySize() << "])\n"
+ << "{\n"
+ " for (int i = 0; i < " << type.getArraySize() << "; ++i)\n"
+ " {\n"
+ " a[i] = b[i];\n"
+ " }\n"
+ "}\n";
+
+ function.functionDefinition = fnOut.c_str();
+
+ mArrayAssignmentFunctions.push_back(function);
+
+ return function.functionName;
+}
+
}
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h
index 5525e6eaa6..51da877c72 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h
@@ -4,18 +4,20 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_OUTPUTHLSL_H_
-#define COMPILER_OUTPUTHLSL_H_
+#ifndef COMPILER_TRANSLATOR_OUTPUTHLSL_H_
+#define COMPILER_TRANSLATOR_OUTPUTHLSL_H_
#include <list>
#include <set>
#include <map>
+#include <stack>
#include "angle_gl.h"
-
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/ParseContext.h"
+class BuiltInFunctionEmulator;
+
namespace sh
{
class UnfoldShortCircuit;
@@ -27,20 +29,25 @@ typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
class OutputHLSL : public TIntermTraverser
{
public:
- OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator);
- ~OutputHLSL();
+ OutputHLSL(sh::GLenum shaderType, int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ const char *sourcePath, ShShaderOutput outputType,
+ int numRenderTargets, const std::vector<Uniform> &uniforms,
+ int compileOptions);
- void output();
+ ~OutputHLSL();
- TInfoSinkBase &getBodyStream();
+ void output(TIntermNode *treeRoot, TInfoSinkBase &objSink);
const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const;
const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
static TString initializer(const TType &type);
+ TInfoSinkBase &getInfoSink() { ASSERT(!mInfoSinkStack.empty()); return *mInfoSinkStack.top(); }
+
protected:
- void header();
+ void header(const BuiltInFunctionEmulator *builtInFunctionEmulator);
// Visit AST nodes and output their code to the body stream
void visitSymbol(TIntermSymbol*);
@@ -49,6 +56,8 @@ class OutputHLSL : public TIntermTraverser
bool visitBinary(Visit visit, TIntermBinary*);
bool visitUnary(Visit visit, TIntermUnary*);
bool visitSelection(Visit visit, TIntermSelection*);
+ bool visitSwitch(Visit visit, TIntermSwitch *);
+ bool visitCase(Visit visit, TIntermCase *);
bool visitAggregate(Visit visit, TIntermAggregate*);
bool visitLoop(Visit visit, TIntermLoop*);
bool visitBranch(Visit visit, TIntermBranch*);
@@ -56,16 +65,39 @@ class OutputHLSL : public TIntermTraverser
void traverseStatements(TIntermNode *node);
bool isSingleStatement(TIntermNode *node);
bool handleExcessiveLoop(TIntermLoop *node);
- void outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString);
+
+ // Emit one of three strings depending on traverse phase. Called with literal strings so using const char* instead of TString.
+ void outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString, TInfoSinkBase &out);
+ void outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString);
void outputLineDirective(int line);
TString argumentString(const TIntermSymbol *symbol);
int vectorSize(const TType &type) const;
- void outputConstructor(Visit visit, const TType &type, const TString &name, const TIntermSequence *parameters);
+ // Emit constructor. Called with literal names so using const char* instead of TString.
+ void outputConstructor(Visit visit, const TType &type, const char *name, const TIntermSequence *parameters);
const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *constUnion);
- TParseContext &mContext;
+ void outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out);
+
+ void writeEmulatedFunctionTriplet(Visit visit, const char *preStr);
+ void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs);
+
+ // 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);
+ void writeDeferredGlobalInitializers(TInfoSinkBase &out);
+
+ // Returns the function name
+ TString addStructEqualityFunction(const TStructure &structure);
+ TString addArrayEqualityFunction(const TType &type);
+ TString addArrayAssignmentFunction(const TType &type);
+
+ sh::GLenum mShaderType;
+ int mShaderVersion;
+ const TExtensionBehavior &mExtensionBehavior;
+ const char *mSourcePath;
const ShShaderOutput mOutputType;
+ int mCompileOptions;
+
UnfoldShortCircuit *mUnfoldShortCircuit;
bool mInsideFunction;
@@ -74,6 +106,11 @@ class OutputHLSL : public TIntermTraverser
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;
+
ReferencedSymbols mReferencedUniforms;
ReferencedSymbols mReferencedInterfaceBlocks;
ReferencedSymbols mReferencedAttributes;
@@ -119,25 +156,13 @@ class OutputHLSL : public TIntermTraverser
bool mUsesPointCoord;
bool mUsesFrontFacing;
bool mUsesPointSize;
+ bool mUsesInstanceID;
bool mUsesFragDepth;
bool mUsesXor;
- bool mUsesMod1;
- bool mUsesMod2v;
- bool mUsesMod2f;
- bool mUsesMod3v;
- bool mUsesMod3f;
- bool mUsesMod4v;
- bool mUsesMod4f;
- bool mUsesFaceforward1;
- bool mUsesFaceforward2;
- bool mUsesFaceforward3;
- bool mUsesFaceforward4;
- bool mUsesAtan2_1;
- bool mUsesAtan2_2;
- bool mUsesAtan2_3;
- bool mUsesAtan2_4;
bool mUsesDiscardRewriting;
bool mUsesNestedBreak;
+ bool mRequiresIEEEStrictCompiling;
+
int mNumRenderTargets;
@@ -156,9 +181,41 @@ class OutputHLSL : public TIntermTraverser
std::map<TIntermTyped*, TString> mFlaggedStructMappedNames;
std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames;
- void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs);
+ // Some initializers use varyings, uniforms or attributes, thus we can't evaluate some variables
+ // at global static scope in HLSL. These variables depend on values which we retrieve from the
+ // shader input structure, which we set in the D3D main function. Instead, we can initialize
+ // these static globals after we initialize our other globals.
+ std::vector<std::pair<TIntermSymbol*, TIntermTyped*>> mDeferredGlobalInitializers;
+
+ 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;
};
}
-#endif // COMPILER_OUTPUTHLSL_H_
+#endif // COMPILER_TRANSLATOR_OUTPUTHLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp b/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp
index 37969b5468..7ad3f817ad 100644
--- a/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp
@@ -9,8 +9,9 @@
#include <stdarg.h>
#include <stdio.h>
-#include "compiler/translator/glslang.h"
#include "compiler/preprocessor/SourceLocation.h"
+#include "compiler/translator/glslang.h"
+#include "compiler/translator/ValidateSwitch.h"
///////////////////////////////////////////////////////////////////////
//
@@ -796,9 +797,24 @@ bool TParseContext::arrayErrorCheck(const TSourceLoc& line, const TString& ident
bool sameScope = false;
TSymbol* symbol = symbolTable.find(identifier, 0, &builtIn, &sameScope);
if (symbol == 0 || !sameScope) {
- if (reservedErrorCheck(line, identifier))
- return true;
-
+ bool needsReservedErrorCheck = true;
+
+ // gl_LastFragData may be redeclared with a new precision qualifier
+ if (identifier.compare(0, 15, "gl_LastFragData") == 0) {
+ if (type.arraySize == static_cast<const TVariable*>(symbolTable.findBuiltIn("gl_MaxDrawBuffers", shaderVersion))->getConstPointer()->getIConst()) {
+ if (TSymbol* builtInSymbol = symbolTable.findBuiltIn(identifier, shaderVersion)) {
+ needsReservedErrorCheck = extensionErrorCheck(line, builtInSymbol->getExtension());
+ }
+ } else {
+ error(line, "redeclaration of array with size != gl_MaxDrawBuffers", identifier.c_str());
+ return true;
+ }
+ }
+
+ if (needsReservedErrorCheck)
+ if (reservedErrorCheck(line, identifier))
+ return true;
+
variable = new TVariable(&identifier, TType(type));
if (type.arraySize)
@@ -976,6 +992,26 @@ bool TParseContext::layoutLocationErrorCheck(const TSourceLoc& location, const T
return false;
}
+bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *aggregate)
+{
+ for (size_t i = 0; i < fnCandidate->getParamCount(); ++i)
+ {
+ TQualifier qual = fnCandidate->getParam(i).type->getQualifier();
+ if (qual == EvqOut || qual == EvqInOut)
+ {
+ TIntermTyped *node = (*(aggregate->getSequence()))[i]->getAsTyped();
+ if (lValueErrorCheck(node->getLine(), "assign", node))
+ {
+ error(node->getLine(),
+ "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
+ recover();
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
bool TParseContext::supportsExtension(const char* extension)
{
const TExtensionBehavior& extbehavior = extensionBehavior();
@@ -1062,14 +1098,14 @@ const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
//
// Return the function symbol if found, otherwise 0.
//
-const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, int shaderVersion, bool *builtIn)
+const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, int inputShaderVersion, bool *builtIn)
{
// First find by unmangled name to check whether the function name has been
// hidden by a variable name or struct typename.
// If a function is found, check for one with a matching argument list.
- const TSymbol* symbol = symbolTable.find(call->getName(), shaderVersion, builtIn);
+ const TSymbol* symbol = symbolTable.find(call->getName(), inputShaderVersion, builtIn);
if (symbol == 0 || symbol->isFunction()) {
- symbol = symbolTable.find(call->getMangledName(), shaderVersion, builtIn);
+ symbol = symbolTable.find(call->getMangledName(), inputShaderVersion, builtIn);
}
if (symbol == 0) {
@@ -1162,7 +1198,7 @@ bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& id
if (qualifier != EvqConst) {
TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
- intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line);
+ intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
if (intermNode == 0) {
assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
return true;
@@ -1375,7 +1411,7 @@ TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &inv
recover();
return NULL;
}
- symbolTable.addInvariantVarying(*identifier);
+ symbolTable.addInvariantVarying(std::string(identifier->c_str()));
const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
ASSERT(variable);
const TType &type = variable->getType();
@@ -1605,7 +1641,7 @@ TFunction *TParseContext::addConstructorFunc(TPublicType publicType)
//
// Returns 0 for an error or the constructed node (aggregate or typed) for no error.
//
-TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, const TType *type, TOperator op, TFunction *fnCall, const TSourceLoc &line)
+TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, TType *type, TOperator op, TFunction *fnCall, const TSourceLoc &line)
{
TIntermAggregate *aggregateArguments = arguments->getAsAggregate();
@@ -1633,13 +1669,21 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, const TType
}
// Turn the argument list itself into a constructor
- TIntermTyped *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
- TIntermTyped *constConstructor = foldConstConstructor(constructor->getAsAggregate(), *type);
+ TIntermAggregate *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line);
+ TIntermTyped *constConstructor = foldConstConstructor(constructor, *type);
if (constConstructor)
{
return constConstructor;
}
+ // Structs should not be precision qualified, the individual members may be.
+ // Built-in types on the other hand should be precision qualified.
+ if (op != EOpConstructStruct)
+ {
+ constructor->setPrecisionFromChildren();
+ type->setPrecision(constructor->getPrecision());
+ }
+
return constructor;
}
@@ -2028,9 +2072,11 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
recover();
}
- if (indexExpression->getQualifier() == EvqConst)
+ TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
+
+ if (indexExpression->getQualifier() == EvqConst && indexConstantUnion)
{
- int index = indexExpression->getAsConstantUnion()->getIConst(0);
+ int index = indexConstantUnion->getIConst(0);
if (index < 0)
{
std::stringstream infoStream;
@@ -2091,7 +2137,7 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
index = baseExpression->getType().getNominalSize() - 1;
}
- indexExpression->getAsConstantUnion()->getUnionArrayPointer()->setIConst(index);
+ indexConstantUnion->getUnionArrayPointer()->setIConst(index);
indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
}
}
@@ -2520,7 +2566,10 @@ TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSou
TStructure* structure = new TStructure(structName, fieldList);
TType* structureType = new TType(structure);
+ // Store a bool in the struct if we're at global scope, to allow us to
+ // skip the local struct scoping workaround in HLSL.
structure->setUniqueId(TSymbolTable::nextUniqueId());
+ structure->setAtGlobalScope(symbolTable.atGlobalLevel());
if (!structName->empty())
{
@@ -2560,6 +2609,553 @@ TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSou
return publicType;
}
+TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, TIntermAggregate *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");
+ recover();
+ return nullptr;
+ }
+
+ if (statementList)
+ {
+ if (!ValidateSwitch::validate(switchType, this, statementList, loc))
+ {
+ recover();
+ return nullptr;
+ }
+ }
+
+ TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc);
+ if (node == nullptr)
+ {
+ error(loc, "erroneous switch statement", "switch");
+ recover();
+ return nullptr;
+ }
+ return node;
+}
+
+TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
+{
+ if (mSwitchNestingLevel == 0)
+ {
+ error(loc, "case labels need to be inside switch statements", "case");
+ recover();
+ return nullptr;
+ }
+ if (condition == nullptr)
+ {
+ error(loc, "case label must have a condition", "case");
+ recover();
+ return nullptr;
+ }
+ if ((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) ||
+ condition->isMatrix() ||
+ condition->isArray() ||
+ condition->isVector())
+ {
+ error(condition->getLine(), "case label must be a scalar integer", "case");
+ recover();
+ }
+ TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
+ if (conditionConst == nullptr)
+ {
+ error(condition->getLine(), "case label must be constant", "case");
+ recover();
+ }
+ TIntermCase *node = intermediate.addCase(condition, loc);
+ if (node == nullptr)
+ {
+ error(loc, "erroneous case statement", "case");
+ recover();
+ return nullptr;
+ }
+ return node;
+}
+
+TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
+{
+ if (mSwitchNestingLevel == 0)
+ {
+ error(loc, "default labels need to be inside switch statements", "default");
+ recover();
+ return nullptr;
+ }
+ TIntermCase *node = intermediate.addCase(nullptr, loc);
+ if (node == nullptr)
+ {
+ error(loc, "erroneous default statement", "default");
+ recover();
+ return nullptr;
+ }
+ return node;
+}
+
+TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc,
+ const TType *funcReturnType)
+{
+ if (child == nullptr)
+ {
+ return nullptr;
+ }
+
+ switch (op)
+ {
+ case EOpLogicalNot:
+ if (child->getBasicType() != EbtBool ||
+ child->isMatrix() ||
+ child->isArray() ||
+ child->isVector())
+ {
+ return nullptr;
+ }
+ break;
+ case EOpBitwiseNot:
+ if ((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
+ child->isMatrix() ||
+ child->isArray())
+ {
+ return nullptr;
+ }
+ break;
+ case EOpPostIncrement:
+ case EOpPreIncrement:
+ case EOpPostDecrement:
+ case EOpPreDecrement:
+ case EOpNegative:
+ case EOpPositive:
+ if (child->getBasicType() == EbtStruct ||
+ child->getBasicType() == EbtBool ||
+ child->isArray())
+ {
+ return nullptr;
+ }
+ // Operators for built-ins are already type checked against their prototype.
+ default:
+ break;
+ }
+
+ return intermediate.addUnaryMath(op, child, loc, funcReturnType);
+}
+
+TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
+{
+ TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
+ if (node == nullptr)
+ {
+ unaryOpError(loc, GetOperatorString(op), child->getCompleteString());
+ recover();
+ return child;
+ }
+ return node;
+}
+
+TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
+{
+ if (lValueErrorCheck(loc, GetOperatorString(op), child))
+ recover();
+ return addUnaryMath(op, child, loc);
+}
+
+bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ if (left->isArray() || right->isArray())
+ {
+ if (shaderVersion < 300)
+ {
+ error(loc, "Invalid operation for arrays", GetOperatorString(op));
+ return false;
+ }
+
+ if (left->isArray() != right->isArray())
+ {
+ error(loc, "array / non-array mismatch", 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;
+ }
+ if (left->getArraySize() != right->getArraySize())
+ {
+ 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;
+ }
+
+ // GLSL ES 1.00 and 3.00 do not support implicit type casting.
+ // So the basic type should usually match.
+ if (!isBitShift && left->getBasicType() != right->getBasicType())
+ {
+ return false;
+ }
+
+ // Check that type sizes match exactly on ops that require that.
+ // Also check restrictions for structs that contain arrays or samplers.
+ switch(op)
+ {
+ case EOpAssign:
+ case EOpInitialize:
+ case EOpEqual:
+ case EOpNotEqual:
+ // ESSL 1.00 sections 5.7, 5.8, 5.9
+ if (shaderVersion < 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 ((shaderVersion < 300 || op == EOpAssign || op == EOpInitialize) &&
+ left->getType().isStructureContainingSamplers())
+ {
+ error(loc, "undefined operation for structs containing samplers", GetOperatorString(op));
+ return false;
+ }
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ if ((left->getNominalSize() != right->getNominalSize()) ||
+ (left->getSecondarySize() != right->getSecondarySize()))
+ {
+ return false;
+ }
+ default:
+ break;
+ }
+
+ return true;
+}
+
+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:
+ break;
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ ASSERT(!left->isArray() && !right->isArray());
+ if (left->isMatrix() || left->isVector() ||
+ left->getBasicType() == EbtStruct)
+ {
+ return nullptr;
+ }
+ break;
+ case EOpLogicalOr:
+ case EOpLogicalXor:
+ case EOpLogicalAnd:
+ ASSERT(!left->isArray() && !right->isArray());
+ if (left->getBasicType() != EbtBool ||
+ left->isMatrix() || left->isVector())
+ {
+ return nullptr;
+ }
+ break;
+ case EOpAdd:
+ case EOpSub:
+ case EOpDiv:
+ case EOpMul:
+ ASSERT(!left->isArray() && !right->isArray());
+ if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
+ {
+ return nullptr;
+ }
+ break;
+ case EOpIMod:
+ ASSERT(!left->isArray() && !right->isArray());
+ // Note that this is only for the % operator, not for mod()
+ if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
+ {
+ return nullptr;
+ }
+ break;
+ // Note that for bitwise ops, type checking is done in promote() to
+ // share code between ops and compound assignment
+ default:
+ break;
+ }
+
+ return intermediate.addBinaryMath(op, left, right, loc);
+}
+
+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->getCompleteString(), right->getCompleteString());
+ recover();
+ 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 == 0)
+ {
+ binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), right->getCompleteString());
+ recover();
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setBConst(false);
+ return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), loc);
+ }
+ return node;
+}
+
+TIntermTyped *TParseContext::createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ if (binaryOpCommonCheck(op, left, right, loc))
+ {
+ return intermediate.addAssign(op, left, right, loc);
+ }
+ return nullptr;
+}
+
+TIntermTyped *TParseContext::addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ TIntermTyped *node = createAssign(op, left, right, loc);
+ if (node == nullptr)
+ {
+ assignError(loc, "assign", left->getCompleteString(), right->getCompleteString());
+ recover();
+ return left;
+ }
+ return node;
+}
+
+TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
+{
+ switch (op)
+ {
+ case EOpContinue:
+ if (mLoopNestingLevel <= 0)
+ {
+ error(loc, "continue statement only allowed in loops", "");
+ recover();
+ }
+ break;
+ case EOpBreak:
+ if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
+ {
+ error(loc, "break statement only allowed in loops and switch statements", "");
+ recover();
+ }
+ break;
+ case EOpReturn:
+ if (currentFunctionType->getBasicType() != EbtVoid)
+ {
+ error(loc, "non-void function must return a value", "return");
+ recover();
+ }
+ break;
+ default:
+ // No checks for discard
+ break;
+ }
+ return intermediate.addBranch(op, loc);
+}
+
+TIntermBranch *TParseContext::addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc)
+{
+ ASSERT(op == EOpReturn);
+ mFunctionReturnsValue = true;
+ if (currentFunctionType->getBasicType() == EbtVoid)
+ {
+ error(loc, "void function cannot return a value", "return");
+ recover();
+ }
+ else if (*currentFunctionType != returnValue->getType())
+ {
+ error(loc, "function return is not matching type:", "return");
+ recover();
+ }
+ return intermediate.addBranch(op, returnValue, loc);
+}
+
+TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *node,
+ const TSourceLoc &loc, bool *fatalError)
+{
+ *fatalError = false;
+ TOperator op = fnCall->getBuiltInOp();
+ TIntermTyped *callNode = nullptr;
+
+ if (op != EOpNull)
+ {
+ //
+ // Then this should be a constructor.
+ // Don't go through the symbol table for constructors.
+ // Their parameters will be verified algorithmically.
+ //
+ TType type(EbtVoid, EbpUndefined); // use this to get the type back
+ if (!constructorErrorCheck(loc, node, *fnCall, op, &type))
+ {
+ //
+ // It's a constructor, of type 'type'.
+ //
+ callNode = addConstructor(node, &type, op, fnCall, loc);
+ }
+
+ if (callNode == nullptr)
+ {
+ recover();
+ callNode = intermediate.setAggregateOperator(nullptr, op, loc);
+ }
+ callNode->setType(type);
+ }
+ else
+ {
+ //
+ // Not a constructor. Find it in the symbol table.
+ //
+ const TFunction* fnCandidate;
+ bool builtIn;
+ fnCandidate = findFunction(loc, fnCall, shaderVersion, &builtIn);
+ if (fnCandidate)
+ {
+ //
+ // A declared function.
+ //
+ if (builtIn && !fnCandidate->getExtension().empty() &&
+ extensionErrorCheck(loc, fnCandidate->getExtension()))
+ {
+ recover();
+ }
+ op = fnCandidate->getBuiltInOp();
+ if (builtIn && op != EOpNull)
+ {
+ //
+ // A function call mapped to a built-in operation.
+ //
+ if (fnCandidate->getParamCount() == 1)
+ {
+ //
+ // Treat it like a built-in unary operator.
+ //
+ callNode = createUnaryMath(op, node->getAsTyped(), loc, &fnCandidate->getReturnType());
+ if (callNode == nullptr)
+ {
+ std::stringstream extraInfoStream;
+ extraInfoStream << "built in unary operator function. Type: "
+ << static_cast<TIntermTyped*>(node)->getCompleteString();
+ std::string extraInfo = extraInfoStream.str();
+ error(node->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
+ *fatalError = true;
+ return nullptr;
+ }
+ }
+ else
+ {
+ TIntermAggregate *aggregate = intermediate.setAggregateOperator(node, op, loc);
+ aggregate->setType(fnCandidate->getReturnType());
+ aggregate->setPrecisionFromChildren();
+ callNode = aggregate;
+
+ // Some built-in functions have out parameters too.
+ functionCallLValueErrorCheck(fnCandidate, aggregate);
+ }
+ }
+ else
+ {
+ // This is a real function call
+
+ TIntermAggregate *aggregate = intermediate.setAggregateOperator(node, EOpFunctionCall, loc);
+ aggregate->setType(fnCandidate->getReturnType());
+
+ // this is how we know whether the given function is a builtIn function or a user defined function
+ // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
+ // if builtIn == true, it's definitely a builtIn function with EOpNull
+ if (!builtIn)
+ aggregate->setUserDefined();
+ aggregate->setName(fnCandidate->getMangledName());
+
+ // This needs to happen after the name is set
+ if (builtIn)
+ aggregate->setBuiltInFunctionPrecision();
+
+ callNode = aggregate;
+
+ functionCallLValueErrorCheck(fnCandidate, aggregate);
+ }
+ }
+ else
+ {
+ // error message was put out by findFunction()
+ // Put on a dummy node for error recovery
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setFConst(0.0f);
+ callNode = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), loc);
+ recover();
+ }
+ }
+ delete fnCall;
+ return callNode;
+}
+
+
//
// Parse an array of strings using yyparse.
//
diff --git a/src/3rdparty/angle/src/compiler/translator/ParseContext.h b/src/3rdparty/angle/src/compiler/translator/ParseContext.h
index 414c475cbb..b6a0f4a637 100644
--- a/src/3rdparty/angle/src/compiler/translator/ParseContext.h
+++ b/src/3rdparty/angle/src/compiler/translator/ParseContext.h
@@ -3,8 +3,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-#ifndef _PARSER_HELPER_INCLUDED_
-#define _PARSER_HELPER_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_PARSECONTEXT_H_
+#define COMPILER_TRANSLATOR_PARSECONTEXT_H_
#include "compiler/translator/Compiler.h"
#include "compiler/translator/Diagnostics.h"
@@ -25,24 +25,25 @@ struct TMatrixFields {
// they can be passed to the parser without needing a global.
//
struct TParseContext {
- TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, sh::GLenum type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) :
+ TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, sh::GLenum type, ShShaderSpec spec, int options, bool checksPrecErrors, TInfoSink& is, bool debugShaderPrecisionSupported) :
intermediate(interm),
symbolTable(symt),
shaderType(type),
shaderSpec(spec),
compileOptions(options),
- sourcePath(sourcePath),
treeRoot(0),
- loopNestingLevel(0),
+ mLoopNestingLevel(0),
structNestingLevel(0),
+ mSwitchNestingLevel(0),
currentFunctionType(NULL),
- functionReturnsValue(false),
+ mFunctionReturnsValue(false),
checksPrecisionErrors(checksPrecErrors),
+ fragmentPrecisionHigh(false),
defaultMatrixPacking(EmpColumnMajor),
defaultBlockStorage(EbsShared),
diagnostics(is),
shaderVersion(100),
- directiveHandler(ext, diagnostics, shaderVersion),
+ directiveHandler(ext, diagnostics, shaderVersion, debugShaderPrecisionSupported),
preprocessor(&diagnostics, &directiveHandler),
scanner(NULL) { }
TIntermediate& intermediate; // to hold and build a parse tree
@@ -51,12 +52,12 @@ struct TParseContext {
ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
int shaderVersion;
int compileOptions;
- const char* sourcePath; // Path of source file or NULL.
TIntermNode* treeRoot; // root of parse tree being created
- int loopNestingLevel; // 0 if outside all loops
+ int mLoopNestingLevel; // 0 if outside all loops
int structNestingLevel; // incremented while parsing a struct declaration
+ int mSwitchNestingLevel; // 0 if outside all switch statements
const TType* currentFunctionType; // the return type of the function that's currently being parsed
- bool functionReturnsValue; // true if a non-void function has a return
+ bool mFunctionReturnsValue; // true if a non-void function has a return
bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
bool fragmentPrecisionHigh; // true if highp precision is supported in the fragment language.
TLayoutMatrixPacking defaultMatrixPacking;
@@ -110,6 +111,7 @@ struct TParseContext {
bool extensionErrorCheck(const TSourceLoc& line, const TString&);
bool singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier);
bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier);
+ bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *);
const TPragma& pragma() const { return directiveHandler.pragma(); }
const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); }
@@ -120,7 +122,7 @@ struct TParseContext {
bool containsSampler(TType& type);
bool areAllChildConst(TIntermAggregate* aggrNode);
- const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, int shaderVersion, bool *builtIn = 0);
+ const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, int inputShaderVersion, bool *builtIn = 0);
bool executeInitializer(const TSourceLoc& line, const TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
@@ -136,7 +138,7 @@ struct TParseContext {
TIntermAggregate* parseInitDeclarator(TPublicType &publicType, TIntermAggregate *declaratorList, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer);
void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
TFunction *addConstructorFunc(TPublicType publicType);
- TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&);
+ TIntermTyped* addConstructor(TIntermNode*, TType*, TOperator, TFunction*, const TSourceLoc&);
TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type);
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&);
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, const TSourceLoc&);
@@ -164,9 +166,42 @@ struct TParseContext {
void exitStructDeclaration();
bool structNestingErrorCheck(const TSourceLoc& line, const TField& field);
+
+ TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc);
+ TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
+ TIntermCase *addDefault(const TSourceLoc &loc);
+
+ TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &);
+ TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &);
+ TIntermTyped *addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right,
+ const TSourceLoc &);
+ TIntermTyped *addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right,
+ const TSourceLoc &);
+ TIntermTyped *addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
+ const TSourceLoc &loc);
+
+ TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
+ TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc);
+
+ TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *node,
+ const TSourceLoc &loc, bool *fatalError);
+
+ private:
+ TIntermTyped *addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right,
+ const TSourceLoc &loc);
+ TIntermTyped *createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
+ const TSourceLoc &loc);
+ // The funcReturnType parameter is expected to be non-null when the operation is a built-in function.
+ // It is expected to be null for other unary operators.
+ TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc,
+ const TType *funcReturnType);
+
+ // Return true if the checks pass
+ bool binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right,
+ const TSourceLoc &loc);
};
int PaParseStrings(size_t count, const char* const string[], const int length[],
TParseContext* context);
-#endif // _PARSER_HELPER_INCLUDED_
+#endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h b/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h
index edd249c4d3..6cd8d30114 100644
--- a/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h
+++ b/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef _POOLALLOC_INCLUDED_
-#define _POOLALLOC_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_POOLALLOC_H_
+#define COMPILER_TRANSLATOR_POOLALLOC_H_
#ifdef _DEBUG
#define GUARD_BLOCKS // define to enable guard block sanity checking
@@ -297,4 +297,4 @@ protected:
TPoolAllocator* allocator;
};
-#endif // _POOLALLOC_INCLUDED_
+#endif // COMPILER_TRANSLATOR_POOLALLOC_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/Pragma.h b/src/3rdparty/angle/src/compiler/translator/Pragma.h
index 4a930a2962..57b1134970 100644
--- a/src/3rdparty/angle/src/compiler/translator/Pragma.h
+++ b/src/3rdparty/angle/src/compiler/translator/Pragma.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_PRAGMA_H_
-#define COMPILER_PRAGMA_H_
+#ifndef COMPILER_TRANSLATOR_PRAGMA_H_
+#define COMPILER_TRANSLATOR_PRAGMA_H_
struct TPragma
{
@@ -18,12 +18,15 @@ struct TPragma
// 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) { }
+ // Precision emulation is turned on by default, but has no effect unless
+ // the extension is enabled.
+ TPragma() : optimize(true), debug(false), debugShaderPrecision(true) { }
+ TPragma(bool o, bool d) : optimize(o), debug(d), debugShaderPrecision(true) { }
bool optimize;
bool debug;
+ bool debugShaderPrecision;
STDGL stdgl;
};
-#endif // COMPILER_PRAGMA_H_
+#endif // COMPILER_TRANSLATOR_PRAGMA_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/QualifierAlive.cpp b/src/3rdparty/angle/src/compiler/translator/QualifierAlive.cpp
index 1f6fb75821..3d950aab5a 100644
--- a/src/3rdparty/angle/src/compiler/translator/QualifierAlive.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/QualifierAlive.cpp
@@ -49,7 +49,7 @@ void TAliveTraverser::visitSymbol(TIntermSymbol* node)
found = true;
}
-bool TAliveTraverser::visitSelection(Visit preVisit, TIntermSelection* node)
+bool TAliveTraverser::visitSelection(Visit, TIntermSelection*)
{
if (wasFound())
return false;
diff --git a/src/3rdparty/angle/src/compiler/translator/QualifierAlive.h b/src/3rdparty/angle/src/compiler/translator/QualifierAlive.h
index 872a06f721..3e4f18012a 100644
--- a/src/3rdparty/angle/src/compiler/translator/QualifierAlive.h
+++ b/src/3rdparty/angle/src/compiler/translator/QualifierAlive.h
@@ -4,4 +4,9 @@
// found in the LICENSE file.
//
+#ifndef COMPILER_TRANSLATOR_QUALIFIERALIVE_H_
+#define COMPILER_TRANSLATOR_QUALIFIERALIVE_H_
+
bool QualifierWritten(TIntermNode* root, TQualifier);
+
+#endif // COMPILER_TRANSLATOR_QUALIFIERALIVE_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.h b/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.h
index ac87600347..2acd68be34 100644
--- a/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.h
+++ b/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_TRANSLATOR_REGENERATE_STRUCT_NAMES_H_
-#define COMPILER_TRANSLATOR_REGENERATE_STRUCT_NAMES_H_
+#ifndef COMPILER_TRANSLATOR_REGENERATESTRUCTNAMES_H_
+#define COMPILER_TRANSLATOR_REGENERATESTRUCTNAMES_H_
#include "compiler/translator/Intermediate.h"
#include "compiler/translator/SymbolTable.h"
@@ -37,4 +37,4 @@ class RegenerateStructNames : public TIntermTraverser
std::set<int> mDeclaredGlobalStructs;
};
-#endif // COMPILER_TRANSLATOR_REGENERATE_STRUCT_NAMES_H_
+#endif // COMPILER_TRANSLATOR_REGENERATESTRUCTNAMES_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp b/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp
new file mode 100644
index 0000000000..b278b53436
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp
@@ -0,0 +1,157 @@
+//
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/RemoveSwitchFallThrough.h"
+
+TIntermAggregate *RemoveSwitchFallThrough::removeFallThrough(TIntermAggregate *statementList)
+{
+ RemoveSwitchFallThrough rm(statementList);
+ ASSERT(statementList);
+ statementList->traverse(&rm);
+ bool lastStatementWasBreak = rm.mLastStatementWasBreak;
+ rm.mLastStatementWasBreak = true;
+ rm.handlePreviousCase();
+ if (!lastStatementWasBreak)
+ {
+ TIntermBranch *finalBreak = new TIntermBranch(EOpBreak, nullptr);
+ rm.mStatementListOut->getSequence()->push_back(finalBreak);
+ }
+ return rm.mStatementListOut;
+}
+
+RemoveSwitchFallThrough::RemoveSwitchFallThrough(TIntermAggregate *statementList)
+ : TIntermTraverser(true, false, false),
+ mStatementList(statementList),
+ mLastStatementWasBreak(false),
+ mPreviousCase(nullptr)
+{
+ mStatementListOut = new TIntermAggregate();
+ mStatementListOut->setOp(EOpSequence);
+}
+
+void RemoveSwitchFallThrough::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 RemoveSwitchFallThrough::visitConstantUnion(TIntermConstantUnion *node)
+{
+ // Conditions of case labels are not traversed, so this is some other constant
+ // Could be just a statement like "0;"
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+}
+
+bool RemoveSwitchFallThrough::visitBinary(Visit, TIntermBinary *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThrough::visitUnary(Visit, TIntermUnary *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThrough::visitSelection(Visit, TIntermSelection *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThrough::visitSwitch(Visit, TIntermSwitch *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ // Don't go into nested switch statements
+ return false;
+}
+
+void RemoveSwitchFallThrough::outputSequence(TIntermSequence *sequence, size_t startIndex)
+{
+ for (size_t i = startIndex; i < sequence->size(); ++i)
+ {
+ mStatementListOut->getSequence()->push_back(sequence->at(i));
+ }
+}
+
+void RemoveSwitchFallThrough::handlePreviousCase()
+{
+ if (mPreviousCase)
+ mCasesSharingBreak.push_back(mPreviousCase);
+ if (mLastStatementWasBreak)
+ {
+ bool labelsWithNoStatements = true;
+ for (size_t i = 0; i < mCasesSharingBreak.size(); ++i)
+ {
+ if (mCasesSharingBreak.at(i)->getSequence()->size() > 1)
+ {
+ labelsWithNoStatements = false;
+ }
+ if (labelsWithNoStatements)
+ {
+ // 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.
+ 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 RemoveSwitchFallThrough::visitCase(Visit, TIntermCase *node)
+{
+ handlePreviousCase();
+ mPreviousCase = new TIntermAggregate();
+ mPreviousCase->setOp(EOpSequence);
+ mPreviousCase->getSequence()->push_back(node);
+ // Don't traverse the condition of the case statement
+ return false;
+}
+
+bool RemoveSwitchFallThrough::visitAggregate(Visit, TIntermAggregate *node)
+{
+ if (node != mStatementList)
+ {
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+ }
+ return true;
+}
+
+bool RemoveSwitchFallThrough::visitLoop(Visit, TIntermLoop *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThrough::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;
+}
diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.h b/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.h
new file mode 100644
index 0000000000..db8699327c
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.h
@@ -0,0 +1,43 @@
+//
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_REMOVESWITCHFALLTHROUGH_H_
+#define COMPILER_TRANSLATOR_REMOVESWITCHFALLTHROUGH_H_
+
+#include "compiler/translator/IntermNode.h"
+
+class RemoveSwitchFallThrough : public TIntermTraverser
+{
+ public:
+ // When given a statementList from a switch AST node, return an updated
+ // statementList that has fall-through removed.
+ static TIntermAggregate *removeFallThrough(TIntermAggregate *statementList);
+
+ private:
+ RemoveSwitchFallThrough(TIntermAggregate *statementList);
+
+ void visitSymbol(TIntermSymbol *node) override;
+ void visitConstantUnion(TIntermConstantUnion *node) override;
+ bool visitBinary(Visit, TIntermBinary *node) override;
+ bool visitUnary(Visit, TIntermUnary *node) override;
+ bool visitSelection(Visit visit, TIntermSelection *node) override;
+ bool visitSwitch(Visit, TIntermSwitch *node) override;
+ bool visitCase(Visit, TIntermCase *node) override;
+ bool visitAggregate(Visit, TIntermAggregate *node) override;
+ bool visitLoop(Visit, TIntermLoop *node) override;
+ bool visitBranch(Visit, TIntermBranch *node) override;
+
+ void outputSequence(TIntermSequence *sequence, size_t startIndex);
+ void handlePreviousCase();
+
+ TIntermAggregate *mStatementList;
+ TIntermAggregate *mStatementListOut;
+ bool mLastStatementWasBreak;
+ TIntermAggregate *mPreviousCase;
+ std::vector<TIntermAggregate *> mCasesSharingBreak;
+};
+
+#endif // COMPILER_TRANSLATOR_REMOVESWITCHFALLTHROUGH_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveTree.cpp b/src/3rdparty/angle/src/compiler/translator/RemoveTree.cpp
deleted file mode 100644
index 0cf6910aa2..0000000000
--- a/src/3rdparty/angle/src/compiler/translator/RemoveTree.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (c) 2002-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/IntermNode.h"
-#include "compiler/translator/RemoveTree.h"
-
-//
-// Code to delete the intermediate tree.
-//
-void RemoveAllTreeNodes(TIntermNode* root)
-{
- std::queue<TIntermNode*> nodeQueue;
-
- nodeQueue.push(root);
-
- while (!nodeQueue.empty())
- {
- TIntermNode *node = nodeQueue.front();
- nodeQueue.pop();
-
- node->enqueueChildren(&nodeQueue);
-
- delete node;
- }
-}
-
diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveTree.h b/src/3rdparty/angle/src/compiler/translator/RemoveTree.h
deleted file mode 100644
index 97a821679c..0000000000
--- a/src/3rdparty/angle/src/compiler/translator/RemoveTree.h
+++ /dev/null
@@ -1,7 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-void RemoveAllTreeNodes(TIntermNode*);
diff --git a/src/3rdparty/angle/src/compiler/translator/RenameFunction.h b/src/3rdparty/angle/src/compiler/translator/RenameFunction.h
index d43e6ef7be..868e5d566b 100644
--- a/src/3rdparty/angle/src/compiler/translator/RenameFunction.h
+++ b/src/3rdparty/angle/src/compiler/translator/RenameFunction.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_RENAME_FUNCTION
-#define COMPILER_RENAME_FUNCTION
+#ifndef COMPILER_TRANSLATOR_RENAMEFUNCTION_H_
+#define COMPILER_TRANSLATOR_RENAMEFUNCTION_H_
#include "compiler/translator/IntermNode.h"
@@ -33,4 +33,4 @@ private:
const TString mNewFunctionName;
};
-#endif // COMPILER_RENAME_FUNCTION
+#endif // COMPILER_TRANSLATOR_RENAMEFUNCTION_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.h b/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.h
index d87baea0fe..5527d27f83 100644
--- a/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.h
+++ b/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.h
@@ -7,8 +7,8 @@
// all if-else blocks to if-if blocks.
//
-#ifndef COMPILER_REWRITE_ELSE_BLOCKS_H_
-#define COMPILER_REWRITE_ELSE_BLOCKS_H_
+#ifndef COMPILER_TRANSLATOR_REWRITEELSEBLOCKS_H_
+#define COMPILER_TRANSLATOR_REWRITEELSEBLOCKS_H_
#include "compiler/translator/IntermNode.h"
@@ -19,4 +19,4 @@ void RewriteElseBlocks(TIntermNode *node);
}
-#endif // COMPILER_REWRITE_ELSE_BLOCKS_H_
+#endif // COMPILER_TRANSLATOR_REWRITEELSEBLOCKS_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h b/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
index 7c6d09c1bb..0726ed4c64 100644
--- a/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
+++ b/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_
-#define COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_
+#ifndef COMPILER_TRANSLATOR_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
+#define COMPILER_TRANSLATOR_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
#include "compiler/translator/IntermNode.h"
@@ -44,4 +44,4 @@ class ScalarizeVecAndMatConstructorArgs : public TIntermTraverser
bool mFragmentPrecisionHigh;
};
-#endif // COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_
+#endif // COMPILER_TRANSLATOR_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/SearchSymbol.cpp b/src/3rdparty/angle/src/compiler/translator/SearchSymbol.cpp
index f78c84e370..fb7a6cdb9b 100644
--- a/src/3rdparty/angle/src/compiler/translator/SearchSymbol.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/SearchSymbol.cpp
@@ -9,7 +9,6 @@
#include "compiler/translator/SearchSymbol.h"
#include "compiler/translator/InfoSink.h"
-#include "compiler/translator/OutputHLSL.h"
namespace sh
{
diff --git a/src/3rdparty/angle/src/compiler/translator/SearchSymbol.h b/src/3rdparty/angle/src/compiler/translator/SearchSymbol.h
index 029ac30b9a..36d5191058 100644
--- a/src/3rdparty/angle/src/compiler/translator/SearchSymbol.h
+++ b/src/3rdparty/angle/src/compiler/translator/SearchSymbol.h
@@ -6,8 +6,8 @@
// SearchSymbol is an AST traverser to detect the use of a given symbol name
//
-#ifndef COMPILER_SEARCHSYMBOL_H_
-#define COMPILER_SEARCHSYMBOL_H_
+#ifndef COMPILER_TRANSLATOR_SEARCHSYMBOL_H_
+#define COMPILER_TRANSLATOR_SEARCHSYMBOL_H_
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/ParseContext.h"
@@ -30,4 +30,4 @@ class SearchSymbol : public TIntermTraverser
};
}
-#endif // COMPILER_SEARCHSYMBOL_H_
+#endif // COMPILER_TRANSLATOR_SEARCHSYMBOL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp
index 0d6a1d64cf..b8040da7f9 100644
--- a/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp
@@ -14,7 +14,9 @@
#include "compiler/translator/Compiler.h"
#include "compiler/translator/InitializeDll.h"
#include "compiler/translator/length_limits.h"
+#ifdef ANGLE_ENABLE_HLSL
#include "compiler/translator/TranslatorHLSL.h"
+#endif // ANGLE_ENABLE_HLSL
#include "compiler/translator/VariablePacker.h"
#include "angle_gl.h"
@@ -92,6 +94,7 @@ TCompiler *GetCompilerFromHandle(ShHandle handle)
return base->getAsCompiler();
}
+#ifdef ANGLE_ENABLE_HLSL
TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
{
if (!handle)
@@ -99,6 +102,7 @@ TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
TShHandleBase *base = static_cast<TShHandleBase *>(handle);
return base->getAsTranslatorHLSL();
}
+#endif // ANGLE_ENABLE_HLSL
} // namespace anonymous
@@ -153,6 +157,10 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->EXT_draw_buffers = 0;
resources->EXT_frag_depth = 0;
resources->EXT_shader_texture_lod = 0;
+ resources->WEBGL_debug_shader_precision = 0;
+ resources->EXT_shader_framebuffer_fetch = 0;
+ resources->NV_shader_framebuffer_fetch = 0;
+ resources->ARM_shader_framebuffer_fetch = 0;
resources->NV_draw_buffers = 0;
@@ -323,6 +331,7 @@ bool ShGetInterfaceBlockRegister(const ShHandle handle,
const std::string &interfaceBlockName,
unsigned int *indexOut)
{
+#ifdef ANGLE_ENABLE_HLSL
ASSERT(indexOut);
TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
@@ -335,12 +344,16 @@ bool ShGetInterfaceBlockRegister(const ShHandle handle,
*indexOut = translator->getInterfaceBlockRegister(interfaceBlockName);
return true;
+#else
+ return false;
+#endif // ANGLE_ENABLE_HLSL
}
bool ShGetUniformRegister(const ShHandle handle,
const std::string &uniformName,
unsigned int *indexOut)
{
+#ifdef ANGLE_ENABLE_HLSL
ASSERT(indexOut);
TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
ASSERT(translator);
@@ -352,4 +365,7 @@ bool ShGetUniformRegister(const ShHandle handle,
*indexOut = translator->getUniformRegister(uniformName);
return true;
+#else
+ return false;
+#endif // ANGLE_ENABLE_HLSL
}
diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
index 3098a7f0c9..0dbbc9e7f6 100644
--- a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
@@ -14,6 +14,23 @@
namespace sh
{
+namespace
+{
+
+InterpolationType GetNonAuxiliaryInterpolationType(InterpolationType interpolation)
+{
+ return (interpolation == INTERPOLATION_CENTROID ? INTERPOLATION_SMOOTH : interpolation);
+}
+
+}
+// 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()
: type(0),
precision(0),
@@ -86,7 +103,6 @@ bool ShaderVariable::findInfoByMappedName(
// 2) the top variable is an array;
// 3) otherwise.
size_t pos = mappedFullName.find_first_of(".[");
- std::string topName;
if (pos == std::string::npos)
{
diff --git a/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.cpp b/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.cpp
new file mode 100644
index 0000000000..ac5eb67070
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.cpp
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/SimplifyArrayAssignment.h"
+
+bool SimplifyArrayAssignment::visitBinary(Visit visit, TIntermBinary *node)
+{
+ switch (node->getOp())
+ {
+ case EOpAssign:
+ {
+ TIntermNode *parent = getParentNode();
+ if (node->getLeft()->isArray() && parent != nullptr)
+ {
+ TIntermAggregate *parentAgg = parent->getAsAggregate();
+ if (parentAgg != nullptr && parentAgg->getOp() == EOpSequence)
+ {
+ // This case is fine, the result of the assignment is not used.
+ break;
+ }
+
+ // The result of the assignment needs to be stored into a temporary variable,
+ // the assignment needs to be replaced with a reference to the temporary variable,
+ // and the temporary variable needs to finally be assigned to the target variable.
+
+ // This also needs to interact correctly with unfolding short circuiting operators.
+ UNIMPLEMENTED();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+}
diff --git a/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.h b/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.h
new file mode 100644
index 0000000000..247eb88d72
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.h
@@ -0,0 +1,25 @@
+//
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SimplifyArrayAssignment is an AST traverser to replace statements where
+// the return value of array assignment is used with statements where
+// the return value of array assignment is not used.
+//
+
+#ifndef COMPILER_TRANSLATOR_SIMPLIFYARRAYASSIGNMENT_H_
+#define COMPILER_TRANSLATOR_SIMPLIFYARRAYASSIGNMENT_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/IntermNode.h"
+
+class SimplifyArrayAssignment : public TIntermTraverser
+{
+ public:
+ SimplifyArrayAssignment() { }
+
+ virtual bool visitBinary(Visit visit, TIntermBinary *node);
+};
+
+#endif // COMPILER_TRANSLATOR_SIMPLIFYARRAYASSIGNMENT_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/StructureHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/StructureHLSL.cpp
index 48929affe6..fd1a29c1cd 100644
--- a/src/3rdparty/angle/src/compiler/translator/StructureHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/StructureHLSL.cpp
@@ -21,9 +21,23 @@ Std140PaddingHelper::Std140PaddingHelper(const std::map<TString, int> &structEle
unsigned *uniqueCounter)
: mPaddingCounter(uniqueCounter),
mElementIndex(0),
- mStructElementIndexes(structElementIndexes)
+ 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)++;
@@ -107,7 +121,7 @@ TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRo
{
const TString &structName = QualifiedStructNameString(*structure,
useHLSLRowMajorPacking, true);
- numComponents = mStructElementIndexes.find(structName)->second;
+ numComponents = mStructElementIndexes->find(structName)->second;
if (numComponents == 0)
{
@@ -274,9 +288,9 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const
for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++)
{
- const TType &type = ctorParameters[parameter];
+ const TType &paramType = ctorParameters[parameter];
- constructor += TypeString(type) + " x" + str(parameter) + ArrayString(type);
+ constructor += TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType);
if (parameter < ctorParameters.size() - 1)
{
diff --git a/src/3rdparty/angle/src/compiler/translator/StructureHLSL.h b/src/3rdparty/angle/src/compiler/translator/StructureHLSL.h
index ed002fef30..cffe2a41ae 100644
--- a/src/3rdparty/angle/src/compiler/translator/StructureHLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/StructureHLSL.h
@@ -7,8 +7,8 @@
// Interfaces of methods for HLSL translation of GLSL structures.
//
-#ifndef TRANSLATOR_STRUCTUREHLSL_H_
-#define TRANSLATOR_STRUCTUREHLSL_H_
+#ifndef COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
+#define COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
#include "compiler/translator/Common.h"
#include "compiler/translator/IntermNode.h"
@@ -27,7 +27,9 @@ class Std140PaddingHelper
{
public:
explicit Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
- unsigned *uniqueCounter);
+ unsigned int *uniqueCounter);
+ Std140PaddingHelper(const Std140PaddingHelper &other);
+ Std140PaddingHelper &operator=(const Std140PaddingHelper &other);
int elementIndex() const { return mElementIndex; }
int prePadding(const TType &type);
@@ -39,10 +41,10 @@ class Std140PaddingHelper
unsigned *mPaddingCounter;
int mElementIndex;
- const std::map<TString, int> &mStructElementIndexes;
+ const std::map<TString, int> *mStructElementIndexes;
};
-class StructureHLSL
+class StructureHLSL : angle::NonCopyable
{
public:
StructureHLSL();
@@ -76,4 +78,4 @@ class StructureHLSL
}
-#endif // COMPILER_STRUCTUREHLSL_H_
+#endif // COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/SymbolTable.cpp b/src/3rdparty/angle/src/compiler/translator/SymbolTable.cpp
index 028da21151..0eb663f018 100644
--- a/src/3rdparty/angle/src/compiler/translator/SymbolTable.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/SymbolTable.cpp
@@ -48,6 +48,16 @@ bool TSymbolTableLevel::insert(TSymbol *symbol)
return result.second;
}
+bool TSymbolTableLevel::insertUnmangled(TFunction *function)
+{
+ function->setUniqueId(TSymbolTable::nextUniqueId());
+
+ // returning true means symbol was added to the table
+ tInsertResult result = level.insert(tLevelPair(function->getName(), function));
+
+ return result.second;
+}
+
TSymbol *TSymbolTableLevel::find(const TString &name) const
{
tLevel::const_iterator it = level.find(name);
@@ -57,47 +67,6 @@ TSymbol *TSymbolTableLevel::find(const TString &name) const
return (*it).second;
}
-//
-// Change all function entries in the table with the non-mangled name
-// to be related to the provided built-in operation. This is a low
-// performance operation, and only intended for symbol tables that
-// live across a large number of compiles.
-//
-void TSymbolTableLevel::relateToOperator(const char *name, TOperator op)
-{
- for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
- {
- if ((*it).second->isFunction())
- {
- TFunction *function = static_cast<TFunction*>((*it).second);
- if (function->getName() == name)
- function->relateToOperator(op);
- }
- }
-}
-
-//
-// Change all function entries in the table with the non-mangled name
-// to be related to the provided built-in extension. This is a low
-// performance operation, and only intended for symbol tables that
-// live across a large number of compiles.
-//
-void TSymbolTableLevel::relateToExtension(const char *name, const TString &ext)
-{
- for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
- {
- TSymbol *symbol = it->second;
- if (symbol->getName() == name)
- symbol->relateToExtension(ext);
- }
-}
-
-TSymbol::TSymbol(const TSymbol &copyOf)
-{
- name = NewPoolTString(copyOf.name->c_str());
- uniqueId = copyOf.uniqueId;
-}
-
TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
bool *builtIn, bool *sameScope) const
{
@@ -148,68 +117,149 @@ TSymbolTable::~TSymbolTable()
pop();
}
-void TSymbolTable::insertBuiltIn(
- ESymbolLevel level, TType *rvalue, const char *name,
- TType *ptype1, TType *ptype2, TType *ptype3, TType *ptype4, TType *ptype5)
+bool IsGenType(const TType *type)
+{
+ if (type)
+ {
+ TBasicType basicType = type->getBasicType();
+ return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType || basicType == EbtGenBType;
+ }
+
+ return false;
+}
+
+bool IsVecType(const TType *type)
+{
+ if (type)
+ {
+ TBasicType basicType = type->getBasicType();
+ return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec || basicType == EbtBVec;
+ }
+
+ return false;
+}
+
+TType *SpecificType(TType *type, int size)
+{
+ ASSERT(size >= 1 && size <= 4);
+
+ if (!type)
+ {
+ return nullptr;
+ }
+
+ ASSERT(!IsVecType(type));
+
+ switch(type->getBasicType())
+ {
+ case EbtGenType: return new TType(EbtFloat, size);
+ case EbtGenIType: return new TType(EbtInt, size);
+ case EbtGenUType: return new TType(EbtUInt, size);
+ case EbtGenBType: return new TType(EbtBool, size);
+ default: return type;
+ }
+}
+
+TType *VectorType(TType *type, int size)
+{
+ ASSERT(size >= 2 && size <= 4);
+
+ if (!type)
+ {
+ return nullptr;
+ }
+
+ ASSERT(!IsGenType(type));
+
+ switch(type->getBasicType())
+ {
+ case EbtVec: return new TType(EbtFloat, size);
+ case EbtIVec: return new TType(EbtInt, size);
+ case EbtUVec: return new TType(EbtUInt, size);
+ case EbtBVec: return new TType(EbtBool, size);
+ default: return type;
+ }
+}
+
+void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, TType *rvalue, const char *name,
+ TType *ptype1, TType *ptype2, TType *ptype3, TType *ptype4, TType *ptype5)
{
if (ptype1->getBasicType() == EbtGSampler2D)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
- insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
- new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
- new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
- new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
- return;
+ insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
}
- if (ptype1->getBasicType() == EbtGSampler3D)
+ else if (ptype1->getBasicType() == EbtGSampler3D)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
- insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
- new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
- new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
- new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
- return;
+ insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
}
- if (ptype1->getBasicType() == EbtGSamplerCube)
+ else if (ptype1->getBasicType() == EbtGSamplerCube)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
- insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
- new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
- new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
- new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
- return;
+ insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
}
- if (ptype1->getBasicType() == EbtGSampler2DArray)
+ else if (ptype1->getBasicType() == EbtGSampler2DArray)
{
bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
- insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
- new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
- new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
- insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
- new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
- return;
+ insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
+ insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
+ }
+ else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
+ {
+ ASSERT(!ptype4 && !ptype5);
+ insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1));
+ insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2));
+ insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3));
+ insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4), SpecificType(ptype2, 4), SpecificType(ptype3, 4));
+ }
+ else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
+ {
+ ASSERT(!ptype4 && !ptype5);
+ insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2));
+ insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3));
+ insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4));
}
+ else
+ {
+ TFunction *function = new TFunction(NewPoolTString(name), *rvalue, op, ext);
- TFunction *function = new TFunction(NewPoolTString(name), *rvalue);
+ TParameter param1 = {0, ptype1};
+ function->addParameter(param1);
- TType *types[] = {ptype1, ptype2, ptype3, ptype4, ptype5};
- for (size_t ii = 0; ii < sizeof(types) / sizeof(types[0]); ++ii)
- {
- if (types[ii])
+ if (ptype2)
{
- TParameter param = {NULL, types[ii]};
- function->addParameter(param);
+ TParameter param2 = {0, ptype2};
+ function->addParameter(param2);
}
- }
- insert(level, function);
+ if (ptype3)
+ {
+ TParameter param3 = {0, ptype3};
+ function->addParameter(param3);
+ }
+
+ if (ptype4)
+ {
+ TParameter param4 = {0, ptype4};
+ function->addParameter(param4);
+ }
+
+ if (ptype5)
+ {
+ TParameter param5 = {0, ptype5};
+ function->addParameter(param5);
+ }
+
+ insert(level, function);
+ }
}
TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
diff --git a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h
index 9cd74218dc..dfc65cb957 100644
--- a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h
+++ b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef _SYMBOL_TABLE_INCLUDED_
-#define _SYMBOL_TABLE_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_SYMBOLTABLE_H_
+#define COMPILER_TRANSLATOR_SYMBOLTABLE_H_
//
// Symbol table for parsing. Has these design characteristics:
@@ -38,7 +38,7 @@
#include "compiler/translator/IntermNode.h"
// Symbol base class. (Can build functions or variables out of these...)
-class TSymbol
+class TSymbol : angle::NonCopyable
{
public:
POOL_ALLOCATOR_NEW_DELETE();
@@ -86,8 +86,6 @@ class TSymbol
}
private:
- DISALLOW_COPY_AND_ASSIGN(TSymbol);
-
int uniqueId; // For real comparing during code generation
const TString *name;
TString extension;
@@ -158,8 +156,6 @@ class TVariable : public TSymbol
}
private:
- DISALLOW_COPY_AND_ASSIGN(TVariable);
-
TType type;
bool userType;
// we are assuming that Pool Allocator will free the memory
@@ -186,13 +182,14 @@ class TFunction : public TSymbol
defined(false)
{
}
- TFunction(const TString *name, const TType &retType, TOperator tOp = EOpNull)
+ TFunction(const TString *name, const TType &retType, TOperator tOp = EOpNull, const char *ext = "")
: TSymbol(name),
returnType(retType),
mangledName(TFunction::mangleName(*name)),
op(tOp),
defined(false)
{
+ relateToExtension(ext);
}
virtual ~TFunction();
virtual bool isFunction() const
@@ -224,10 +221,6 @@ class TFunction : public TSymbol
return returnType;
}
- void relateToOperator(TOperator o)
- {
- op = o;
- }
TOperator getBuiltInOp() const
{
return op;
@@ -252,8 +245,6 @@ class TFunction : public TSymbol
}
private:
- DISALLOW_COPY_AND_ASSIGN(TFunction);
-
typedef TVector<TParameter> TParamList;
TParamList parameters;
TType returnType;
@@ -291,10 +282,10 @@ class TSymbolTableLevel
bool insert(TSymbol *symbol);
- TSymbol *find(const TString &name) const;
+ // Insert a function using its unmangled name as the key.
+ bool insertUnmangled(TFunction *function);
- void relateToOperator(const char *name, TOperator op);
- void relateToExtension(const char *name, const TString &ext);
+ TSymbol *find(const TString &name) const;
protected:
tLevel level;
@@ -310,7 +301,7 @@ const int ESSL3_BUILTINS = 2;
const int LAST_BUILTIN_LEVEL = ESSL3_BUILTINS;
const int GLOBAL_LEVEL = 3;
-class TSymbolTable
+class TSymbolTable : angle::NonCopyable
{
public:
TSymbolTable()
@@ -363,6 +354,12 @@ class TSymbolTable
return table[level]->insert(symbol);
}
+ bool insert(ESymbolLevel level, const char *ext, TSymbol *symbol)
+ {
+ symbol->relateToExtension(ext);
+ return table[level]->insert(symbol);
+ }
+
bool insertConstInt(ESymbolLevel level, const char *name, int value)
{
TVariable *constant = new TVariable(
@@ -371,9 +368,26 @@ class TSymbolTable
return insert(level, constant);
}
+ void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, TType *rvalue, const char *name,
+ TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0);
+
void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name,
- TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0,
- TType *ptype4 = 0, TType *ptype5 = 0);
+ TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
+ {
+ insertBuiltIn(level, EOpNull, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
+ }
+
+ void insertBuiltIn(ESymbolLevel level, const char *ext, TType *rvalue, const char *name,
+ TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
+ {
+ insertBuiltIn(level, EOpNull, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
+ }
+
+ void insertBuiltIn(ESymbolLevel level, TOperator op, TType *rvalue, const char *name,
+ TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
+ {
+ insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
+ }
TSymbol *find(const TString &name, int shaderVersion,
bool *builtIn = NULL, bool *sameScope = NULL) const;
@@ -385,14 +399,6 @@ class TSymbolTable
return table[currentLevel() - 1];
}
- void relateToOperator(ESymbolLevel level, const char *name, TOperator op)
- {
- table[level]->relateToOperator(name, op);
- }
- void relateToExtension(ESymbolLevel level, const char *name, const TString &ext)
- {
- table[level]->relateToExtension(name, ext);
- }
void dump(TInfoSink &infoSink) const;
bool setDefaultPrecision(const TPublicType &type, TPrecision prec)
@@ -413,7 +419,7 @@ class TSymbolTable
// This records invariant varyings declared through
// "invariant varying_name;".
- void addInvariantVarying(const TString &originalName)
+ void addInvariantVarying(const std::string &originalName)
{
mInvariantVaryings.insert(originalName);
}
@@ -421,7 +427,7 @@ class TSymbolTable
// 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 TString &originalName) const
+ bool isVaryingInvariant(const std::string &originalName) const
{
return (mGlobalInvariant ||
mInvariantVaryings.count(originalName) > 0);
@@ -445,10 +451,10 @@ class TSymbolTable
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
std::vector< PrecisionStackLevel *> precisionStack;
- std::set<TString> mInvariantVaryings;
+ std::set<std::string> mInvariantVaryings;
bool mGlobalInvariant;
static int uniqueIdCounter;
};
-#endif // _SYMBOL_TABLE_INCLUDED_
+#endif // COMPILER_TRANSLATOR_SYMBOLTABLE_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp
index dcbf3cea1d..238bc97576 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp
@@ -6,40 +6,91 @@
#include "compiler/translator/TranslatorESSL.h"
+#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
+#include "compiler/translator/EmulatePrecision.h"
#include "compiler/translator/OutputESSL.h"
#include "angle_gl.h"
TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
- : TCompiler(type, spec, SH_ESSL_OUTPUT) {
+ : TCompiler(type, spec, SH_ESSL_OUTPUT)
+{
}
-void TranslatorESSL::translate(TIntermNode* root) {
+void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions)
+{
+ if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS)
+ InitBuiltInFunctionEmulatorForGLSL(emu, getShaderType());
+}
+
+void TranslatorESSL::translate(TIntermNode *root, int) {
TInfoSinkBase& sink = getInfoSink().obj;
+ int shaderVersion = getShaderVersion();
+ if (shaderVersion > 100)
+ {
+ sink << "#version " << shaderVersion << " es\n";
+ }
+
writePragma();
// Write built-in extension behaviors.
writeExtensionBehavior();
+ bool precisionEmulation = getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision;
+
+ if (precisionEmulation)
+ {
+ EmulatePrecision emulatePrecision;
+ root->traverse(&emulatePrecision);
+ emulatePrecision.updateTree();
+ emulatePrecision.writeEmulationHelpers(sink, SH_ESSL_OUTPUT);
+ }
+
// Write emulated built-in functions if needed.
- getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
- sink, getShaderType() == GL_FRAGMENT_SHADER);
+ 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 webgl_emu_precision highp\n"
+ << "#else\n"
+ << "#define webgl_emu_precision mediump\n"
+ << "#endif\n\n";
+ }
+ else
+ {
+ sink << "#define webgl_emu_precision highp\n";
+ }
+
+ getBuiltInFunctionEmulator().OutputEmulatedFunctions(sink);
+ sink << "// END: Generated code for built-in function emulation\n\n";
+ }
// Write array bounds clamping emulation if needed.
getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
// Write translated shader.
- TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable(), getShaderVersion());
+ TOutputESSL outputESSL(sink,
+ getArrayIndexClampingStrategy(),
+ getHashFunction(),
+ getNameMap(),
+ getSymbolTable(),
+ shaderVersion,
+ precisionEmulation);
root->traverse(&outputESSL);
}
void TranslatorESSL::writeExtensionBehavior() {
TInfoSinkBase& sink = getInfoSink().obj;
- const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
- for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
- iter != extensionBehavior.end(); ++iter) {
+ const TExtensionBehavior& extBehavior = getExtensionBehavior();
+ for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
+ iter != extBehavior.end(); ++iter) {
if (iter->second != EBhUndefined) {
- if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") {
+ if (getResources().NV_shader_framebuffer_fetch && iter->first == "GL_EXT_shader_framebuffer_fetch") {
+ sink << "#extension GL_NV_shader_framebuffer_fetch : "
+ << getBehaviorString(iter->second) << "\n";
+ } else if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") {
sink << "#extension GL_NV_draw_buffers : "
<< getBehaviorString(iter->second) << "\n";
} else {
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.h b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.h
index 55766822d1..89a3e473e9 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.h
@@ -4,20 +4,23 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_TRANSLATORESSL_H_
-#define COMPILER_TRANSLATORESSL_H_
+#ifndef COMPILER_TRANSLATOR_TRANSLATORESSL_H_
+#define COMPILER_TRANSLATOR_TRANSLATORESSL_H_
#include "compiler/translator/Compiler.h"
-class TranslatorESSL : public TCompiler {
-public:
+class TranslatorESSL : public TCompiler
+{
+ public:
TranslatorESSL(sh::GLenum type, ShShaderSpec spec);
-protected:
- virtual void translate(TIntermNode* root);
+ protected:
+ void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) override;
-private:
+ virtual void translate(TIntermNode *root, int compileOptions);
+
+ private:
void writeExtensionBehavior();
};
-#endif // COMPILER_TRANSLATORESSL_H_
+#endif // COMPILER_TRANSLATOR_TRANSLATORESSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
index 6acbf7c5a8..aea3f77c4e 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
@@ -6,14 +6,69 @@
#include "compiler/translator/TranslatorGLSL.h"
+#include "angle_gl.h"
+#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
+#include "compiler/translator/EmulatePrecision.h"
#include "compiler/translator/OutputGLSL.h"
#include "compiler/translator/VersionGLSL.h"
-TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec)
- : TCompiler(type, spec, SH_GLSL_OUTPUT) {
+namespace
+{
+
+// To search for what output variables are used in a fragment shader.
+// We handle gl_FragColor and gl_FragData at the moment.
+class TFragmentOutSearcher : public TIntermTraverser
+{
+ public:
+ TFragmentOutSearcher()
+ : mUsesGlFragColor(false),
+ mUsesGlFragData(false)
+ {
+ }
+
+ bool usesGlFragColor() const
+ {
+ return mUsesGlFragColor;
+ }
+
+ bool usesGlFragData() const
+ {
+ return mUsesGlFragData;
+ }
+
+ protected:
+ virtual void visitSymbol(TIntermSymbol *node) override
+ {
+ if (node->getSymbol() == "gl_FragColor")
+ {
+ mUsesGlFragColor = true;
+ }
+ else if (node->getSymbol() == "gl_FragData")
+ {
+ mUsesGlFragData = true;
+ }
+ }
+
+ private:
+ bool mUsesGlFragColor;
+ bool mUsesGlFragData;
+};
+
+} // namespace anonymous
+
+TranslatorGLSL::TranslatorGLSL(sh::GLenum type,
+ ShShaderSpec spec,
+ ShShaderOutput output)
+ : TCompiler(type, spec, output) {
+}
+
+void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions)
+{
+ if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS)
+ InitBuiltInFunctionEmulatorForGLSL(emu, getShaderType());
}
-void TranslatorGLSL::translate(TIntermNode* root) {
+void TranslatorGLSL::translate(TIntermNode *root, int) {
TInfoSinkBase& sink = getInfoSink().obj;
// Write GLSL version.
@@ -24,21 +79,60 @@ void TranslatorGLSL::translate(TIntermNode* root) {
// Write extension behaviour as needed
writeExtensionBehavior();
+ bool precisionEmulation = getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision;
+
+ if (precisionEmulation)
+ {
+ EmulatePrecision emulatePrecision;
+ root->traverse(&emulatePrecision);
+ emulatePrecision.updateTree();
+ emulatePrecision.writeEmulationHelpers(sink, getOutputType());
+ }
+
// Write emulated built-in functions if needed.
- getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
- sink, false);
+ if (!getBuiltInFunctionEmulator().IsOutputEmpty())
+ {
+ sink << "// BEGIN: Generated code for built-in function emulation\n\n";
+ sink << "#define webgl_emu_precision\n\n";
+ getBuiltInFunctionEmulator().OutputEmulatedFunctions(sink);
+ sink << "// END: Generated code for built-in function emulation\n\n";
+ }
// Write array bounds clamping emulation if needed.
getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
+ // 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 &&
+ getOutputType() == SH_GLSL_CORE_OUTPUT)
+ {
+ TFragmentOutSearcher searcher;
+ root->traverse(&searcher);
+ ASSERT(!(searcher.usesGlFragData() && searcher.usesGlFragColor()));
+ if (searcher.usesGlFragColor())
+ {
+ sink << "out vec4 webgl_FragColor;\n";
+ }
+ if (searcher.usesGlFragData())
+ {
+ sink << "out vec4 webgl_FragData[gl_MaxDrawBuffers];\n";
+ }
+ }
+
// Write translated shader.
- TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable(), getShaderVersion());
+ TOutputGLSL outputGLSL(sink,
+ getArrayIndexClampingStrategy(),
+ getHashFunction(),
+ getNameMap(),
+ getSymbolTable(),
+ getShaderVersion(),
+ getOutputType());
root->traverse(&outputGLSL);
}
void TranslatorGLSL::writeVersion(TIntermNode *root)
{
- TVersionGLSL versionGLSL(getShaderType(), getPragma());
+ 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.
@@ -52,9 +146,9 @@ void TranslatorGLSL::writeVersion(TIntermNode *root)
void TranslatorGLSL::writeExtensionBehavior() {
TInfoSinkBase& sink = getInfoSink().obj;
- const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
- for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
- iter != extensionBehavior.end(); ++iter) {
+ const TExtensionBehavior& extBehavior = getExtensionBehavior();
+ for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
+ iter != extBehavior.end(); ++iter) {
if (iter->second == EBhUndefined)
continue;
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h
index 766d8d910e..4a5a641096 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h
@@ -4,22 +4,24 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_TRANSLATORGLSL_H_
-#define COMPILER_TRANSLATORGLSL_H_
+#ifndef COMPILER_TRANSLATOR_TRANSLATORGLSL_H_
+#define COMPILER_TRANSLATOR_TRANSLATORGLSL_H_
#include "compiler/translator/Compiler.h"
class TranslatorGLSL : public TCompiler
{
public:
- TranslatorGLSL(sh::GLenum type, ShShaderSpec spec);
+ TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
protected:
- virtual void translate(TIntermNode *root);
+ void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) override;
+
+ virtual void translate(TIntermNode *root, int compileOptions);
private:
void writeVersion(TIntermNode *root);
void writeExtensionBehavior();
};
-#endif // COMPILER_TRANSLATORGLSL_H_
+#endif // COMPILER_TRANSLATOR_TRANSLATORGLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.cpp
index 22bf60e86e..f6275defa1 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.cpp
@@ -6,20 +6,26 @@
#include "compiler/translator/TranslatorHLSL.h"
-#include "compiler/translator/InitializeParseContext.h"
#include "compiler/translator/OutputHLSL.h"
+#include "compiler/translator/SimplifyArrayAssignment.h"
TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
: TCompiler(type, spec, output)
{
}
-void TranslatorHLSL::translate(TIntermNode *root)
+void TranslatorHLSL::translate(TIntermNode *root, int compileOptions)
{
- TParseContext& parseContext = *GetGlobalParseContext();
- sh::OutputHLSL outputHLSL(parseContext, this);
+ const ShBuiltInResources &resources = getResources();
+ int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
- outputHLSL.output();
+ SimplifyArrayAssignment simplify;
+ root->traverse(&simplify);
+
+ sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(),
+ getSourcePath(), getOutputType(), numRenderTargets, getUniforms(), compileOptions);
+
+ outputHLSL.output(root, getInfoSink().obj);
mInterfaceBlockRegisterMap = outputHLSL.getInterfaceBlockRegisterMap();
mUniformRegisterMap = outputHLSL.getUniformRegisterMap();
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.h b/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.h
index 11a042d83a..1920ed5755 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_TRANSLATORHLSL_H_
-#define COMPILER_TRANSLATORHLSL_H_
+#ifndef COMPILER_TRANSLATOR_TRANSLATORHLSL_H_
+#define COMPILER_TRANSLATOR_TRANSLATORHLSL_H_
#include "compiler/translator/Compiler.h"
@@ -22,10 +22,10 @@ class TranslatorHLSL : public TCompiler
unsigned int getUniformRegister(const std::string &uniformName) const;
protected:
- virtual void translate(TIntermNode* root);
+ virtual void translate(TIntermNode *root, int compileOptions);
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
std::map<std::string, unsigned int> mUniformRegisterMap;
};
-#endif // COMPILER_TRANSLATORHLSL_H_
+#endif // COMPILER_TRANSLATOR_TRANSLATORHLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/Types.cpp b/src/3rdparty/angle/src/compiler/translator/Types.cpp
index d36936fb23..b970bf5ac4 100644
--- a/src/3rdparty/angle/src/compiler/translator/Types.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/Types.cpp
@@ -178,11 +178,12 @@ size_t TType::getObjectSize() const
if (isArray())
{
- size_t arraySize = getArraySize();
- if (arraySize > INT_MAX / totalSize)
+ // TODO: getArraySize() returns an int, not a size_t
+ size_t currentArraySize = getArraySize();
+ if (currentArraySize > INT_MAX / totalSize)
totalSize = INT_MAX;
else
- totalSize *= arraySize;
+ totalSize *= currentArraySize;
}
return totalSize;
@@ -199,6 +200,17 @@ bool TStructure::containsArrays() const
return false;
}
+bool TStructure::containsSamplers() const
+{
+ for (size_t i = 0; i < mFields->size(); ++i)
+ {
+ const TType *fieldType = (*mFields)[i]->type();
+ if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
+ return true;
+ }
+ return false;
+}
+
TString TFieldListCollection::buildMangledName() const
{
TString mangledName(mangledNamePrefix());
diff --git a/src/3rdparty/angle/src/compiler/translator/Types.h b/src/3rdparty/angle/src/compiler/translator/Types.h
index 075196daa3..044f22c3c1 100644
--- a/src/3rdparty/angle/src/compiler/translator/Types.h
+++ b/src/3rdparty/angle/src/compiler/translator/Types.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef _TYPES_INCLUDED
-#define _TYPES_INCLUDED
+#ifndef COMPILER_TRANSLATOR_TYPES_H_
+#define COMPILER_TRANSLATOR_TYPES_H_
#include "common/angleutils.h"
@@ -17,7 +17,7 @@ struct TPublicType;
class TType;
class TSymbol;
-class TField
+class TField : angle::NonCopyable
{
public:
POOL_ALLOCATOR_NEW_DELETE();
@@ -49,7 +49,6 @@ class TField
}
private:
- DISALLOW_COPY_AND_ASSIGN(TField);
TType *mType;
TString *mName;
TSourceLoc mLine;
@@ -62,7 +61,7 @@ inline TFieldList *NewPoolTFieldList()
return new(memory) TFieldList;
}
-class TFieldListCollection
+class TFieldListCollection : angle::NonCopyable
{
public:
const TString &name() const
@@ -113,7 +112,8 @@ class TStructure : public TFieldListCollection
TStructure(const TString *name, TFieldList *fields)
: TFieldListCollection(name, fields),
mDeepestNesting(0),
- mUniqueId(0)
+ mUniqueId(0),
+ mAtGlobalScope(false)
{
}
@@ -124,6 +124,7 @@ class TStructure : public TFieldListCollection
return mDeepestNesting;
}
bool containsArrays() const;
+ bool containsSamplers() const;
bool equals(const TStructure &other) const;
@@ -138,9 +139,17 @@ class TStructure : public TFieldListCollection
return mUniqueId;
}
- private:
- DISALLOW_COPY_AND_ASSIGN(TStructure);
+ void setAtGlobalScope(bool atGlobalScope)
+ {
+ mAtGlobalScope = atGlobalScope;
+ }
+
+ bool atGlobalScope() const
+ {
+ return mAtGlobalScope;
+ }
+ private:
// 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.
@@ -159,6 +168,7 @@ class TStructure : public TFieldListCollection
mutable int mDeepestNesting;
int mUniqueId;
+ bool mAtGlobalScope;
};
class TInterfaceBlock : public TFieldListCollection
@@ -201,7 +211,6 @@ class TInterfaceBlock : public TFieldListCollection
}
private:
- DISALLOW_COPY_AND_ASSIGN(TInterfaceBlock);
virtual TString mangledNamePrefix() const
{
return "iblock-";
@@ -325,6 +334,10 @@ class TType
{
return primarySize > 1 && secondarySize > 1;
}
+ bool isNonSquareMatrix() const
+ {
+ return isMatrix() && primarySize != secondarySize;
+ }
bool isArray() const
{
return array ? true : false;
@@ -464,6 +477,11 @@ class TType
return structure ? structure->containsArrays() : false;
}
+ bool isStructureContainingSamplers() const
+ {
+ return structure ? structure->containsSamplers() : false;
+ }
+
protected:
TString buildMangledName() const;
size_t getStructSize() const;
@@ -584,4 +602,4 @@ struct TPublicType
}
};
-#endif // _TYPES_INCLUDED_
+#endif // COMPILER_TRANSLATOR_TYPES_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.cpp b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.cpp
index 65f50c4cc3..f79f9dd7fb 100644
--- a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.cpp
@@ -16,7 +16,7 @@
namespace sh
{
-UnfoldShortCircuit::UnfoldShortCircuit(TParseContext &context, OutputHLSL *outputHLSL) : mContext(context), mOutputHLSL(outputHLSL)
+UnfoldShortCircuit::UnfoldShortCircuit(OutputHLSL *outputHLSL) : mOutputHLSL(outputHLSL)
{
mTemporaryIndex = 0;
}
@@ -30,7 +30,7 @@ void UnfoldShortCircuit::traverse(TIntermNode *node)
bool UnfoldShortCircuit::visitBinary(Visit visit, TIntermBinary *node)
{
- TInfoSinkBase &out = mOutputHLSL->getBodyStream();
+ TInfoSinkBase &out = mOutputHLSL->getInfoSink();
// 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
@@ -111,7 +111,7 @@ bool UnfoldShortCircuit::visitBinary(Visit visit, TIntermBinary *node)
bool UnfoldShortCircuit::visitSelection(Visit visit, TIntermSelection *node)
{
- TInfoSinkBase &out = mOutputHLSL->getBodyStream();
+ TInfoSinkBase &out = mOutputHLSL->getInfoSink();
// Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;"
if (node->usesTernaryOperator())
diff --git a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.h b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.h
index 6fd3b457bd..eaceb0a0b3 100644
--- a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.h
+++ b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.h
@@ -6,8 +6,8 @@
// UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements
//
-#ifndef COMPILER_UNFOLDSHORTCIRCUIT_H_
-#define COMPILER_UNFOLDSHORTCIRCUIT_H_
+#ifndef COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_
+#define COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/ParseContext.h"
@@ -19,7 +19,7 @@ class OutputHLSL;
class UnfoldShortCircuit : public TIntermTraverser
{
public:
- UnfoldShortCircuit(TParseContext &context, OutputHLSL *outputHLSL);
+ UnfoldShortCircuit(OutputHLSL *outputHLSL);
void traverse(TIntermNode *node);
bool visitBinary(Visit visit, TIntermBinary*);
@@ -29,11 +29,10 @@ class UnfoldShortCircuit : public TIntermTraverser
int getNextTemporaryIndex();
protected:
- TParseContext &mContext;
OutputHLSL *const mOutputHLSL;
int mTemporaryIndex;
};
}
-#endif // COMPILER_UNFOLDSHORTCIRCUIT_H_
+#endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp
index 29c4397d56..d548d421d2 100644
--- a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp
@@ -50,32 +50,8 @@ bool UnfoldShortCircuitAST::visitBinary(Visit visit, TIntermBinary *node)
}
if (replacement)
{
- replacements.push_back(
- NodeUpdateEntry(getParentNode(), node, replacement));
+ mReplacements.push_back(
+ NodeUpdateEntry(getParentNode(), node, replacement, false));
}
return true;
}
-
-void UnfoldShortCircuitAST::updateTree()
-{
- for (size_t ii = 0; ii < replacements.size(); ++ii)
- {
- const NodeUpdateEntry& entry = replacements[ii];
- ASSERT(entry.parent);
- bool replaced = entry.parent->replaceChildNode(
- entry.original, entry.replacement);
- ASSERT(replaced);
-
- // In AST traversing, a parent is visited before its children.
- // After we replace a node, if an 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 < replacements.size(); ++jj)
- {
- NodeUpdateEntry& entry2 = replacements[jj];
- if (entry2.parent == entry.original)
- entry2.parent = entry.replacement;
- }
- }
-}
-
diff --git a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.h b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.h
index 3acaf7ee7c..7b698ccb63 100644
--- a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.h
+++ b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.h
@@ -7,8 +7,8 @@
// operations with ternary operations.
//
-#ifndef COMPILER_UNFOLD_SHORT_CIRCUIT_AST_H_
-#define COMPILER_UNFOLD_SHORT_CIRCUIT_AST_H_
+#ifndef COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_
+#define COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_
#include "common/angleutils.h"
#include "compiler/translator/IntermNode.h"
@@ -23,29 +23,6 @@ class UnfoldShortCircuitAST : public TIntermTraverser
UnfoldShortCircuitAST() { }
virtual bool visitBinary(Visit visit, TIntermBinary *);
-
- void updateTree();
-
- private:
- struct NodeUpdateEntry
- {
- NodeUpdateEntry(TIntermNode *_parent,
- TIntermNode *_original,
- TIntermNode *_replacement)
- : parent(_parent),
- original(_original),
- replacement(_replacement) {}
-
- TIntermNode *parent;
- TIntermNode *original;
- TIntermNode *replacement;
- };
-
- // During traversing, save all the replacements that need to happen;
- // then replace them by calling updateNodes().
- std::vector<NodeUpdateEntry> replacements;
-
- DISALLOW_COPY_AND_ASSIGN(UnfoldShortCircuitAST);
};
-#endif // COMPILER_UNFOLD_SHORT_CIRCUIT_AST_H_
+#endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/UniformHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/UniformHLSL.cpp
index 61b6ed7455..71659fe354 100644
--- a/src/3rdparty/angle/src/compiler/translator/UniformHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/UniformHLSL.cpp
@@ -7,14 +7,13 @@
// Methods for GLSL to HLSL translation for uniforms and interface blocks.
//
-#include "OutputHLSL.h"
-#include "common/blocklayout.h"
-#include "common/utilities.h"
#include "compiler/translator/UniformHLSL.h"
+
+#include "common/utilities.h"
#include "compiler/translator/StructureHLSL.h"
-#include "compiler/translator/util.h"
#include "compiler/translator/UtilsHLSL.h"
-#include "compiler/translator/TranslatorHLSL.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "compiler/translator/util.h"
namespace sh
{
@@ -61,13 +60,13 @@ static TString InterfaceBlockStructName(const TInterfaceBlock &interfaceBlock)
return DecoratePrivate(interfaceBlock.name()) + "_type";
}
-UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL, TranslatorHLSL *translator)
+UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType, const std::vector<Uniform> &uniforms)
: mUniformRegister(0),
mInterfaceBlockRegister(0),
mSamplerRegister(0),
mStructureHLSL(structureHLSL),
- mOutputType(translator->getOutputType()),
- mUniforms(translator->getUniforms())
+ mOutputType(outputType),
+ mUniforms(uniforms)
{}
void UniformHLSL::reserveUniformRegisters(unsigned int registerCount)
@@ -105,7 +104,7 @@ unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type, con
unsigned int registerCount = HLSLVariableRegisterCount(*uniform, mOutputType);
- if (gl::IsSampler(uniform->type))
+ if (gl::IsSamplerType(uniform->type))
{
mSamplerRegister += registerCount;
}
diff --git a/src/3rdparty/angle/src/compiler/translator/UniformHLSL.h b/src/3rdparty/angle/src/compiler/translator/UniformHLSL.h
index 91fa51588b..4ab9ccdf53 100644
--- a/src/3rdparty/angle/src/compiler/translator/UniformHLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/UniformHLSL.h
@@ -7,19 +7,19 @@
// Methods for GLSL to HLSL translation for uniforms and interface blocks.
//
-#ifndef TRANSLATOR_UNIFORMHLSL_H_
-#define TRANSLATOR_UNIFORMHLSL_H_
+#ifndef COMPILER_TRANSLATOR_UNIFORMHLSL_H_
+#define COMPILER_TRANSLATOR_UNIFORMHLSL_H_
-#include "compiler/translator/Types.h"
+#include "compiler/translator/OutputHLSL.h"
namespace sh
{
class StructureHLSL;
-class UniformHLSL
+class UniformHLSL : angle::NonCopyable
{
public:
- UniformHLSL(StructureHLSL *structureHLSL, TranslatorHLSL *translator);
+ UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType, const std::vector<Uniform> &uniforms);
void reserveUniformRegisters(unsigned int registerCount);
void reserveInterfaceBlockRegisters(unsigned int registerCount);
@@ -60,4 +60,4 @@ class UniformHLSL
}
-#endif // TRANSLATOR_UNIFORMHLSL_H_
+#endif // COMPILER_TRANSLATOR_UNIFORMHLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.cpp
index de0c36ca65..94e19ac40d 100644
--- a/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.cpp
@@ -175,6 +175,13 @@ TString StructNameString(const TStructure &structure)
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()) + "_" + structure.name();
}
diff --git a/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.h b/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.h
index aaa3ddf5d2..9800a3bbf3 100644
--- a/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.h
@@ -7,8 +7,8 @@
// Utility methods for GLSL to HLSL translation.
//
-#ifndef TRANSLATOR_UTILSHLSL_H_
-#define TRANSLATOR_UTILSHLSL_H_
+#ifndef COMPILER_TRANSLATOR_UTILSHLSL_H_
+#define COMPILER_TRANSLATOR_UTILSHLSL_H_
#include <vector>
#include "compiler/translator/Types.h"
@@ -34,4 +34,4 @@ TString QualifierString(TQualifier qualifier);
}
-#endif // TRANSLATOR_UTILSHLSL_H_
+#endif // COMPILER_TRANSLATOR_UTILSHLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp
index 896e1cd7a0..12367066e8 100644
--- a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp
@@ -47,93 +47,6 @@ class ValidateConstIndexExpr : public TIntermTraverser
TLoopStack& mLoopStack;
};
-const char *GetOperatorString(TOperator op)
-{
- switch (op)
- {
- case EOpInitialize: return "=";
- case EOpAssign: return "=";
- case EOpAddAssign: return "+=";
- case EOpSubAssign: return "-=";
- case EOpDivAssign: return "/=";
-
- // Fall-through.
- case EOpMulAssign:
- case EOpVectorTimesMatrixAssign:
- case EOpVectorTimesScalarAssign:
- case EOpMatrixTimesScalarAssign:
- case EOpMatrixTimesMatrixAssign: return "*=";
-
- // Fall-through.
- case EOpIndexDirect:
- case EOpIndexIndirect: return "[]";
-
- case EOpIndexDirectStruct:
- case EOpIndexDirectInterfaceBlock: return ".";
- case EOpVectorSwizzle: return ".";
- case EOpAdd: return "+";
- case EOpSub: return "-";
- case EOpMul: return "*";
- case EOpDiv: return "/";
- case EOpMod: UNIMPLEMENTED(); break;
- case EOpEqual: return "==";
- case EOpNotEqual: return "!=";
- case EOpLessThan: return "<";
- case EOpGreaterThan: return ">";
- case EOpLessThanEqual: return "<=";
- case EOpGreaterThanEqual: return ">=";
-
- // Fall-through.
- case EOpVectorTimesScalar:
- case EOpVectorTimesMatrix:
- case EOpMatrixTimesVector:
- case EOpMatrixTimesScalar:
- case EOpMatrixTimesMatrix: return "*";
-
- case EOpLogicalOr: return "||";
- case EOpLogicalXor: return "^^";
- case EOpLogicalAnd: return "&&";
- case EOpNegative: return "-";
- case EOpPositive: return "+";
- case EOpVectorLogicalNot: return "not";
- case EOpLogicalNot: return "!";
- case EOpPostIncrement: return "++";
- case EOpPostDecrement: return "--";
- case EOpPreIncrement: return "++";
- case EOpPreDecrement: return "--";
-
- case EOpRadians: return "radians";
- case EOpDegrees: return "degrees";
- case EOpSin: return "sin";
- case EOpCos: return "cos";
- case EOpTan: return "tan";
- case EOpAsin: return "asin";
- case EOpAcos: return "acos";
- case EOpAtan: return "atan";
- case EOpExp: return "exp";
- case EOpLog: return "log";
- case EOpExp2: return "exp2";
- case EOpLog2: return "log2";
- case EOpSqrt: return "sqrt";
- case EOpInverseSqrt: return "inversesqrt";
- case EOpAbs: return "abs";
- case EOpSign: return "sign";
- case EOpFloor: return "floor";
- case EOpCeil: return "ceil";
- case EOpFract: return "fract";
- case EOpLength: return "length";
- case EOpNormalize: return "normalize";
- case EOpDFdx: return "dFdx";
- case EOpDFdy: return "dFdy";
- case EOpFwidth: return "fwidth";
- case EOpAny: return "any";
- case EOpAll: return "all";
-
- default: break;
- }
- return "";
-}
-
} // namespace anonymous
ValidateLimitations::ValidateLimitations(sh::GLenum shaderType,
diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.h b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.h
index e6e8a9619f..59cccb565f 100644
--- a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.h
+++ b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.h
@@ -4,6 +4,9 @@
// found in the LICENSE file.
//
+#ifndef COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_
+#define COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_
+
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/LoopInfo.h"
@@ -53,3 +56,4 @@ class ValidateLimitations : public TIntermTraverser
TLoopStack mLoopStack;
};
+#endif // COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.h b/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.h
index 0f808dbb97..1538e0f157 100644
--- a/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.h
+++ b/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.h
@@ -4,6 +4,9 @@
// found in the LICENSE file.
//
+#ifndef COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
+#define COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
+
#include "compiler/translator/IntermNode.h"
#include <set>
@@ -31,3 +34,5 @@ class ValidateOutputs : public TIntermTraverser
void error(TSourceLoc loc, const char *reason, const char* token);
};
+
+#endif // COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.cpp
new file mode 100644
index 0000000000..9a4ed33632
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.cpp
@@ -0,0 +1,200 @@
+//
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/translator/ValidateSwitch.h"
+
+#include "compiler/translator/ParseContext.h"
+
+bool ValidateSwitch::validate(TBasicType switchType, TParseContext *context,
+ TIntermAggregate *statementList, const TSourceLoc &loc)
+{
+ ValidateSwitch validate(switchType, context);
+ ASSERT(statementList);
+ statementList->traverse(&validate);
+ return validate.validateInternal(loc);
+}
+
+ValidateSwitch::ValidateSwitch(TBasicType switchType, TParseContext *context)
+ : TIntermTraverser(true, false, true),
+ mSwitchType(switchType),
+ mContext(context),
+ mCaseTypeMismatch(false),
+ mFirstCaseFound(false),
+ mStatementBeforeCase(false),
+ mLastStatementWasCase(false),
+ mControlFlowDepth(0),
+ mCaseInsideControlFlow(false),
+ mDefaultCount(0),
+ mDuplicateCases(false)
+{}
+
+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::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::visitSelection(Visit visit, TIntermSelection *)
+{
+ 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)
+ {
+ mContext->error(node->getLine(), "label statement nested inside control flow", nodeStr);
+ mCaseInsideControlFlow = true;
+ }
+ mFirstCaseFound = true;
+ mLastStatementWasCase = true;
+ if (!node->hasCondition())
+ {
+ ++mDefaultCount;
+ if (mDefaultCount > 1)
+ {
+ mContext->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)
+ {
+ mContext->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())
+ {
+ mContext->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())
+ {
+ mContext->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)
+ {
+ mContext->error(loc,
+ "statement before the first label", "switch");
+ }
+ if (mLastStatementWasCase)
+ {
+ mContext->error(loc,
+ "no statement between the last label and the end of the switch statement", "switch");
+ }
+ return !mStatementBeforeCase && !mLastStatementWasCase && !mCaseInsideControlFlow &&
+ !mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases;
+}
diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.h b/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.h
new file mode 100644
index 0000000000..88b68a500e
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.h
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATESWITCH_H_
+#define COMPILER_TRANSLATOR_VALIDATESWITCH_H_
+
+#include "compiler/translator/IntermNode.h"
+
+struct TParseContext;
+
+class ValidateSwitch : public TIntermTraverser
+{
+ public:
+ // Check for errors and output messages any remaining errors on the context.
+ // Returns true if there are no errors.
+ static bool validate(TBasicType switchType, TParseContext *context,
+ TIntermAggregate *statementList, const TSourceLoc &loc);
+
+ void visitSymbol(TIntermSymbol *) override;
+ void visitConstantUnion(TIntermConstantUnion *) override;
+ bool visitBinary(Visit, TIntermBinary *) override;
+ bool visitUnary(Visit, TIntermUnary *) override;
+ bool visitSelection(Visit visit, TIntermSelection *) 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, TParseContext *context);
+
+ bool validateInternal(const TSourceLoc &loc);
+
+ TBasicType mSwitchType;
+ TParseContext *mContext;
+ 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;
+};
+
+#endif // COMPILER_TRANSLATOR_VALIDATESWITCH_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp b/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp
index d8e13788b7..cf229ec96a 100644
--- a/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp
@@ -142,8 +142,10 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
mPointCoordAdded(false),
mFrontFacingAdded(false),
mFragCoordAdded(false),
+ mInstanceIDAdded(false),
mPositionAdded(false),
mPointSizeAdded(false),
+ mLastFragDataAdded(false),
mHashFunction(hashFunction),
mSymbolTable(symbolTable)
{
@@ -249,6 +251,22 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
mPointCoordAdded = true;
}
return;
+ case EvqInstanceID:
+ if (!mInstanceIDAdded)
+ {
+ Attribute info;
+ const char kName[] = "gl_InstanceID";
+ info.name = kName;
+ info.mappedName = kName;
+ info.type = GL_INT;
+ info.arraySize = 0;
+ info.precision = GL_HIGH_INT; // Defined by spec.
+ info.staticUse = true;
+ info.location = -1;
+ mAttribs->push_back(info);
+ mInstanceIDAdded = true;
+ }
+ return;
case EvqPosition:
if (!mPositionAdded)
{
@@ -281,6 +299,22 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
mPointSizeAdded = true;
}
return;
+ case EvqLastFragData:
+ if (!mLastFragDataAdded)
+ {
+ Varying info;
+ const char kName[] = "gl_LastFragData";
+ info.name = kName;
+ info.mappedName = kName;
+ info.type = GL_FLOAT_VEC4;
+ info.arraySize = static_cast<const TVariable*>(mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100))->getConstPointer()->getIConst();
+ info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
+ info.staticUse = true;
+ info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
+ mVaryings->push_back(info);
+ mLastFragDataAdded = true;
+ }
+ return;
default:
break;
}
@@ -301,8 +335,6 @@ class NameHashingTraverser : public GetVariableTraverser
{}
private:
- DISALLOW_COPY_AND_ASSIGN(NameHashingTraverser);
-
virtual void visitVariable(ShaderVariable *variable)
{
TString stringName = TString(variable->name.c_str());
diff --git a/src/3rdparty/angle/src/compiler/translator/VariableInfo.h b/src/3rdparty/angle/src/compiler/translator/VariableInfo.h
index 92d376d879..bb1328a507 100644
--- a/src/3rdparty/angle/src/compiler/translator/VariableInfo.h
+++ b/src/3rdparty/angle/src/compiler/translator/VariableInfo.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_VARIABLE_INFO_H_
-#define COMPILER_VARIABLE_INFO_H_
+#ifndef COMPILER_TRANSLATOR_VARIABLEINFO_H_
+#define COMPILER_TRANSLATOR_VARIABLEINFO_H_
#include <GLSLANG/ShaderLang.h>
@@ -51,8 +51,10 @@ class CollectVariables : public TIntermTraverser
bool mFrontFacingAdded;
bool mFragCoordAdded;
+ bool mInstanceIDAdded;
bool mPositionAdded;
bool mPointSizeAdded;
+ bool mLastFragDataAdded;
ShHashFunction64 mHashFunction;
@@ -65,4 +67,4 @@ void ExpandUniforms(const std::vector<Uniform> &compact,
}
-#endif // COMPILER_VARIABLE_INFO_H_
+#endif // COMPILER_TRANSLATOR_VARIABLEINFO_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/VariablePacker.h b/src/3rdparty/angle/src/compiler/translator/VariablePacker.h
index 1de5332d8a..9c80eea618 100644
--- a/src/3rdparty/angle/src/compiler/translator/VariablePacker.h
+++ b/src/3rdparty/angle/src/compiler/translator/VariablePacker.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef _VARIABLEPACKER_INCLUDED_
-#define _VARIABLEPACKER_INCLUDED_
+#ifndef COMPILER_TRANSLATOR_VARIABLEPACKER_H_
+#define COMPILER_TRANSLATOR_VARIABLEPACKER_H_
#include <vector>
#include "compiler/translator/VariableInfo.h"
@@ -38,4 +38,4 @@ class VariablePacker {
std::vector<unsigned> rows_;
};
-#endif // _VARIABLEPACKER_INCLUDED_
+#endif // COMPILER_TRANSLATOR_VARIABLEPACKER_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp
index 05b111a7a7..f6f568897d 100644
--- a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp
@@ -8,6 +8,7 @@
static const int GLSL_VERSION_110 = 110;
static const int GLSL_VERSION_120 = 120;
+static const int GLSL_VERSION_150 = 150;
// We need to scan for the following:
// 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
@@ -26,12 +27,22 @@ static const int GLSL_VERSION_120 = 120;
// 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)
+TVersionGLSL::TVersionGLSL(sh::GLenum type,
+ const TPragma &pragma,
+ ShShaderOutput output)
{
- if (pragma.stdgl.invariantAll)
- mVersion = GLSL_VERSION_120;
+ if (output == SH_GLSL_CORE_OUTPUT)
+ {
+ mVersion = GLSL_VERSION_150;
+ }
else
- mVersion = GLSL_VERSION_110;
+ {
+ ASSERT(output == SH_GLSL_COMPATIBILITY_OUTPUT);
+ if (pragma.stdgl.invariantAll)
+ mVersion = GLSL_VERSION_120;
+ else
+ mVersion = GLSL_VERSION_110;
+ }
}
void TVersionGLSL::visitSymbol(TIntermSymbol *node)
diff --git a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h
index 72368e39d6..2b63d5f25d 100644
--- a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h
@@ -29,14 +29,16 @@
class TVersionGLSL : public TIntermTraverser
{
public:
- TVersionGLSL(sh::GLenum type, const TPragma &pragma);
-
- // Returns 120 if the following is used the shader:
- // - "invariant",
- // - "gl_PointCoord",
- // - matrix/matrix constructors
- // - array "out" parameters
- // Else 110 is returned.
+ 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() { return mVersion; }
virtual void visitSymbol(TIntermSymbol *);
diff --git a/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp b/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp
new file mode 100644
index 0000000000..7c74105680
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp
@@ -0,0 +1,123 @@
+//
+// Copyright (c) 2013-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.
+//
+// blocklayout.cpp:
+// Implementation for block layout classes and methods.
+//
+
+#include "compiler/translator/blocklayout.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+
+namespace sh
+{
+
+BlockLayoutEncoder::BlockLayoutEncoder()
+ : mCurrentOffset(0)
+{
+}
+
+BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
+{
+ int arrayStride;
+ int matrixStride;
+
+ getBlockLayoutInfo(type, arraySize, isRowMajorMatrix, &arrayStride, &matrixStride);
+
+ const BlockMemberInfo memberInfo(mCurrentOffset * BytesPerComponent, arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, isRowMajorMatrix);
+
+ advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride);
+
+ return memberInfo;
+}
+
+// static
+size_t BlockLayoutEncoder::getBlockRegister(const BlockMemberInfo &info)
+{
+ return (info.offset / BytesPerComponent) / ComponentsPerRegister;
+}
+
+// static
+size_t BlockLayoutEncoder::getBlockRegisterElement(const BlockMemberInfo &info)
+{
+ return (info.offset / BytesPerComponent) % ComponentsPerRegister;
+}
+
+void BlockLayoutEncoder::nextRegister()
+{
+ mCurrentOffset = rx::roundUp<size_t>(mCurrentOffset, ComponentsPerRegister);
+}
+
+Std140BlockEncoder::Std140BlockEncoder()
+{
+}
+
+void Std140BlockEncoder::enterAggregateType()
+{
+ nextRegister();
+}
+
+void Std140BlockEncoder::exitAggregateType()
+{
+ nextRegister();
+}
+
+void Std140BlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, 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)) == BytesPerComponent);
+
+ size_t baseAlignment = 0;
+ int matrixStride = 0;
+ int arrayStride = 0;
+
+ if (gl::IsMatrixType(type))
+ {
+ baseAlignment = ComponentsPerRegister;
+ matrixStride = ComponentsPerRegister;
+
+ if (arraySize > 0)
+ {
+ const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ arrayStride = ComponentsPerRegister * numRegisters;
+ }
+ }
+ else if (arraySize > 0)
+ {
+ baseAlignment = ComponentsPerRegister;
+ arrayStride = ComponentsPerRegister;
+ }
+ else
+ {
+ const int numComponents = gl::VariableComponentCount(type);
+ baseAlignment = (numComponents == 3 ? 4u : static_cast<size_t>(numComponents));
+ }
+
+ mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
+
+ *matrixStrideOut = matrixStride;
+ *arrayStrideOut = arrayStride;
+}
+
+void Std140BlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
+{
+ if (arraySize > 0)
+ {
+ mCurrentOffset += arrayStride * arraySize;
+ }
+ else if (gl::IsMatrixType(type))
+ {
+ ASSERT(matrixStride == ComponentsPerRegister);
+ const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ mCurrentOffset += ComponentsPerRegister * numRegisters;
+ }
+ else
+ {
+ mCurrentOffset += gl::VariableComponentCount(type);
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/common/blocklayout.h b/src/3rdparty/angle/src/compiler/translator/blocklayout.h
index d46ac6e547..c11357fe66 100644
--- a/src/3rdparty/angle/src/common/blocklayout.h
+++ b/src/3rdparty/angle/src/compiler/translator/blocklayout.h
@@ -24,7 +24,7 @@ struct Uniform;
struct Varying;
struct InterfaceBlock;
-struct BlockMemberInfo
+struct COMPILER_EXPORT BlockMemberInfo
{
BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
: offset(offset),
@@ -44,7 +44,7 @@ struct BlockMemberInfo
bool isRowMajorMatrix;
};
-class BlockLayoutEncoder
+class COMPILER_EXPORT BlockLayoutEncoder
{
public:
BlockLayoutEncoder();
@@ -61,6 +61,9 @@ class BlockLayoutEncoder
static const size_t BytesPerComponent = 4u;
static const unsigned int ComponentsPerRegister = 4u;
+ static size_t getBlockRegister(const BlockMemberInfo &info);
+ static size_t getBlockRegisterElement(const BlockMemberInfo &info);
+
protected:
size_t mCurrentOffset;
@@ -73,7 +76,7 @@ class BlockLayoutEncoder
// 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
+class COMPILER_EXPORT Std140BlockEncoder : public BlockLayoutEncoder
{
public:
Std140BlockEncoder();
@@ -86,42 +89,6 @@ class Std140BlockEncoder : public BlockLayoutEncoder
virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
};
-// 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);
-
- virtual void enterAggregateType();
- virtual void exitAggregateType();
- void skipRegisters(unsigned int numRegisters);
-
- bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
-
- static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
-
- protected:
- virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
- virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
-
- HLSLBlockEncoderStrategy mEncoderStrategy;
-};
-
-// 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 Varying &variable);
-unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType);
-
}
#endif // COMMON_BLOCKLAYOUT_H_
diff --git a/src/3rdparty/angle/src/common/blocklayout.cpp b/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.cpp
index e3b2d43566..f32cf2cf89 100644
--- a/src/3rdparty/angle/src/common/blocklayout.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.cpp
@@ -7,108 +7,17 @@
// Implementation for block layout classes and methods.
//
-#include "common/blocklayout.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+
#include "common/mathutil.h"
#include "common/utilities.h"
namespace sh
{
-BlockLayoutEncoder::BlockLayoutEncoder()
- : mCurrentOffset(0)
-{
-}
-
-BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
-{
- int arrayStride;
- int matrixStride;
-
- getBlockLayoutInfo(type, arraySize, isRowMajorMatrix, &arrayStride, &matrixStride);
-
- const BlockMemberInfo memberInfo(mCurrentOffset * BytesPerComponent, arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, isRowMajorMatrix);
-
- advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride);
-
- return memberInfo;
-}
-
-void BlockLayoutEncoder::nextRegister()
-{
- mCurrentOffset = rx::roundUp<size_t>(mCurrentOffset, ComponentsPerRegister);
-}
-
-Std140BlockEncoder::Std140BlockEncoder()
-{
-}
-
-void Std140BlockEncoder::enterAggregateType()
-{
- nextRegister();
-}
-
-void Std140BlockEncoder::exitAggregateType()
-{
- nextRegister();
-}
-
-void Std140BlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, 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)) == BytesPerComponent);
-
- size_t baseAlignment = 0;
- int matrixStride = 0;
- int arrayStride = 0;
-
- if (gl::IsMatrixType(type))
- {
- baseAlignment = ComponentsPerRegister;
- matrixStride = ComponentsPerRegister;
-
- if (arraySize > 0)
- {
- const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
- arrayStride = ComponentsPerRegister * numRegisters;
- }
- }
- else if (arraySize > 0)
- {
- baseAlignment = ComponentsPerRegister;
- arrayStride = ComponentsPerRegister;
- }
- else
- {
- const int numComponents = gl::VariableComponentCount(type);
- baseAlignment = (numComponents == 3 ? 4u : static_cast<size_t>(numComponents));
- }
-
- mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
-
- *matrixStrideOut = matrixStride;
- *arrayStrideOut = arrayStride;
-}
-
-void Std140BlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
-{
- if (arraySize > 0)
- {
- mCurrentOffset += arrayStride * arraySize;
- }
- else if (gl::IsMatrixType(type))
- {
- ASSERT(matrixStride == ComponentsPerRegister);
- const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
- mCurrentOffset += ComponentsPerRegister * numRegisters;
- }
- else
- {
- mCurrentOffset += gl::VariableComponentCount(type);
- }
-}
-
HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy)
- : mEncoderStrategy(strategy)
+ : mEncoderStrategy(strategy),
+ mTransposeMatrices(false)
{
}
@@ -121,8 +30,10 @@ void HLSLBlockEncoder::exitAggregateType()
{
}
-void HLSLBlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
+void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn, unsigned int arraySize, 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)) == BytesPerComponent);
@@ -166,8 +77,10 @@ void HLSLBlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, b
*arrayStrideOut = arrayStride;
}
-void HLSLBlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
+void HLSLBlockEncoder::advanceOffset(GLenum typeIn, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
{
+ GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
+
if (arraySize > 0)
{
mCurrentOffset += arrayStride * (arraySize - 1);
@@ -230,9 +143,10 @@ void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *
}
}
-unsigned int HLSLVariableRegisterCount(const Varying &variable)
+unsigned int HLSLVariableRegisterCount(const Varying &variable, bool transposeMatrices)
{
HLSLBlockEncoder encoder(HLSLBlockEncoder::ENCODE_PACKED);
+ encoder.setTransposeMatrices(transposeMatrices);
HLSLVariableRegisterCount(variable, &encoder);
const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister);
diff --git a/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.h b/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.h
new file mode 100644
index 0000000000..c61cb1ae57
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.h
@@ -0,0 +1,62 @@
+//
+// Copyright (c) 2013-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.
+//
+// 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 "angle_gl.h"
+#include "blocklayout.h"
+#include <GLSLANG/ShaderLang.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 COMPILER_EXPORT HLSLBlockEncoder : public BlockLayoutEncoder
+{
+ public:
+ enum HLSLBlockEncoderStrategy
+ {
+ ENCODE_PACKED,
+ ENCODE_LOOSE
+ };
+
+ HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy);
+
+ virtual void enterAggregateType();
+ virtual void exitAggregateType();
+ void skipRegisters(unsigned int numRegisters);
+
+ bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
+ void setTransposeMatrices(bool enabled) { mTransposeMatrices = enabled; }
+
+ static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
+
+ protected:
+ virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut);
+ virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride);
+
+ 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).
+COMPILER_EXPORT unsigned int HLSLVariableRegisterCount(const Varying &variable, bool transposeMatrices);
+COMPILER_EXPORT unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType);
+
+}
+
+#endif // COMMON_BLOCKLAYOUTHLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/compilerdebug.h b/src/3rdparty/angle/src/compiler/translator/compilerdebug.h
index 7a371516af..84a12ad2f8 100644
--- a/src/3rdparty/angle/src/compiler/translator/compilerdebug.h
+++ b/src/3rdparty/angle/src/compiler/translator/compilerdebug.h
@@ -6,8 +6,8 @@
// debug.h: Debugging utilities.
-#ifndef COMPILER_DEBUG_H_
-#define COMPILER_DEBUG_H_
+#ifndef COMPILER_TRANSLATOR_COMPILERDEBUG_H_
+#define COMPILER_TRANSLATOR_COMPILERDEBUG_H_
#include <assert.h>
@@ -49,5 +49,5 @@ void Trace(const char* format, ...);
assert(false); \
} while(0)
-#endif // COMPILER_DEBUG_H_
+#endif // COMPILER_TRANSLATOR_COMPILERDEBUG_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.h b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.h
index bc25fe7cbc..22db633678 100644
--- a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.h
+++ b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H
-#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H
+#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_
+#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_
#include "compiler/translator/IntermNode.h"
@@ -186,7 +186,7 @@ private:
//
// When using this, just fill in the methods for nodes you want visited.
//
-class TDependencyGraphTraverser {
+class TDependencyGraphTraverser : angle::NonCopyable {
public:
TDependencyGraphTraverser() : mDepth(0) {}
@@ -209,4 +209,4 @@ private:
TGraphNodeSet mVisited;
};
-#endif
+#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h
index b76f075e68..f7b3bd4b43 100644
--- a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h
+++ b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
-#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
+#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_
+#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_
#include "compiler/translator/depgraph/DependencyGraph.h"
@@ -104,7 +104,7 @@ class TDependencyGraphBuilder : public TIntermTraverser
// An instance of this class pushes a new node set when instantiated.
// When the instance goes out of scope, it and pops the node set.
//
- class TNodeSetMaintainer
+ class TNodeSetMaintainer : angle::NonCopyable
{
public:
TNodeSetMaintainer(TDependencyGraphBuilder *factory)
@@ -122,7 +122,7 @@ class TDependencyGraphBuilder : public TIntermTraverser
// When the instance goes out of scope, it and pops the top node set and adds
// its contents to the new top node set.
//
- class TNodeSetPropagatingMaintainer
+ class TNodeSetPropagatingMaintainer : angle::NonCopyable
{
public:
TNodeSetPropagatingMaintainer(TDependencyGraphBuilder *factory)
@@ -147,7 +147,7 @@ class TDependencyGraphBuilder : public TIntermTraverser
// kRightSubtree will never be replaced by a real symbol because we are tracking
// the leftmost symbol.
//
- class TLeftmostSymbolMaintainer
+ class TLeftmostSymbolMaintainer : angle::NonCopyable
{
public:
TLeftmostSymbolMaintainer(
@@ -196,4 +196,4 @@ class TDependencyGraphBuilder : public TIntermTraverser
TSymbolStack mLeftmostSymbols;
};
-#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
+#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h
index c3a4112278..b201e0a671 100644
--- a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h
+++ b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h
@@ -4,27 +4,28 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_OUTPUT_H
-#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_OUTPUT_H
+#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_
+#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_
#include "compiler/translator/depgraph/DependencyGraph.h"
#include "compiler/translator/InfoSink.h"
-class TDependencyGraphOutput : public TDependencyGraphTraverser {
-public:
+class TDependencyGraphOutput : public TDependencyGraphTraverser
+{
+ public:
TDependencyGraphOutput(TInfoSinkBase& sink) : mSink(sink) {}
- virtual void visitSymbol(TGraphSymbol* symbol);
- virtual void visitArgument(TGraphArgument* parameter);
- virtual void visitFunctionCall(TGraphFunctionCall* functionCall);
- virtual void visitSelection(TGraphSelection* selection);
- virtual void visitLoop(TGraphLoop* loop);
- virtual void visitLogicalOp(TGraphLogicalOp* logicalOp);
+ void visitSymbol(TGraphSymbol* symbol) override;
+ void visitArgument(TGraphArgument* parameter) override;
+ void visitFunctionCall(TGraphFunctionCall* functionCall) override;
+ void visitSelection(TGraphSelection* selection) override;
+ void visitLoop(TGraphLoop* loop) override;
+ void visitLogicalOp(TGraphLogicalOp* logicalOp) override;
void outputAllSpanningTrees(TDependencyGraph& graph);
-private:
+ private:
void outputIndentation();
TInfoSinkBase& mSink;
};
-#endif // COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_OUTPUT_H
+#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/glslang.h b/src/3rdparty/angle/src/compiler/translator/glslang.h
index f221199093..db31e6946c 100644
--- a/src/3rdparty/angle/src/compiler/translator/glslang.h
+++ b/src/3rdparty/angle/src/compiler/translator/glslang.h
@@ -4,6 +4,9 @@
// found in the LICENSE file.
//
+#ifndef COMPILER_TRANSLATOR_GLSLANG_H_
+#define COMPILER_TRANSLATOR_GLSLANG_H_
+
struct TParseContext;
extern int glslang_initialize(TParseContext* context);
extern int glslang_finalize(TParseContext* context);
@@ -14,3 +17,4 @@ extern int glslang_scan(size_t count,
TParseContext* context);
extern int glslang_parse(TParseContext* context);
+#endif // COMPILER_TRANSLATOR_GLSLANG_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/glslang.l b/src/3rdparty/angle/src/compiler/translator/glslang.l
index 518b78df11..ee4d28b6d6 100644
--- a/src/3rdparty/angle/src/compiler/translator/glslang.l
+++ b/src/3rdparty/angle/src/compiler/translator/glslang.l
@@ -32,6 +32,7 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
#pragma warning(disable: 4189)
#pragma warning(disable: 4505)
#pragma warning(disable: 4701)
+#pragma warning(disable: 4702)
#endif
}
@@ -70,6 +71,7 @@ static int floatsuffix_check(TParseContext* context);
%option noyywrap nounput never-interactive
%option yylineno reentrant bison-bridge bison-locations
%option extra-type="TParseContext*"
+%x FIELDS
D [0-9]
L [a-zA-Z_]
@@ -358,7 +360,7 @@ O [0-7]
")" { return RIGHT_PAREN; }
("["|"<:") { return LEFT_BRACKET; }
("]"|":>") { return RIGHT_BRACKET; }
-"." { return DOT; }
+"." { BEGIN(FIELDS); return DOT; }
"!" { return BANG; }
"-" { return DASH; }
"~" { return TILDE; }
@@ -373,9 +375,16 @@ O [0-7]
"&" { return AMPERSAND; }
"?" { return QUESTION; }
+<FIELDS>{L}({L}|{D})* {
+ BEGIN(INITIAL);
+ yylval->lex.string = NewPoolTString(yytext);
+ return FIELD_SELECTION;
+}
+<FIELDS>[ \t\v\f\r] {}
+
[ \t\v\n\f\r] { }
-<<EOF>> { yyterminate(); }
-. { assert(false); return 0; }
+<*><<EOF>> { yyterminate(); }
+<*>. { assert(false); return 0; }
%%
@@ -492,8 +501,8 @@ int floatsuffix_check(TParseContext* context)
return(FLOATCONSTANT);
}
-void yyerror(YYLTYPE* lloc, TParseContext* context, const char* reason) {
- context->error(*lloc, reason, yyget_text(context->scanner));
+void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* reason) {
+ context->error(*lloc, reason, yyget_text(scanner));
context->recover();
}
diff --git a/src/3rdparty/angle/src/compiler/translator/glslang.y b/src/3rdparty/angle/src/compiler/translator/glslang.y
index e271de978c..6024898cb0 100644
--- a/src/3rdparty/angle/src/compiler/translator/glslang.y
+++ b/src/3rdparty/angle/src/compiler/translator/glslang.y
@@ -32,6 +32,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
#pragma warning(disable: 4189)
#pragma warning(disable: 4505)
#pragma warning(disable: 4701)
+#pragma warning(disable: 4702)
#endif
#include "angle_gl.h"
@@ -41,12 +42,11 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
#define YYENABLE_NLS 0
-#define YYLEX_PARAM context->scanner
-
%}
%expect 1 /* One shift reduce conflict because of if | else */
-%pure-parser
%parse-param {TParseContext* context}
+%param {void *scanner}
+%define api.pure full
%locations
%code requires {
@@ -72,6 +72,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
TIntermNodePair nodePair;
TIntermTyped* intermTypedNode;
TIntermAggregate* intermAggregate;
+ TIntermSwitch* intermSwitch;
+ TIntermCase* intermCase;
};
union {
TPublicType type;
@@ -88,11 +90,11 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
%{
extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
-extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason);
+extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, const char* reason);
#define YYLLOC_DEFAULT(Current, Rhs, N) \
do { \
- if (YYID(N)) { \
+ 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; \
@@ -179,6 +181,8 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason)
%type <interm.intermNode> declaration external_declaration
%type <interm.intermNode> for_init_statement compound_statement_no_new_scope
%type <interm.nodePair> selection_rest_statement for_rest_statement
+%type <interm.intermSwitch> switch_statement
+%type <interm.intermCase> case_label
%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope
%type <interm> single_declaration init_declarator_list
@@ -269,28 +273,14 @@ postfix_expression
| function_call {
$$ = $1;
}
- | postfix_expression DOT identifier {
+ | postfix_expression DOT FIELD_SELECTION {
$$ = context->addFieldSelectionExpression($1, @2, *$3.string, @3);
}
| postfix_expression INC_OP {
- if (context->lValueErrorCheck(@2, "++", $1))
- context->recover();
- $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, @2);
- if ($$ == 0) {
- context->unaryOpError(@2, "++", $1->getCompleteString());
- context->recover();
- $$ = $1;
- }
+ $$ = context->addUnaryMathLValue(EOpPostIncrement, $1, @2);
}
| postfix_expression DEC_OP {
- if (context->lValueErrorCheck(@2, "--", $1))
- context->recover();
- $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, @2);
- if ($$ == 0) {
- context->unaryOpError(@2, "--", $1->getCompleteString());
- context->recover();
- $$ = $1;
- }
+ $$ = context->addUnaryMathLValue(EOpPostDecrement, $1, @2);
}
;
@@ -304,118 +294,12 @@ integer_expression
function_call
: function_call_or_method {
- TFunction* fnCall = $1.function;
- TOperator op = fnCall->getBuiltInOp();
-
- if (op != EOpNull)
+ bool fatalError = false;
+ $$ = context->addFunctionCallOrMethod($1.function, $1.intermNode, @1, &fatalError);
+ if (fatalError)
{
- //
- // Then this should be a constructor.
- // Don't go through the symbol table for constructors.
- // Their parameters will be verified algorithmically.
- //
- TType type(EbtVoid, EbpUndefined); // use this to get the type back
- if (context->constructorErrorCheck(@1, $1.intermNode, *fnCall, op, &type)) {
- $$ = 0;
- } else {
- //
- // It's a constructor, of type 'type'.
- //
- $$ = context->addConstructor($1.intermNode, &type, op, fnCall, @1);
- }
-
- if ($$ == 0) {
- context->recover();
- $$ = context->intermediate.setAggregateOperator(0, op, @1);
- }
- $$->setType(type);
- } else {
- //
- // Not a constructor. Find it in the symbol table.
- //
- const TFunction* fnCandidate;
- bool builtIn;
- fnCandidate = context->findFunction(@1, fnCall, context->shaderVersion, &builtIn);
- if (fnCandidate) {
- //
- // A declared function.
- //
- if (builtIn && !fnCandidate->getExtension().empty() &&
- context->extensionErrorCheck(@1, fnCandidate->getExtension())) {
- context->recover();
- }
- op = fnCandidate->getBuiltInOp();
- if (builtIn && op != EOpNull) {
- //
- // A function call mapped to a built-in operation.
- //
- if (fnCandidate->getParamCount() == 1) {
- //
- // Treat it like a built-in unary operator.
- //
- $$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1);
- const TType& returnType = fnCandidate->getReturnType();
- if (returnType.getBasicType() == EbtBool) {
- // Bool types should not have precision, so we'll override any precision
- // that might have been set by addUnaryMath.
- $$->setType(returnType);
- } else {
- // addUnaryMath has set the precision of the node based on the operand.
- $$->setTypePreservePrecision(returnType);
- }
- if ($$ == 0) {
- std::stringstream extraInfoStream;
- extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
- std::string extraInfo = extraInfoStream.str();
- context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str());
- YYERROR;
- }
- } else {
- TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
- aggregate->setType(fnCandidate->getReturnType());
- aggregate->setPrecisionFromChildren();
- $$ = aggregate;
- }
- } else {
- // This is a real function call
-
- TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
- aggregate->setType(fnCandidate->getReturnType());
-
- // this is how we know whether the given function is a builtIn function or a user defined function
- // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
- // if builtIn == true, it's definitely a builtIn function with EOpNull
- if (!builtIn)
- aggregate->setUserDefined();
- aggregate->setName(fnCandidate->getMangledName());
-
- // This needs to happen after the name is set
- if (builtIn)
- aggregate->setBuiltInFunctionPrecision();
-
- $$ = aggregate;
-
- TQualifier qual;
- for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
- qual = fnCandidate->getParam(i).type->getQualifier();
- if (qual == EvqOut || qual == EvqInOut) {
- if (context->lValueErrorCheck($$->getLine(), "assign", (*($$->getAsAggregate()->getSequence()))[i]->getAsTyped())) {
- context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error");
- context->recover();
- }
- }
- }
- }
- } else {
- // error message was put out by PaFindFunction()
- // Put on a dummy node for error recovery
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setFConst(0.0f);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
- context->recover();
- }
+ YYERROR;
}
- delete fnCall;
}
;
@@ -484,6 +368,13 @@ function_identifier
TFunction *function = new TFunction($1.string, type);
$$ = function;
}
+ | FIELD_SELECTION {
+ if (context->reservedErrorCheck(@1, *$1.string))
+ context->recover();
+ TType type(EbtVoid, EbpUndefined);
+ TFunction *function = new TFunction($1.string, type);
+ $$ = function;
+ }
;
unary_expression
@@ -491,40 +382,14 @@ unary_expression
$$ = $1;
}
| INC_OP unary_expression {
- if (context->lValueErrorCheck(@1, "++", $2))
- context->recover();
- $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, @1);
- if ($$ == 0) {
- context->unaryOpError(@1, "++", $2->getCompleteString());
- context->recover();
- $$ = $2;
- }
+ $$ = context->addUnaryMathLValue(EOpPreIncrement, $2, @1);
}
| DEC_OP unary_expression {
- if (context->lValueErrorCheck(@1, "--", $2))
- context->recover();
- $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, @1);
- if ($$ == 0) {
- context->unaryOpError(@1, "--", $2->getCompleteString());
- context->recover();
- $$ = $2;
- }
+ $$ = context->addUnaryMathLValue(EOpPreDecrement, $2, @1);
}
| unary_operator unary_expression {
if ($1.op != EOpNull) {
- $$ = context->intermediate.addUnaryMath($1.op, $2, @1);
- if ($$ == 0) {
- const char* errorOp = "";
- switch($1.op) {
- case EOpNegative: errorOp = "-"; break;
- case EOpPositive: errorOp = "+"; break;
- case EOpLogicalNot: errorOp = "!"; break;
- default: break;
- }
- context->unaryOpError(@1, errorOp, $2->getCompleteString());
- context->recover();
- $$ = $2;
- }
+ $$ = context->addUnaryMath($1.op, $2, @1);
} else
$$ = $2;
}
@@ -535,172 +400,117 @@ unary_operator
: PLUS { $$.op = EOpPositive; }
| DASH { $$.op = EOpNegative; }
| BANG { $$.op = EOpLogicalNot; }
+ | TILDE {
+ ES3_ONLY("~", @$, "bit-wise operator");
+ $$.op = EOpBitwiseNot;
+ }
;
// Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
multiplicative_expression
: unary_expression { $$ = $1; }
| multiplicative_expression STAR unary_expression {
- $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, "*", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- $$ = $1;
- }
+ $$ = context->addBinaryMath(EOpMul, $1, $3, @2);
}
| multiplicative_expression SLASH unary_expression {
- $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, "/", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- $$ = $1;
- }
+ $$ = context->addBinaryMath(EOpDiv, $1, $3, @2);
+ }
+ | multiplicative_expression PERCENT unary_expression {
+ ES3_ONLY("%", @2, "integer modulus operator");
+ $$ = context->addBinaryMath(EOpIMod, $1, $3, @2);
}
;
additive_expression
: multiplicative_expression { $$ = $1; }
| additive_expression PLUS multiplicative_expression {
- $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, "+", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- $$ = $1;
- }
+ $$ = context->addBinaryMath(EOpAdd, $1, $3, @2);
}
| additive_expression DASH multiplicative_expression {
- $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, "-", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- $$ = $1;
- }
+ $$ = context->addBinaryMath(EOpSub, $1, $3, @2);
}
;
shift_expression
: additive_expression { $$ = $1; }
+ | shift_expression LEFT_OP additive_expression {
+ ES3_ONLY("<<", @2, "bit-wise operator");
+ $$ = context->addBinaryMath(EOpBitShiftLeft, $1, $3, @2);
+ }
+ | shift_expression RIGHT_OP additive_expression {
+ ES3_ONLY(">>", @2, "bit-wise operator");
+ $$ = context->addBinaryMath(EOpBitShiftRight, $1, $3, @2);
+ }
;
relational_expression
: shift_expression { $$ = $1; }
| relational_expression LEFT_ANGLE shift_expression {
- $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, "<", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
- }
+ $$ = context->addBinaryMathBooleanResult(EOpLessThan, $1, $3, @2);
}
| relational_expression RIGHT_ANGLE shift_expression {
- $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, ">", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
- }
+ $$ = context->addBinaryMathBooleanResult(EOpGreaterThan, $1, $3, @2);
}
| relational_expression LE_OP shift_expression {
- $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, "<=", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
- }
+ $$ = context->addBinaryMathBooleanResult(EOpLessThanEqual, $1, $3, @2);
}
| relational_expression GE_OP shift_expression {
- $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, ">=", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
- }
+ $$ = context->addBinaryMathBooleanResult(EOpGreaterThanEqual, $1, $3, @2);
}
;
equality_expression
: relational_expression { $$ = $1; }
| equality_expression EQ_OP relational_expression {
- $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, "==", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
- }
+ $$ = context->addBinaryMathBooleanResult(EOpEqual, $1, $3, @2);
}
| equality_expression NE_OP relational_expression {
- $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, "!=", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
- }
+ $$ = context->addBinaryMathBooleanResult(EOpNotEqual, $1, $3, @2);
}
;
and_expression
: equality_expression { $$ = $1; }
+ | and_expression AMPERSAND equality_expression {
+ ES3_ONLY("&", @2, "bit-wise operator");
+ $$ = context->addBinaryMath(EOpBitwiseAnd, $1, $3, @2);
+ }
;
exclusive_or_expression
: and_expression { $$ = $1; }
+ | exclusive_or_expression CARET and_expression {
+ ES3_ONLY("^", @2, "bit-wise operator");
+ $$ = context->addBinaryMath(EOpBitwiseXor, $1, $3, @2);
+ }
;
inclusive_or_expression
: exclusive_or_expression { $$ = $1; }
+ | inclusive_or_expression VERTICAL_BAR exclusive_or_expression {
+ ES3_ONLY("|", @2, "bit-wise operator");
+ $$ = context->addBinaryMath(EOpBitwiseOr, $1, $3, @2);
+ }
;
logical_and_expression
: inclusive_or_expression { $$ = $1; }
| logical_and_expression AND_OP inclusive_or_expression {
- $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, "&&", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
- }
+ $$ = context->addBinaryMathBooleanResult(EOpLogicalAnd, $1, $3, @2);
}
;
logical_xor_expression
: logical_and_expression { $$ = $1; }
| logical_xor_expression XOR_OP logical_and_expression {
- $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, "^^", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
- }
+ $$ = context->addBinaryMathBooleanResult(EOpLogicalXor, $1, $3, @2);
}
;
logical_or_expression
: logical_xor_expression { $$ = $1; }
| logical_or_expression OR_OP logical_xor_expression {
- $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, @2);
- if ($$ == 0) {
- context->binaryOpError(@2, "||", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- ConstantUnion *unionArray = new ConstantUnion[1];
- unionArray->setBConst(false);
- $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
- }
+ $$ = context->addBinaryMathBooleanResult(EOpLogicalOr, $1, $3, @2);
}
;
@@ -727,12 +537,7 @@ assignment_expression
| unary_expression assignment_operator assignment_expression {
if (context->lValueErrorCheck(@2, "assign", $1))
context->recover();
- $$ = context->intermediate.addAssign($2.op, $1, $3, @2);
- if ($$ == 0) {
- context->assignError(@2, "assign", $1->getCompleteString(), $3->getCompleteString());
- context->recover();
- $$ = $1;
- }
+ $$ = context->addAssign($2.op, $1, $3, @2);
}
;
@@ -740,8 +545,32 @@ assignment_operator
: EQUAL { $$.op = EOpAssign; }
| MUL_ASSIGN { $$.op = EOpMulAssign; }
| DIV_ASSIGN { $$.op = EOpDivAssign; }
+ | MOD_ASSIGN {
+ ES3_ONLY("%=", @$, "integer modulus operator");
+ $$.op = EOpIModAssign;
+ }
| ADD_ASSIGN { $$.op = EOpAddAssign; }
| SUB_ASSIGN { $$.op = EOpSubAssign; }
+ | LEFT_ASSIGN {
+ ES3_ONLY("<<=", @$, "bit-wise operator");
+ $$.op = EOpBitShiftLeftAssign;
+ }
+ | RIGHT_ASSIGN {
+ ES3_ONLY(">>=", @$, "bit-wise operator");
+ $$.op = EOpBitShiftRightAssign;
+ }
+ | AND_ASSIGN {
+ ES3_ONLY("&=", @$, "bit-wise operator");
+ $$.op = EOpBitwiseAndAssign;
+ }
+ | XOR_ASSIGN {
+ ES3_ONLY("^=", @$, "bit-wise operator");
+ $$.op = EOpBitwiseXorAssign;
+ }
+ | OR_ASSIGN {
+ ES3_ONLY("|=", @$, "bit-wise operator");
+ $$.op = EOpBitwiseOrAssign;
+ }
;
expression
@@ -877,7 +706,7 @@ function_prototype
{
// Insert the unmangled name to detect potential future redefinition as a variable.
TFunction *function = new TFunction(NewPoolTString($1->getName().c_str()), $1->getReturnType());
- context->symbolTable.getOuterLevel()->insert(function);
+ context->symbolTable.getOuterLevel()->insertUnmangled(function);
}
//
@@ -1599,12 +1428,14 @@ statement
| simple_statement { $$ = $1; }
;
-// Grammar Note: No labeled statements; 'goto' is not supported.
+// Grammar Note: Labeled statements for SWITCH only; 'goto' is not supported.
simple_statement
: declaration_statement { $$ = $1; }
| expression_statement { $$ = $1; }
| selection_statement { $$ = $1; }
+ | switch_statement { $$ = $1; }
+ | case_label { $$ = $1; }
| iteration_statement { $$ = $1; }
| jump_statement { $$ = $1; }
;
@@ -1677,7 +1508,21 @@ selection_rest_statement
}
;
-// Grammar Note: No 'switch'. Switch statements not supported.
+switch_statement
+ : SWITCH LEFT_PAREN expression RIGHT_PAREN { ++context->mSwitchNestingLevel; } compound_statement {
+ $$ = context->addSwitch($3, $6, @1);
+ --context->mSwitchNestingLevel;
+ }
+ ;
+
+case_label
+ : CASE constant_expression COLON {
+ $$ = context->addCase($2, @1);
+ }
+ | DEFAULT COLON {
+ $$ = context->addDefault(@1);
+ }
+ ;
condition
// In 1996 c++ draft, conditions can include single declarations
@@ -1703,22 +1548,22 @@ condition
;
iteration_statement
- : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
+ : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->mLoopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
context->symbolTable.pop();
$$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, @1);
- --context->loopNestingLevel;
+ --context->mLoopNestingLevel;
}
- | DO { ++context->loopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
+ | DO { ++context->mLoopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
if (context->boolErrorCheck(@8, $6))
context->recover();
$$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
- --context->loopNestingLevel;
+ --context->mLoopNestingLevel;
}
- | FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
+ | FOR LEFT_PAREN { context->symbolTable.push(); ++context->mLoopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
context->symbolTable.pop();
$$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, @1);
- --context->loopNestingLevel;
+ --context->mLoopNestingLevel;
}
;
@@ -1753,40 +1598,20 @@ for_rest_statement
jump_statement
: CONTINUE SEMICOLON {
- if (context->loopNestingLevel <= 0) {
- context->error(@1, "continue statement only allowed in loops", "");
- context->recover();
- }
- $$ = context->intermediate.addBranch(EOpContinue, @1);
+ $$ = context->addBranch(EOpContinue, @1);
}
| BREAK SEMICOLON {
- if (context->loopNestingLevel <= 0) {
- context->error(@1, "break statement only allowed in loops", "");
- context->recover();
- }
- $$ = context->intermediate.addBranch(EOpBreak, @1);
+ $$ = context->addBranch(EOpBreak, @1);
}
| RETURN SEMICOLON {
- $$ = context->intermediate.addBranch(EOpReturn, @1);
- if (context->currentFunctionType->getBasicType() != EbtVoid) {
- context->error(@1, "non-void function must return a value", "return");
- context->recover();
- }
+ $$ = context->addBranch(EOpReturn, @1);
}
| RETURN expression SEMICOLON {
- $$ = context->intermediate.addBranch(EOpReturn, $2, @1);
- context->functionReturnsValue = true;
- if (context->currentFunctionType->getBasicType() == EbtVoid) {
- context->error(@1, "void function cannot return a value", "return");
- context->recover();
- } else if (*(context->currentFunctionType) != $2->getType()) {
- context->error(@1, "function return is not matching type:", "return");
- context->recover();
- }
+ $$ = context->addBranch(EOpReturn, $2, @1);
}
| DISCARD SEMICOLON {
FRAG_ONLY("discard", @1);
- $$ = context->intermediate.addBranch(EOpKill, @1);
+ $$ = context->addBranch(EOpKill, @1);
}
;
@@ -1857,7 +1682,7 @@ function_definition
// Remember the return type for later checking for RETURN statements.
//
context->currentFunctionType = &(prevDec->getReturnType());
- context->functionReturnsValue = false;
+ context->mFunctionReturnsValue = false;
//
// Insert parameters into the symbol table.
@@ -1896,12 +1721,12 @@ function_definition
}
context->intermediate.setAggregateOperator(paramNodes, EOpParameters, @1);
$1.intermAggregate = paramNodes;
- context->loopNestingLevel = 0;
+ context->mLoopNestingLevel = 0;
}
compound_statement_no_new_scope {
//?? Check that all paths return a value if return type != void ?
// May be best done as post process phase on intermediate code
- if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
+ if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->mFunctionReturnsValue) {
context->error(@1, "function does not return a value:", "", $1.function->getName().c_str());
context->recover();
}
@@ -1923,5 +1748,5 @@ function_definition
%%
int glslang_parse(TParseContext* context) {
- return yyparse(context);
+ return yyparse(context, context->scanner);
}
diff --git a/src/3rdparty/angle/src/compiler/translator/intermOut.cpp b/src/3rdparty/angle/src/compiler/translator/intermOut.cpp
index 00780f0454..07c50f0ce5 100644
--- a/src/3rdparty/angle/src/compiler/translator/intermOut.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/intermOut.cpp
@@ -131,6 +131,25 @@ bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node)
case EOpDivAssign:
out << "divide second child into first child";
break;
+ case EOpIModAssign:
+ out << "modulo second child into first child";
+ break;
+ case EOpBitShiftLeftAssign:
+ out << "bit-wise shift first child left by second child";
+ break;
+ case EOpBitShiftRightAssign:
+ out << "bit-wise shift first child right by second child";
+ break;
+ case EOpBitwiseAndAssign:
+ out << "bit-wise and second child into first child";
+ break;
+ case EOpBitwiseXorAssign:
+ out << "bit-wise xor second child into first child";
+ break;
+ case EOpBitwiseOrAssign:
+ out << "bit-wise or second child into first child";
+ break;
+
case EOpIndexDirect:
out << "direct index";
break;
@@ -159,6 +178,25 @@ bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node)
case EOpDiv:
out << "divide";
break;
+ case EOpIMod:
+ out << "modulo";
+ break;
+ case EOpBitShiftLeft:
+ out << "bit-wise shift left";
+ break;
+ case EOpBitShiftRight:
+ out << "bit-wise shift right";
+ break;
+ case EOpBitwiseAnd:
+ out << "bit-wise and";
+ break;
+ case EOpBitwiseXor:
+ out << "bit-wise xor";
+ break;
+ case EOpBitwiseOr:
+ out << "bit-wise or";
+ break;
+
case EOpEqual:
out << "Compare Equal";
break;
@@ -211,6 +249,36 @@ bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node)
out << "\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)
+ {
+ mDepth++;
+ node->getLeft()->traverse(this);
+ mDepth--;
+
+ TIntermConstantUnion *intermConstantUnion = node->getRight()->getAsConstantUnion();
+ ASSERT(intermConstantUnion);
+
+ OutputTreeText(out, intermConstantUnion, mDepth + 1);
+
+ // The following code finds the field name from the constant union
+ const ConstantUnion *constantUnion = intermConstantUnion->getUnionArrayPointer();
+ 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()];
+
+ out << constantUnion->getIConst() << " (field '" << field->name() << "')";
+
+ return false;
+ }
+
return true;
}
@@ -226,6 +294,7 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
case EOpPositive: out << "Positive sign"; break;
case EOpVectorLogicalNot:
case EOpLogicalNot: out << "Negate conditional"; break;
+ case EOpBitwiseNot: out << "bit-wise not"; break;
case EOpPostIncrement: out << "Post-Increment"; break;
case EOpPostDecrement: out << "Post-Decrement"; break;
@@ -241,6 +310,13 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
case EOpAcos: out << "arc cosine"; break;
case EOpAtan: out << "arc tangent"; break;
+ case EOpSinh: out << "hyperbolic sine"; break;
+ case EOpCosh: out << "hyperbolic cosine"; break;
+ case EOpTanh: out << "hyperbolic tangent"; break;
+ case EOpAsinh: out << "arc hyperbolic sine"; break;
+ case EOpAcosh: out << "arc hyperbolic cosine"; break;
+ case EOpAtanh: out << "arc hyperbolic tangent"; break;
+
case EOpExp: out << "exp"; break;
case EOpLog: out << "log"; break;
case EOpExp2: out << "exp2"; break;
@@ -251,8 +327,26 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
case EOpAbs: out << "Absolute value"; break;
case EOpSign: out << "Sign"; break;
case EOpFloor: out << "Floor"; break;
+ case EOpTrunc: out << "Truncate"; break;
+ case EOpRound: out << "Round"; break;
+ case EOpRoundEven: out << "Round half even"; break;
case EOpCeil: out << "Ceiling"; break;
case EOpFract: out << "Fraction"; break;
+ case EOpIsNan: out << "Is not a number"; break;
+ case EOpIsInf: out << "Is infinity"; break;
+
+ case EOpFloatBitsToInt: out << "float bits to int"; break;
+ case EOpFloatBitsToUint: out << "float bits to uint"; break;
+ case EOpIntBitsToFloat: out << "int bits to float"; break;
+ case EOpUintBitsToFloat: out << "uint bits to float"; break;
+
+ case EOpPackSnorm2x16: out << "pack Snorm 2x16"; break;
+ case EOpPackUnorm2x16: out << "pack Unorm 2x16"; break;
+ case EOpPackHalf2x16: out << "pack half 2x16"; break;
+
+ case EOpUnpackSnorm2x16: out << "unpack Snorm 2x16"; break;
+ case EOpUnpackUnorm2x16: out << "unpack Unorm 2x16"; break;
+ case EOpUnpackHalf2x16: out << "unpack half 2x16"; break;
case EOpLength: out << "length"; break;
case EOpNormalize: out << "normalize"; break;
@@ -260,6 +354,10 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
// case EOpDPdy: out << "dPdy"; break;
// case EOpFwidth: out << "fwidth"; break;
+ case EOpDeterminant: out << "determinant"; break;
+ case EOpTranspose: out << "transpose"; break;
+ case EOpInverse: out << "inverse"; break;
+
case EOpAny: out << "any"; break;
case EOpAll: out << "all"; break;
@@ -326,6 +424,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpVectorNotEqual: out << "NotEqual"; break;
case EOpMod: out << "mod"; break;
+ case EOpModf: out << "modf"; break;
case EOpPow: out << "pow"; break;
case EOpAtan: out << "arc tangent"; break;
@@ -345,6 +444,8 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpRefract: out << "refract"; break;
case EOpMul: out << "component-wise multiply"; break;
+ case EOpOuterProduct: out << "outer product"; break;
+
case EOpDeclaration: out << "Declaration: "; break;
case EOpInvariantDeclaration: out << "Invariant Declaration: "; break;
@@ -518,14 +619,13 @@ bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch *node)
//
// This function is the one to call externally to start the traversal.
// Individual functions can be initialized to 0 to skip processing of that
-// type of node. It's children will still be processed.
+// type of node. Its children will still be processed.
//
-void TIntermediate::outputTree(TIntermNode *root)
+void TIntermediate::outputTree(TIntermNode *root, TInfoSinkBase &infoSink)
{
- if (root == NULL)
- return;
+ TOutputTraverser it(infoSink);
- TOutputTraverser it(mInfoSink.info);
+ ASSERT(root);
root->traverse(&it);
}
diff --git a/src/3rdparty/angle/src/compiler/translator/length_limits.h b/src/3rdparty/angle/src/compiler/translator/length_limits.h
index df70ee5d84..88634381fa 100644
--- a/src/3rdparty/angle/src/compiler/translator/length_limits.h
+++ b/src/3rdparty/angle/src/compiler/translator/length_limits.h
@@ -8,8 +8,8 @@
// length_limits.h
//
-#if !defined(__LENGTH_LIMITS_H)
-#define __LENGTH_LIMITS_H 1
+#ifndef COMPILER_TRANSLATOR_LENGTHLIMITS_H_
+#define COMPILER_TRANSLATOR_LENGTHLIMITS_H_
#include "GLSLANG/ShaderLang.h"
@@ -18,4 +18,4 @@
size_t GetGlobalMaxTokenSize(ShShaderSpec spec);
-#endif // !(defined(__LENGTH_LIMITS_H)
+#endif // COMPILER_TRANSLATOR_LENGTHLIMITS_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h b/src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h
index 80d5f7fa7f..b8c7e82956 100644
--- a/src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h
+++ b/src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h
@@ -4,35 +4,36 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_
-#define COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_
+#ifndef COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_
+#define COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/depgraph/DependencyGraph.h"
class TInfoSinkBase;
-class RestrictFragmentShaderTiming : TDependencyGraphTraverser {
-public:
- RestrictFragmentShaderTiming(TInfoSinkBase& sink);
- void enforceRestrictions(const TDependencyGraph& graph);
+class RestrictFragmentShaderTiming : TDependencyGraphTraverser
+{
+ public:
+ RestrictFragmentShaderTiming(TInfoSinkBase &sink);
+ void enforceRestrictions(const TDependencyGraph &graph);
int numErrors() const { return mNumErrors; }
- virtual void visitArgument(TGraphArgument* parameter);
- virtual void visitSelection(TGraphSelection* selection);
- virtual void visitLoop(TGraphLoop* loop);
- virtual void visitLogicalOp(TGraphLogicalOp* logicalOp);
+ void visitArgument(TGraphArgument *parameter) override;
+ void visitSelection(TGraphSelection *selection) override;
+ void visitLoop(TGraphLoop *loop) override;
+ void visitLogicalOp(TGraphLogicalOp *logicalOp) override;
-private:
- void beginError(const TIntermNode* node);
- void validateUserDefinedFunctionCallUsage(const TDependencyGraph& graph);
- bool isSamplingOp(const TIntermAggregate* intermFunctionCall) const;
+ private:
+ void beginError(const TIntermNode *node);
+ void validateUserDefinedFunctionCallUsage(const TDependencyGraph &graph);
+ bool isSamplingOp(const TIntermAggregate *intermFunctionCall) const;
- TInfoSinkBase& mSink;
+ TInfoSinkBase &mSink;
int mNumErrors;
typedef std::set<TString> StringSet;
StringSet mSamplingOps;
};
-#endif // COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_
+#endif // COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h b/src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h
index a6263567b4..74bfd0b5c2 100644
--- a/src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h
+++ b/src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_
-#define COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_
+#ifndef COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_
+#define COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/InfoSink.h"
@@ -28,4 +28,4 @@ private:
int mNumErrors;
};
-#endif // COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_
+#endif // COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/util.cpp b/src/3rdparty/angle/src/compiler/translator/util.cpp
index 8cc06a658a..42a995ee6f 100644
--- a/src/3rdparty/angle/src/compiler/translator/util.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/util.cpp
@@ -307,7 +307,7 @@ void GetVariableTraverser::setTypeSpecificInfo(
break;
case EvqVaryingIn:
case EvqVaryingOut:
- if (mSymbolTable.isVaryingInvariant(name))
+ if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())))
{
variable->isInvariant = true;
}
diff --git a/src/3rdparty/angle/src/compiler/translator/util.h b/src/3rdparty/angle/src/compiler/translator/util.h
index fb5308759e..68bae66168 100644
--- a/src/3rdparty/angle/src/compiler/translator/util.h
+++ b/src/3rdparty/angle/src/compiler/translator/util.h
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#ifndef COMPILER_UTIL_H
-#define COMPILER_UTIL_H
+#ifndef COMPILER_TRANSLATOR_UTIL_H_
+#define COMPILER_TRANSLATOR_UTIL_H_
#include <stack>
@@ -37,7 +37,7 @@ bool IsVarying(TQualifier qualifier);
InterpolationType GetInterpolationType(TQualifier qualifier);
TString ArrayString(const TType &type);
-class GetVariableTraverser
+class GetVariableTraverser : angle::NonCopyable
{
public:
GetVariableTraverser(const TSymbolTable &symbolTable);
@@ -57,10 +57,8 @@ class GetVariableTraverser
const TType &type, const TString &name, VarT *variable) {}
const TSymbolTable &mSymbolTable;
-
- DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser);
};
}
-#endif // COMPILER_UTIL_H
+#endif // COMPILER_TRANSLATOR_UTIL_H_
diff --git a/src/3rdparty/angle/src/id/commit.h b/src/3rdparty/angle/src/id/commit.h
new file mode 100644
index 0000000000..fd9a011d0c
--- /dev/null
+++ b/src/3rdparty/angle/src/id/commit.h
@@ -0,0 +1,3 @@
+#define ANGLE_COMMIT_HASH "99f075dade7c"
+#define ANGLE_COMMIT_HASH_SIZE 12
+#define ANGLE_COMMIT_DATE "2015-04-02 17:07:24 +0000"
diff --git a/src/3rdparty/angle/src/libEGL/AttributeMap.cpp b/src/3rdparty/angle/src/libANGLE/AttributeMap.cpp
index 28dd3d842e..651a012037 100644
--- a/src/3rdparty/angle/src/libEGL/AttributeMap.cpp
+++ b/src/3rdparty/angle/src/libANGLE/AttributeMap.cpp
@@ -4,7 +4,7 @@
// found in the LICENSE file.
//
-#include "libEGL/AttributeMap.h"
+#include "libANGLE/AttributeMap.h"
namespace egl
{
@@ -15,9 +15,12 @@ AttributeMap::AttributeMap()
AttributeMap::AttributeMap(const EGLint *attributes)
{
- for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2)
+ if (attributes)
{
- insert(curAttrib[0], curAttrib[1]);
+ for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2)
+ {
+ insert(curAttrib[0], curAttrib[1]);
+ }
}
}
@@ -37,4 +40,14 @@ EGLint AttributeMap::get(EGLint key, EGLint defaultValue) const
return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue;
}
+AttributeMap::const_iterator AttributeMap::begin() const
+{
+ return mAttributes.begin();
+}
+
+AttributeMap::const_iterator AttributeMap::end() const
+{
+ return mAttributes.end();
+}
+
}
diff --git a/src/3rdparty/angle/src/libEGL/AttributeMap.h b/src/3rdparty/angle/src/libANGLE/AttributeMap.h
index f2f082fe21..72b6edc3c7 100644
--- a/src/3rdparty/angle/src/libEGL/AttributeMap.h
+++ b/src/3rdparty/angle/src/libANGLE/AttributeMap.h
@@ -4,8 +4,9 @@
// found in the LICENSE file.
//
-#ifndef LIBEGL_ATTRIBUTEMAP_H_
-#define LIBEGL_ATTRIBUTEMAP_H_
+#ifndef LIBANGLE_ATTRIBUTEMAP_H_
+#define LIBANGLE_ATTRIBUTEMAP_H_
+
#include <EGL/egl.h>
@@ -24,10 +25,15 @@ class AttributeMap
virtual bool contains(EGLint key) const;
virtual EGLint get(EGLint key, EGLint defaultValue) const;
+ typedef std::map<EGLint, EGLint>::const_iterator const_iterator;
+
+ const_iterator begin() const;
+ const_iterator end() const;
+
private:
std::map<EGLint, EGLint> mAttributes;
};
}
-#endif // LIBEGL_ATTRIBUTEMAP_H_
+#endif // LIBANGLE_ATTRIBUTEMAP_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h b/src/3rdparty/angle/src/libANGLE/BinaryStream.h
index 4f7f5f2c85..50392e1d3f 100644
--- a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
+++ b/src/3rdparty/angle/src/libANGLE/BinaryStream.h
@@ -6,8 +6,8 @@
// BinaryStream.h: Provides binary serialization of simple types.
-#ifndef LIBGLESV2_BINARYSTREAM_H_
-#define LIBGLESV2_BINARYSTREAM_H_
+#ifndef LIBANGLE_BINARYSTREAM_H_
+#define LIBANGLE_BINARYSTREAM_H_
#include "common/angleutils.h"
#include "common/mathutil.h"
@@ -17,10 +17,22 @@
#include <vector>
#include <stdint.h>
+template <typename T>
+void StaticAssertIsFundamental()
+{
+ // c++11 STL is not available on OSX or Android
+#if !defined(ANGLE_PLATFORM_APPLE) && !defined(ANGLE_PLATFORM_ANDROID)
+ static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
+#else
+ union { T dummy; } dummy;
+ static_cast<void>(dummy);
+#endif
+}
+
namespace gl
{
-class BinaryInputStream
+class BinaryInputStream : angle::NonCopyable
{
public:
BinaryInputStream(const void *data, size_t length)
@@ -122,7 +134,6 @@ class BinaryInputStream
}
private:
- DISALLOW_COPY_AND_ASSIGN(BinaryInputStream);
bool mError;
size_t mOffset;
const uint8_t *mData;
@@ -131,7 +142,7 @@ class BinaryInputStream
template <typename T>
void read(T *v, size_t num)
{
- META_ASSERT(std::is_fundamental<T>::value);
+ StaticAssertIsFundamental<T>();
size_t length = num * sizeof(T);
@@ -153,7 +164,7 @@ class BinaryInputStream
};
-class BinaryOutputStream
+class BinaryOutputStream : angle::NonCopyable
{
public:
BinaryOutputStream()
@@ -191,13 +202,12 @@ class BinaryOutputStream
}
private:
- DISALLOW_COPY_AND_ASSIGN(BinaryOutputStream);
std::vector<char> mData;
template <typename T>
void write(const T *v, size_t num)
{
- META_ASSERT(std::is_fundamental<T>::value);
+ StaticAssertIsFundamental<T>();
const char *asBytes = reinterpret_cast<const char*>(v);
mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T));
}
@@ -205,4 +215,4 @@ class BinaryOutputStream
};
}
-#endif // LIBGLESV2_BINARYSTREAM_H_
+#endif // LIBANGLE_BINARYSTREAM_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp b/src/3rdparty/angle/src/libANGLE/Buffer.cpp
index 3b2a1a912a..f394a6b1d1 100644
--- a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Buffer.cpp
@@ -8,9 +8,9 @@
// index data. Implements GL buffer objects and related functionality.
// [OpenGL ES 2.0.24] section 2.9 page 21.
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/renderer/BufferImpl.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/renderer/BufferImpl.h"
+#include "libANGLE/renderer/Renderer.h"
namespace gl
{
@@ -118,11 +118,4 @@ Error Buffer::unmap()
return error;
}
-void Buffer::markTransformFeedbackUsage()
-{
- // TODO: Only used by the DX11 backend. Refactor to a more appropriate place.
- mBuffer->markTransformFeedbackUsage();
- mIndexRangeCache.clear();
-}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libANGLE/Buffer.h
index daa862ca0d..6793028e3b 100644
--- a/src/3rdparty/angle/src/libGLESv2/Buffer.h
+++ b/src/3rdparty/angle/src/libANGLE/Buffer.h
@@ -8,14 +8,14 @@
// index data. Implements GL buffer objects and related functionality.
// [OpenGL ES 2.0.24] section 2.9 page 21.
-#ifndef LIBGLESV2_BUFFER_H_
-#define LIBGLESV2_BUFFER_H_
+#ifndef LIBANGLE_BUFFER_H_
+#define LIBANGLE_BUFFER_H_
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/renderer/IndexRangeCache.h"
#include "common/angleutils.h"
-#include "common/RefCountObject.h"
-#include "libGLESv2/renderer/IndexRangeCache.h"
namespace rx
{
@@ -48,14 +48,10 @@ class Buffer : public RefCountObject
rx::BufferImpl *getImplementation() const { return mBuffer; }
- void markTransformFeedbackUsage();
-
rx::IndexRangeCache *getIndexRangeCache() { return &mIndexRangeCache; }
const rx::IndexRangeCache *getIndexRangeCache() const { return &mIndexRangeCache; }
private:
- DISALLOW_COPY_AND_ASSIGN(Buffer);
-
rx::BufferImpl *mBuffer;
GLenum mUsage;
@@ -71,4 +67,4 @@ class Buffer : public RefCountObject
}
-#endif // LIBGLESV2_BUFFER_H_
+#endif // LIBANGLE_BUFFER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Caps.cpp b/src/3rdparty/angle/src/libANGLE/Caps.cpp
index 983800c0e6..086d0a02a2 100644
--- a/src/3rdparty/angle/src/libGLESv2/Caps.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Caps.cpp
@@ -4,7 +4,7 @@
// found in the LICENSE file.
//
-#include "libGLESv2/Caps.h"
+#include "libANGLE/Caps.h"
#include "common/debug.h"
#include "common/angleutils.h"
@@ -13,6 +13,14 @@
#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
{
@@ -119,6 +127,9 @@ Extensions::Extensions()
packReverseRowOrder(false),
standardDerivatives(false),
shaderTextureLOD(false),
+ shaderFramebufferFetch(false),
+ ARMshaderFramebufferFetch(false),
+ NVshaderFramebufferFetch(false),
fragDepth(false),
textureUsage(false),
translatedShaderSource(false),
@@ -126,14 +137,6 @@ Extensions::Extensions()
{
}
-static void InsertExtensionString(const std::string &extension, bool supported, std::vector<std::string> *extensionVector)
-{
- if (supported)
- {
- extensionVector->push_back(extension);
- }
-}
-
std::vector<std::string> Extensions::getStrings() const
{
std::vector<std::string> extensionStrings;
@@ -173,6 +176,9 @@ std::vector<std::string> Extensions::getStrings() const
InsertExtensionString("GL_ANGLE_pack_reverse_row_order", packReverseRowOrder, &extensionStrings);
InsertExtensionString("GL_OES_standard_derivatives", standardDerivatives, &extensionStrings);
InsertExtensionString("GL_EXT_shader_texture_lod", shaderTextureLOD, &extensionStrings);
+ InsertExtensionString("GL_NV_shader_framebuffer_fetch", NVshaderFramebufferFetch, &extensionStrings);
+ InsertExtensionString("GL_ARM_shader_framebuffer_fetch", ARMshaderFramebufferFetch,&extensionStrings);
+ InsertExtensionString("GL_EXT_shader_framebuffer_fetch", shaderFramebufferFetch, &extensionStrings);
InsertExtensionString("GL_EXT_frag_depth", fragDepth, &extensionStrings);
InsertExtensionString("GL_ANGLE_texture_usage", textureUsage, &extensionStrings);
InsertExtensionString("GL_ANGLE_translated_shader_source", translatedShaderSource, &extensionStrings);
@@ -371,6 +377,41 @@ void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
colorBufferFloat = DetermineColorBufferFloatSupport(textureCaps);
}
+TypePrecision::TypePrecision()
+{
+ range[0] = 0;
+ range[1] = 0;
+ precision = 0;
+}
+
+void TypePrecision::setIEEEFloat()
+{
+ range[0] = 127;
+ range[1] = 127;
+ precision = 23;
+}
+
+void TypePrecision::setTwosComplementInt(unsigned int bits)
+{
+ range[0] = GLint(bits) - 1;
+ range[1] = GLint(bits) - 2;
+ precision = 0;
+}
+
+void TypePrecision::setSimulatedInt(unsigned int r)
+{
+ range[0] = GLint(r);
+ range[1] = GLint(r);
+ precision = 0;
+}
+
+void TypePrecision::get(GLint *returnRange, GLint *returnPrecision) const
+{
+ returnRange[0] = range[0];
+ returnRange[1] = range[1];
+ *returnPrecision = precision;
+}
+
Caps::Caps()
: maxElementIndex(0),
max3DTextureSize(0),
@@ -423,3 +464,64 @@ Caps::Caps()
}
}
+
+namespace egl
+{
+
+Caps::Caps()
+ : textureNPOT(false)
+{
+}
+
+DisplayExtensions::DisplayExtensions()
+ : createContextRobustness(false),
+ d3dShareHandleClientBuffer(false),
+ surfaceD3DTexture2DShareHandle(false),
+ querySurfacePointer(false),
+ windowFixedSize(false),
+ postSubBuffer(false),
+ createContext(false)
+{
+}
+
+std::vector<std::string> DisplayExtensions::getStrings() const
+{
+ std::vector<std::string> extensionStrings;
+
+ // | Extension name | Supported flag | Output vector |
+ InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings);
+ InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings);
+ InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings);
+
+ return extensionStrings;
+}
+
+
+ClientExtensions::ClientExtensions()
+ : clientExtensions(false),
+ platformBase(false),
+ platformANGLE(false),
+ platformANGLED3D(false),
+ platformANGLEOpenGL(false)
+{
+}
+
+std::vector<std::string> ClientExtensions::getStrings() const
+{
+ std::vector<std::string> extensionStrings;
+
+ // | Extension name | Supported flag | Output vector |
+ InsertExtensionString("EGL_EXT_client_extensions", clientExtensions, &extensionStrings);
+ InsertExtensionString("EGL_EXT_platform_base", platformBase, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings);
+
+ return extensionStrings;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/Caps.h b/src/3rdparty/angle/src/libANGLE/Caps.h
index a00e554176..37a634226a 100644
--- a/src/3rdparty/angle/src/libGLESv2/Caps.h
+++ b/src/3rdparty/angle/src/libANGLE/Caps.h
@@ -1,18 +1,19 @@
-#ifndef LIBGLESV2_CAPS_H
-#define LIBGLESV2_CAPS_H
-
//
// Copyright (c) 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/angletypes.h"
+#include <map>
#include <set>
-#include <unordered_map>
-#include <vector>
#include <string>
+#include <vector>
namespace gl
{
@@ -45,7 +46,7 @@ struct TextureCaps
class TextureCapsMap
{
public:
- typedef std::unordered_map<GLenum, TextureCaps>::const_iterator const_iterator;
+ typedef std::map<GLenum, TextureCaps>::const_iterator const_iterator;
void insert(GLenum internalFormat, const TextureCaps &caps);
void remove(GLenum internalFormat);
@@ -58,7 +59,7 @@ class TextureCapsMap
size_t size() const;
private:
- typedef std::unordered_map<GLenum, TextureCaps> InternalFormatToCapsMap;
+ typedef std::map<GLenum, TextureCaps> InternalFormatToCapsMap;
InternalFormatToCapsMap mCapsMap;
};
@@ -190,6 +191,15 @@ struct Extensions
// GL_EXT_shader_texture_lod
bool shaderTextureLOD;
+ // GL_EXT_shader_framebuffer_fetch
+ bool shaderFramebufferFetch;
+
+ // GL_ARM_shader_framebuffer_fetch
+ bool ARMshaderFramebufferFetch;
+
+ // GL_NV_shader_framebuffer_fetch
+ bool NVshaderFramebufferFetch;
+
// GL_EXT_frag_depth
bool fragDepth;
@@ -205,6 +215,20 @@ struct Extensions
bool colorBufferFloat;
};
+struct TypePrecision
+{
+ TypePrecision();
+
+ void setIEEEFloat();
+ void setTwosComplementInt(unsigned int bits);
+ void setSimulatedInt(unsigned int range);
+
+ void get(GLint *returnRange, GLint *returnPrecision) const;
+
+ GLint range[2];
+ GLint precision;
+};
+
struct Caps
{
Caps();
@@ -232,6 +256,18 @@ struct Caps
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;
GLuint64 maxServerWaitTimeout;
// Table 6.31, implementation dependent vertex shader limits
@@ -270,4 +306,69 @@ struct Caps
}
-#endif // LIBGLESV2_CAPS_H
+namespace egl
+{
+
+struct Caps
+{
+ Caps();
+
+ // Support for NPOT surfaces
+ bool textureNPOT;
+};
+
+struct DisplayExtensions
+{
+ DisplayExtensions();
+
+ // Generate a vector of supported extension strings
+ std::vector<std::string> getStrings() const;
+
+ // EGL_EXT_create_context_robustness
+ bool createContextRobustness;
+
+ // EGL_ANGLE_d3d_share_handle_client_buffer
+ bool d3dShareHandleClientBuffer;
+
+ // EGL_ANGLE_surface_d3d_texture_2d_share_handle
+ bool surfaceD3DTexture2DShareHandle;
+
+ // EGL_ANGLE_query_surface_pointer
+ bool querySurfacePointer;
+
+ // EGL_ANGLE_window_fixed_size
+ bool windowFixedSize;
+
+ // EGL_NV_post_sub_buffer
+ bool postSubBuffer;
+
+ // EGL_KHR_create_context
+ bool createContext;
+};
+
+struct ClientExtensions
+{
+ ClientExtensions();
+
+ // Generate a vector of supported extension strings
+ std::vector<std::string> getStrings() const;
+
+ // EGL_EXT_client_extensions
+ bool clientExtensions;
+
+ // EGL_EXT_platform_base
+ bool platformBase;
+
+ // EGL_ANGLE_platform_angle
+ bool platformANGLE;
+
+ // EGL_ANGLE_platform_angle_d3d
+ bool platformANGLED3D;
+
+ // EGL_ANGLE_platform_angle_opengl
+ bool platformANGLEOpenGL;
+};
+
+}
+
+#endif // LIBANGLE_CAPS_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Compiler.cpp b/src/3rdparty/angle/src/libANGLE/Compiler.cpp
new file mode 100644
index 0000000000..7d0efea220
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Compiler.cpp
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 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 "libANGLE/renderer/CompilerImpl.h"
+
+#include "common/debug.h"
+
+namespace gl
+{
+
+Compiler::Compiler(rx::CompilerImpl *impl)
+ : mCompiler(impl)
+{
+ ASSERT(mCompiler);
+}
+
+Compiler::~Compiler()
+{
+ SafeDelete(mCompiler);
+}
+
+Error Compiler::release()
+{
+ return mCompiler->release();
+}
+
+rx::CompilerImpl *Compiler::getImplementation()
+{
+ return mCompiler;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/Compiler.h b/src/3rdparty/angle/src/libANGLE/Compiler.h
new file mode 100644
index 0000000000..05de15ec97
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Compiler.h
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 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 "libANGLE/Error.h"
+
+namespace rx
+{
+class CompilerImpl;
+}
+
+namespace gl
+{
+
+class Compiler final
+{
+ public:
+ explicit Compiler(rx::CompilerImpl *impl);
+ ~Compiler();
+
+ Error release();
+
+ rx::CompilerImpl *getImplementation();
+
+ private:
+ rx::CompilerImpl *mCompiler;
+};
+
+}
+
+#endif // LIBANGLE_COMPILER_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Config.cpp b/src/3rdparty/angle/src/libANGLE/Config.cpp
new file mode 100644
index 0000000000..1b1fc50cb3
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Config.cpp
@@ -0,0 +1,275 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// 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 "angle_gl.h"
+#include <EGL/eglext.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),
+ colorBufferType(EGL_NONE),
+ 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)
+{
+}
+
+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 = 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) \
+ if (x.attribute != y.attribute) \
+ { \
+ return x.attribute < y.attribute; \
+ }
+
+ static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "Unexpected EGL enum value.");
+ SORT(configCaveat);
+
+ 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:
+ void scanForWantedComponents(const AttributeMap &attributeMap)
+ {
+ // [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.
+ for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++)
+ {
+ EGLint attributeKey = attribIter->first;
+ EGLint attributeValue = attribIter->second;
+ if (attributeKey != 0 && attributeValue != EGL_DONT_CARE)
+ {
+ switch (attributeKey)
+ {
+ case EGL_RED_SIZE: mWantRed = true; break;
+ case EGL_GREEN_SIZE: mWantGreen = true; break;
+ case EGL_BLUE_SIZE: mWantBlue = true; break;
+ case EGL_ALPHA_SIZE: mWantAlpha = true; break;
+ case EGL_LUMINANCE_SIZE: mWantLuminance = true; break;
+ }
+ }
+ }
+ }
+
+ 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++)
+ {
+ EGLint attributeKey = attribIter->first;
+ EGLint attributeValue = attribIter->second;
+
+ 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 == (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 == (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 == (EGLenum)attributeValue; break;
+ case EGL_TRANSPARENT_BLUE_VALUE: match = config.transparentBlueValue == attributeValue; break;
+ case EGL_TRANSPARENT_GREEN_VALUE: match = config.transparentGreenValue == attributeValue; break;
+ case EGL_TRANSPARENT_RED_VALUE: match = config.transparentRedValue == attributeValue; break;
+ case EGL_BIND_TO_TEXTURE_RGB: match = config.bindToTextureRGB == (EGLBoolean)attributeValue; break;
+ case EGL_BIND_TO_TEXTURE_RGBA: match = config.bindToTextureRGBA == (EGLBoolean)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 == (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;
+ default: UNREACHABLE();
+ }
+
+ if (!match)
+ {
+ break;
+ }
+ }
+
+ if (match)
+ {
+ result.push_back(&config);
+ }
+ }
+
+ // Sort the result
+ std::sort(result.begin(), result.end(), ConfigSorter(attributeMap));
+
+ return result;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/Config.h b/src/3rdparty/angle/src/libANGLE/Config.h
new file mode 100644
index 0000000000..aed8aedb1d
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Config.h
@@ -0,0 +1,91 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// 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();
+
+ 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 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
+};
+
+class ConfigSet
+{
+ public:
+ 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;
+
+ private:
+ typedef std::map<EGLint, const Config> ConfigMap;
+ ConfigMap mConfigs;
+};
+
+}
+
+#endif // INCLUDE_CONFIG_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/constants.h b/src/3rdparty/angle/src/libANGLE/Constants.h
index 69c4823fb2..dc8f9555b8 100644
--- a/src/3rdparty/angle/src/libGLESv2/constants.h
+++ b/src/3rdparty/angle/src/libANGLE/Constants.h
@@ -6,8 +6,8 @@
// Contants.h: Defines some implementation specific and gl constants
-#ifndef LIBGLESV2_CONSTANTS_H_
-#define LIBGLESV2_CONSTANTS_H_
+#ifndef LIBANGLE_CONSTANTS_H_
+#define LIBANGLE_CONSTANTS_H_
namespace gl
{
@@ -41,4 +41,4 @@ enum
}
-#endif // LIBGLESV2_CONSTANTS_H_
+#endif // LIBANGLE_CONSTANTS_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libANGLE/Context.cpp
index 3772da6f42..1da5fdae95 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Context.cpp
@@ -7,37 +7,36 @@
// Context.cpp: Implements the gl::Context class, managing all GL state and performing
// rendering operations. It is the GLES2 specific implementation of EGLContext.
-#include "libGLESv2/Context.h"
+#include "libANGLE/Context.h"
-#include "common/utilities.h"
-#include "common/platform.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/Fence.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/Program.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/Query.h"
-#include "libGLESv2/ResourceManager.h"
-#include "libGLESv2/Sampler.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/TransformFeedback.h"
-#include "libGLESv2/VertexArray.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/validationES.h"
-#include "libGLESv2/renderer/Renderer.h"
-
-#include "libEGL/Surface.h"
-
-#include <sstream>
#include <iterator>
+#include <sstream>
+
+#include "common/platform.h"
+#include "common/utilities.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Compiler.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Fence.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Query.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/ResourceManager.h"
+#include "libANGLE/Sampler.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/TransformFeedback.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/validationES.h"
+#include "libANGLE/renderer/Renderer.h"
namespace gl
{
-Context::Context(int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
+Context::Context(const egl::Config *config, int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
: mRenderer(renderer)
{
ASSERT(robustAccess == false); // Unimplemented
@@ -47,6 +46,10 @@ Context::Context(int clientVersion, const Context *shareContext, rx::Renderer *r
mClientVersion = clientVersion;
+ mConfigID = config->configID;
+ mClientType = EGL_OPENGL_ES_API;
+ mRenderBuffer = EGL_NONE;
+
mFenceNVHandleAllocator.setBaseHandle(0);
if (shareContext != NULL)
@@ -65,19 +68,19 @@ Context::Context(int clientVersion, const Context *shareContext, rx::Renderer *r
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
- Texture2D *zeroTexture2D = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0);
+ Texture *zeroTexture2D = new Texture(mRenderer->createTexture(GL_TEXTURE_2D), 0, GL_TEXTURE_2D);
mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
- TextureCubeMap *zeroTextureCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0);
+ Texture *zeroTextureCube = new Texture(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0, GL_TEXTURE_CUBE_MAP);
mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
if (mClientVersion >= 3)
{
// TODO: These could also be enabled via extension
- Texture3D *zeroTexture3D = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0);
+ Texture *zeroTexture3D = new Texture(mRenderer->createTexture(GL_TEXTURE_3D), 0, GL_TEXTURE_3D);
mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
- Texture2DArray *zeroTexture2DArray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0);
+ Texture *zeroTexture2DArray = new Texture(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0, GL_TEXTURE_2D_ARRAY);
mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
}
@@ -120,25 +123,18 @@ Context::Context(int clientVersion, const Context *shareContext, rx::Renderer *r
mResetStatus = GL_NO_ERROR;
mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
mRobustAccess = robustAccess;
+
+ mCompiler = new Compiler(mRenderer->createCompiler(getData()));
}
Context::~Context()
{
- GLuint currentProgram = mState.getCurrentProgramId();
- if (currentProgram != 0)
- {
- Program *programObject = mResourceManager->getProgram(currentProgram);
- if (programObject)
- {
- programObject->release();
- }
- currentProgram = 0;
- }
- mState.setCurrentProgram(0, NULL);
+ mState.reset();
while (!mFramebufferMap.empty())
{
- deleteFramebuffer(mFramebufferMap.begin()->first);
+ // Delete the framebuffer in reverse order to destroy the framebuffer zero last.
+ deleteFramebuffer(mFramebufferMap.rbegin()->first);
}
while (!mFenceNVMap.empty())
@@ -162,9 +158,9 @@ Context::~Context()
deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
}
- for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
+ for (auto it = mZeroTextures.begin(); it != mZeroTextures.end(); ++it)
{
- i->second.set(NULL);
+ it->second.set(NULL);
}
mZeroTextures.clear();
@@ -172,6 +168,8 @@ Context::~Context()
{
mResourceManager->release();
}
+
+ SafeDelete(mCompiler);
}
void Context::makeCurrent(egl::Surface *surface)
@@ -187,14 +185,12 @@ void Context::makeCurrent(egl::Surface *surface)
mHasBeenCurrent = true;
}
- // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
- rx::SwapChain *swapchain = surface->getSwapChain();
-
- rx::RenderbufferImpl *colorbufferZero = mRenderer->createRenderbuffer(swapchain, false);
- rx::RenderbufferImpl *depthStencilbufferZero = mRenderer->createRenderbuffer(swapchain, true);
- Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
+ // TODO(jmadill): do not allocate new pointers here
+ Framebuffer *framebufferZero = new DefaultFramebuffer(mCaps, mRenderer, surface);
setFramebufferZero(framebufferZero);
+
+ mRenderBuffer = surface->getRenderBuffer();
}
// NOTE: this function should not assume that this context is current!
@@ -239,7 +235,7 @@ GLsync Context::createFenceSync()
{
GLuint handle = mResourceManager->createFenceSync();
- return reinterpret_cast<GLsync>(handle);
+ return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
}
GLuint Context::createVertexArray()
@@ -348,7 +344,7 @@ void Context::deleteFenceSync(GLsync fenceSync)
void Context::deleteVertexArray(GLuint vertexArray)
{
- VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray);
+ auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
if (vertexArrayObject != mVertexArrayMap.end())
{
@@ -372,7 +368,7 @@ void Context::deleteSampler(GLuint sampler)
void Context::deleteTransformFeedback(GLuint transformFeedback)
{
- TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(transformFeedback);
+ auto iter = mTransformFeedbackMap.find(transformFeedback);
if (iter != mTransformFeedbackMap.end())
{
detachTransformFeedback(transformFeedback);
@@ -454,7 +450,7 @@ FenceSync *Context::getFenceSync(GLsync handle) const
VertexArray *Context::getVertexArray(GLuint handle) const
{
- VertexArrayMap::const_iterator vertexArray = mVertexArrayMap.find(handle);
+ auto vertexArray = mVertexArrayMap.find(handle);
if (vertexArray == mVertexArrayMap.end())
{
@@ -526,7 +522,7 @@ void Context::bindReadFramebuffer(GLuint framebuffer)
{
if (!getFramebuffer(framebuffer))
{
- mFramebufferMap[framebuffer] = new Framebuffer(framebuffer);
+ mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer);
}
mState.setReadFramebufferBinding(getFramebuffer(framebuffer));
@@ -536,7 +532,7 @@ void Context::bindDrawFramebuffer(GLuint framebuffer)
{
if (!getFramebuffer(framebuffer))
{
- mFramebufferMap[framebuffer] = new Framebuffer(framebuffer);
+ mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer);
}
mState.setDrawFramebufferBinding(getFramebuffer(framebuffer));
@@ -626,58 +622,7 @@ void Context::bindPixelUnpackBuffer(GLuint buffer)
void Context::useProgram(GLuint program)
{
- GLuint priorProgramId = mState.getCurrentProgramId();
- Program *priorProgram = mResourceManager->getProgram(priorProgramId);
-
- if (priorProgramId != program)
- {
- mState.setCurrentProgram(program, mResourceManager->getProgram(program));
-
- if (priorProgram)
- {
- priorProgram->release();
- }
- }
-}
-
-Error Context::linkProgram(GLuint program)
-{
- Program *programObject = mResourceManager->getProgram(program);
-
- Error error = programObject->link(getData());
- if (error.isError())
- {
- return error;
- }
-
- // if the current program was relinked successfully we
- // need to install the new executables
- if (programObject->isLinked() && program == mState.getCurrentProgramId())
- {
- mState.setCurrentProgramBinary(programObject->getProgramBinary());
- }
-
- return Error(GL_NO_ERROR);
-}
-
-Error Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
-{
- Program *programObject = mResourceManager->getProgram(program);
-
- Error error = programObject->setProgramBinary(binaryFormat, binary, length);
- if (error.isError())
- {
- return error;
- }
-
- // if the current program was reloaded successfully we
- // need to install the new executables
- if (programObject->isLinked() && program == mState.getCurrentProgramId())
- {
- mState.setCurrentProgramBinary(programObject->getProgramBinary());
- }
-
- return Error(GL_NO_ERROR);
+ mState.setProgram(getProgram(program));
}
void Context::bindTransformFeedback(GLuint transformFeedback)
@@ -784,44 +729,19 @@ Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
Texture *Context::getTargetTexture(GLenum target) const
{
- if (!ValidTextureTarget(this, target))
- {
- return NULL;
- }
-
- switch (target)
- {
- case GL_TEXTURE_2D: return getTexture2D();
- case GL_TEXTURE_CUBE_MAP: return getTextureCubeMap();
- case GL_TEXTURE_3D: return getTexture3D();
- case GL_TEXTURE_2D_ARRAY: return getTexture2DArray();
- default: return NULL;
- }
-}
-
-Texture2D *Context::getTexture2D() const
-{
- return static_cast<Texture2D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D));
-}
+ ASSERT(ValidTextureTarget(this, target));
-TextureCubeMap *Context::getTextureCubeMap() const
-{
- return static_cast<TextureCubeMap*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_CUBE_MAP));
+ return getSamplerTexture(mState.getActiveSampler(), target);
}
-Texture3D *Context::getTexture3D() const
+Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
{
- return static_cast<Texture3D*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_3D));
+ return mState.getSamplerTexture(sampler, type);
}
-Texture2DArray *Context::getTexture2DArray() const
+Compiler *Context::getCompiler() const
{
- return static_cast<Texture2DArray*>(getSamplerTexture(mState.getActiveSampler(), GL_TEXTURE_2D_ARRAY));
-}
-
-Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
-{
- return mState.getSamplerTexture(sampler, type);
+ return mCompiler;
}
void Context::getBooleanv(GLenum pname, GLboolean *params)
@@ -900,17 +820,6 @@ void Context::getIntegerv(GLenum pname, GLint *params)
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break;
case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = mCaps.compressedTextureFormats.size(); break;
case GL_MAX_SAMPLES_ANGLE: *params = mExtensions.maxSamples; break;
- case GL_IMPLEMENTATION_COLOR_READ_TYPE:
- case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
- {
- GLenum internalFormat, format, type;
- getCurrentReadFormatType(&internalFormat, &format, &type);
- if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
- *params = format;
- else
- *params = type;
- }
- break;
case GL_MAX_VIEWPORT_DIMS:
{
params[0] = mCaps.maxViewportWidth;
@@ -1025,6 +934,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
*numParams = mCaps.shaderBinaryFormats.size();
}
return true;
+
case GL_MAX_VERTEX_ATTRIBS:
case GL_MAX_VERTEX_UNIFORM_VECTORS:
case GL_MAX_VARYING_VECTORS:
@@ -1286,62 +1196,6 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned
return false;
}
-Error Context::clear(GLbitfield mask)
-{
- if (mState.isRasterizerDiscardEnabled())
- {
- return Error(GL_NO_ERROR);
- }
-
- return mRenderer->clear(getData(), mask);
-}
-
-Error Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
-{
- if (mState.isRasterizerDiscardEnabled())
- {
- return Error(GL_NO_ERROR);
- }
-
- return mRenderer->clearBufferfv(getData(), buffer, drawbuffer, values);
-}
-
-Error Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
-{
- if (mState.isRasterizerDiscardEnabled())
- {
- return Error(GL_NO_ERROR);
- }
-
- return mRenderer->clearBufferuiv(getData(), buffer, drawbuffer, values);
-}
-
-Error Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
-{
- if (mState.isRasterizerDiscardEnabled())
- {
- return Error(GL_NO_ERROR);
- }
-
- return mRenderer->clearBufferiv(getData(), buffer, drawbuffer, values);
-}
-
-Error Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
-{
- if (mState.isRasterizerDiscardEnabled())
- {
- return Error(GL_NO_ERROR);
- }
-
- return mRenderer->clearBufferfi(getData(), buffer, drawbuffer, depth, stencil);
-}
-
-Error Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
-{
- return mRenderer->readPixels(getData(), x, y, width, height, format, type, bufSize, pixels);
-}
-
Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
return mRenderer->drawArrays(getData(), mode, first, count, instances);
@@ -1354,10 +1208,14 @@ Error Context::drawElements(GLenum mode, GLsizei count, GLenum type,
return mRenderer->drawElements(getData(), mode, count, type, indices, instances, indexRange);
}
-// Implements glFlush when block is false, glFinish when block is true
-Error Context::sync(bool block)
+Error Context::flush()
{
- return mRenderer->sync(block);
+ return mRenderer->flush();
+}
+
+Error Context::finish()
+{
+ return mRenderer->finish();
}
void Context::recordError(const Error &error)
@@ -1391,7 +1249,10 @@ GLenum Context::getResetStatus()
{
// mResetStatus will be set by the markContextLost callback
// in the case a notification is sent
- mRenderer->testDeviceLost(true);
+ if (mRenderer->testDeviceLost())
+ {
+ mRenderer->notifyDeviceLost();
+ }
}
GLenum status = mResetStatus;
@@ -1419,6 +1280,21 @@ int Context::getClientVersion() const
return mClientVersion;
}
+EGLint Context::getConfigID() const
+{
+ return mConfigID;
+}
+
+EGLenum Context::getClientType() const
+{
+ return mClientType;
+}
+
+EGLenum Context::getRenderBuffer() const
+{
+ return mRenderBuffer;
+}
+
const Caps &Context::getCaps() const
{
return mCaps;
@@ -1434,22 +1310,6 @@ const Extensions &Context::getExtensions() const
return mExtensions;
}
-void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
-{
- Framebuffer *framebuffer = mState.getReadFramebuffer();
- ASSERT(framebuffer && framebuffer->completeness(getData()) == GL_FRAMEBUFFER_COMPLETE);
-
- FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
- ASSERT(attachment);
-
- GLenum actualFormat = attachment->getActualFormat();
- const InternalFormat &actualFormatInfo = GetInternalFormatInfo(actualFormat);
-
- *internalFormat = actualFormat;
- *format = actualFormatInfo.format;
- *type = actualFormatInfo.type;
-}
-
void Context::detachTexture(GLuint texture)
{
// Simple pass-through to State's detachTexture method, as textures do not require
@@ -1487,12 +1347,12 @@ void Context::detachFramebuffer(GLuint framebuffer)
// 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))
+ if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0)
{
bindReadFramebuffer(0);
}
- if (mState.removeDrawFramebufferBinding(framebuffer))
+ if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0)
{
bindDrawFramebuffer(0);
}
@@ -1660,19 +1520,6 @@ size_t Context::getExtensionStringCount() const
return mExtensionStrings.size();
}
-Error Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- return mRenderer->blitFramebuffer(getData(), srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1, mask, filter);
-}
-
-void Context::releaseShaderCompiler()
-{
- mRenderer->releaseShaderCompiler();
-}
-
void Context::initCaps(GLuint clientVersion)
{
mCaps = mRenderer->getRendererCaps();
@@ -1738,32 +1585,3 @@ Data Context::getData() const
}
}
-
-extern "C"
-{
-gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
-{
- return new gl::Context(clientVersion, shareContext, renderer, notifyResets, robustAccess);
-}
-
-void glDestroyContext(gl::Context *context)
-{
- delete context;
-
- if (context == gl::getContext())
- {
- gl::makeCurrent(NULL, NULL, NULL);
- }
-}
-
-void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
-{
- gl::makeCurrent(context, display, surface);
-}
-
-gl::Context *glGetCurrentContext()
-{
- return gl::getContext();
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.h b/src/3rdparty/angle/src/libANGLE/Context.h
index 0699592d91..eeada43355 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.h
+++ b/src/3rdparty/angle/src/libANGLE/Context.h
@@ -7,26 +7,24 @@
// Context.h: Defines the gl::Context class, managing all GL state and performing
// rendering operations. It is the GLES2 specific implementation of EGLContext.
-#ifndef LIBGLESV2_CONTEXT_H_
-#define LIBGLESV2_CONTEXT_H_
+#ifndef LIBANGLE_CONTEXT_H_
+#define LIBANGLE_CONTEXT_H_
#include "common/angleutils.h"
-#include "common/RefCountObject.h"
-#include "libGLESv2/Caps.h"
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/Data.h"
-#include "libGLESv2/Error.h"
-#include "libGLESv2/HandleAllocator.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/angletypes.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Data.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/HandleAllocator.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/angletypes.h"
#include "angle_gl.h"
#include <string>
#include <set>
#include <map>
-#include <unordered_map>
-#include <array>
namespace rx
{
@@ -36,18 +34,15 @@ class Renderer;
namespace egl
{
class Surface;
+struct Config;
}
namespace gl
{
+class Compiler;
class Shader;
class Program;
-class ProgramBinary;
class Texture;
-class Texture2D;
-class TextureCubeMap;
-class Texture3D;
-class Texture2DArray;
class Framebuffer;
class Renderbuffer;
class FenceNV;
@@ -60,10 +55,10 @@ class VertexArray;
class Sampler;
class TransformFeedback;
-class Context
+class Context final : angle::NonCopyable
{
public:
- Context(int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
+ Context(const egl::Config *config, int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
virtual ~Context();
@@ -125,8 +120,6 @@ class Context
void bindPixelPackBuffer(GLuint buffer);
void bindPixelUnpackBuffer(GLuint buffer);
void useProgram(GLuint program);
- Error linkProgram(GLuint program);
- Error setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
void bindTransformFeedback(GLuint transformFeedback);
Error beginQuery(GLenum target, GLuint query);
@@ -155,13 +148,10 @@ class Context
TransformFeedback *getTransformFeedback(GLuint handle) const;
Texture *getTargetTexture(GLenum target) const;
- Texture2D *getTexture2D() const;
- TextureCubeMap *getTextureCubeMap() const;
- Texture3D *getTexture3D() const;
- Texture2DArray *getTexture2DArray() const;
-
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
+ Compiler *getCompiler() const;
+
bool isSampler(GLuint samplerName) const;
void getBooleanv(GLenum pname, GLboolean *params);
@@ -175,18 +165,12 @@ class Context
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
- Error clear(GLbitfield mask);
- Error clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values);
- Error clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values);
- Error clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values);
- Error clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
-
- Error readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);
Error drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances);
Error drawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei instances,
const rx::RangeUI &indexRange);
- Error sync(bool block); // flush/finish
+ Error flush();
+ Error finish();
void recordError(const Error &error);
@@ -196,6 +180,10 @@ class Context
virtual int getClientVersion() const;
+ EGLint getConfigID() const;
+ EGLenum getClientType() const;
+ EGLenum getRenderBuffer() const;
+
const Caps &getCaps() const;
const TextureCapsMap &getTextureCaps() const;
const Extensions &getExtensions() const;
@@ -206,11 +194,6 @@ class Context
const std::string &getExtensionString(size_t idx) const;
size_t getExtensionStringCount() const;
- void getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type);
-
- Error blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter);
-
rx::Renderer *getRenderer() { return mRenderer; }
State &getState() { return mState; }
@@ -218,11 +201,7 @@ class Context
Data getData() const;
- void releaseShaderCompiler();
-
private:
- DISALLOW_COPY_AND_ASSIGN(Context);
-
void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer);
@@ -241,31 +220,38 @@ class Context
TextureCapsMap mTextureCaps;
Extensions mExtensions;
+ // Shader compiler
+ Compiler *mCompiler;
+
rx::Renderer *const mRenderer;
State mState;
int mClientVersion;
+ EGLint mConfigID;
+ EGLenum mClientType;
+ EGLenum mRenderBuffer;
+
TextureMap mZeroTextures;
- typedef std::unordered_map<GLuint, Framebuffer*> FramebufferMap;
+ typedef std::map<GLuint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap;
HandleAllocator mFramebufferHandleAllocator;
- typedef std::unordered_map<GLuint, FenceNV*> FenceNVMap;
+ typedef std::map<GLuint, FenceNV*> FenceNVMap;
FenceNVMap mFenceNVMap;
HandleAllocator mFenceNVHandleAllocator;
- typedef std::unordered_map<GLuint, Query*> QueryMap;
+ typedef std::map<GLuint, Query*> QueryMap;
QueryMap mQueryMap;
HandleAllocator mQueryHandleAllocator;
- typedef std::unordered_map<GLuint, VertexArray*> VertexArrayMap;
+ typedef std::map<GLuint, VertexArray*> VertexArrayMap;
VertexArrayMap mVertexArrayMap;
HandleAllocator mVertexArrayHandleAllocator;
BindingPointer<TransformFeedback> mTransformFeedbackZero;
- typedef std::unordered_map<GLuint, TransformFeedback*> TransformFeedbackMap;
+ typedef std::map<GLuint, TransformFeedback*> TransformFeedbackMap;
TransformFeedbackMap mTransformFeedbackMap;
HandleAllocator mTransformFeedbackAllocator;
@@ -288,4 +274,4 @@ class Context
};
}
-#endif // INCLUDE_CONTEXT_H_
+#endif // LIBANGLE_CONTEXT_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Data.cpp b/src/3rdparty/angle/src/libANGLE/Data.cpp
index 3ddf591d77..7832e21b23 100644
--- a/src/3rdparty/angle/src/libGLESv2/Data.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Data.cpp
@@ -6,8 +6,8 @@
// Data.cpp: Container class for all GL relevant state, caps and objects
-#include "libGLESv2/Data.h"
-#include "libGLESv2/ResourceManager.h"
+#include "libANGLE/Data.h"
+#include "libANGLE/ResourceManager.h"
namespace gl
{
diff --git a/src/3rdparty/angle/src/libGLESv2/Data.h b/src/3rdparty/angle/src/libANGLE/Data.h
index 9234403e13..7eb6827dfc 100644
--- a/src/3rdparty/angle/src/libGLESv2/Data.h
+++ b/src/3rdparty/angle/src/libANGLE/Data.h
@@ -6,15 +6,15 @@
// Data.h: Container class for all GL relevant state, caps and objects
-#ifndef LIBGLESV2_DATA_H_
-#define LIBGLESV2_DATA_H_
+#ifndef LIBANGLE_DATA_H_
+#define LIBANGLE_DATA_H_
-#include "libGLESv2/State.h"
+#include "libANGLE/State.h"
namespace gl
{
-struct Data
+struct Data final
{
public:
Data(GLint clientVersion, const State &state, const Caps &caps,
@@ -35,4 +35,4 @@ struct Data
}
-#endif // LIBGLESV2_DATA_H_
+#endif // LIBANGLE_DATA_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Display.cpp b/src/3rdparty/angle/src/libANGLE/Display.cpp
new file mode 100644
index 0000000000..1f54f82dea
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Display.cpp
@@ -0,0 +1,675 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// 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 <map>
+#include <sstream>
+#include <vector>
+
+#include <platform/Platform.h>
+#include <EGL/eglext.h>
+
+#include "common/debug.h"
+#include "common/mathutil.h"
+#include "common/platform.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/DisplayImpl.h"
+
+#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
+# include "libANGLE/renderer/d3d/DisplayD3D.h"
+#endif
+
+#if defined(ANGLE_ENABLE_OPENGL)
+# if defined(ANGLE_PLATFORM_WINDOWS)
+# include "libANGLE/renderer/gl/wgl/DisplayWGL.h"
+# else
+# error Unsupported OpenGL platform.
+# endif
+#endif
+
+namespace egl
+{
+
+namespace
+{
+
+class DefaultPlatform : public angle::Platform
+{
+public:
+ DefaultPlatform() {}
+ ~DefaultPlatform() override {}
+};
+
+DefaultPlatform *defaultPlatform = nullptr;
+
+void InitDefaultPlatformImpl()
+{
+ if (ANGLEPlatformCurrent() == nullptr)
+ {
+ if (defaultPlatform == nullptr)
+ {
+ defaultPlatform = new DefaultPlatform();
+ }
+
+ ANGLEPlatformInitialize(defaultPlatform);
+ }
+}
+
+void DeinitDefaultPlatformImpl()
+{
+ if (defaultPlatform != nullptr)
+ {
+ if (ANGLEPlatformCurrent() == defaultPlatform)
+ {
+ ANGLEPlatformShutdown();
+ }
+
+ SafeDelete(defaultPlatform);
+ }
+}
+
+typedef std::map<EGLNativeWindowType, Surface*> 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 WindowSurfaceMap windowSurfaces;
+ return &windowSurfaces;
+}
+
+typedef std::map<EGLNativeDisplayType, Display*> DisplayMap;
+static DisplayMap *GetDisplayMap()
+{
+ static DisplayMap displays;
+ return &displays;
+}
+
+rx::DisplayImpl *CreateDisplayImpl(const AttributeMap &attribMap)
+{
+ rx::DisplayImpl *impl = nullptr;
+ EGLint displayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
+ switch (displayType)
+ {
+ case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
+#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
+ // Default to D3D displays
+ impl = new rx::DisplayD3D();
+#else
+ // No display available
+ UNREACHABLE();
+#endif
+ 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();
+#else
+ // A D3D display was requested on a platform that doesn't support it
+ UNREACHABLE();
+#endif
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
+#if defined(ANGLE_ENABLE_OPENGL)
+#if defined(ANGLE_PLATFORM_WINDOWS)
+ impl = new rx::DisplayWGL();
+#else
+#error Unsupported OpenGL platform.
+#endif
+#else
+ UNREACHABLE();
+#endif
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ ASSERT(impl != nullptr);
+ return impl;
+}
+
+}
+
+Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap)
+{
+ // Initialize the global platform if not already
+ InitDefaultPlatformImpl();
+
+ Display *display = NULL;
+
+ DisplayMap *displays = GetDisplayMap();
+ DisplayMap::const_iterator iter = displays->find(displayId);
+ if (iter != displays->end())
+ {
+ display = iter->second;
+ }
+
+ if (display == nullptr)
+ {
+ // Validate the native display
+ if (!Display::isValidNativeDisplay(displayId))
+ {
+ return NULL;
+ }
+
+ display = new Display(displayId);
+ displays->insert(std::make_pair(displayId, display));
+ }
+
+ // Apply new attributes if the display is not initialized yet.
+ if (!display->isInitialized())
+ {
+ rx::DisplayImpl* impl = CreateDisplayImpl(attribMap);
+ display->setAttributes(impl, attribMap);
+ }
+
+ return display;
+}
+
+Display::Display(EGLNativeDisplayType displayId)
+ : mImplementation(nullptr),
+ mDisplayId(displayId),
+ mAttributeMap(),
+ mConfigSet(),
+ mContextSet(),
+ mInitialized(false),
+ mCaps(),
+ mDisplayExtensions(),
+ mDisplayExtensionString(),
+ mVendorString()
+{
+}
+
+Display::~Display()
+{
+ terminate();
+
+ DisplayMap *displays = GetDisplayMap();
+ DisplayMap::iterator iter = displays->find(mDisplayId);
+ if (iter != displays->end())
+ {
+ displays->erase(iter);
+ }
+
+ SafeDelete(mImplementation);
+}
+
+void Display::setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap)
+{
+ ASSERT(!mInitialized);
+
+ ASSERT(impl != nullptr);
+ SafeDelete(mImplementation);
+ mImplementation = impl;
+
+ mAttributeMap = attribMap;
+}
+
+Error Display::initialize()
+{
+ ASSERT(mImplementation != nullptr);
+
+ if (isInitialized())
+ {
+ return Error(EGL_SUCCESS);
+ }
+
+ Error error = mImplementation->initialize(this);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mCaps = mImplementation->getCaps();
+
+ mConfigSet = mImplementation->generateConfigs();
+ if (mConfigSet.size() == 0)
+ {
+ mImplementation->terminate();
+ return Error(EGL_NOT_INITIALIZED);
+ }
+
+ initDisplayExtensions();
+ initVendorString();
+
+ mInitialized = true;
+ return Error(EGL_SUCCESS);
+}
+
+void Display::terminate()
+{
+ makeCurrent(nullptr, nullptr, nullptr);
+
+ while (!mContextSet.empty())
+ {
+ destroyContext(*mContextSet.begin());
+ }
+
+ mConfigSet.clear();
+
+ mImplementation->terminate();
+ mInitialized = false;
+
+ // De-init default platform
+ DeinitDefaultPlatformImpl();
+}
+
+std::vector<const Config*> Display::getConfigs(const egl::AttributeMap &attribs) const
+{
+ return mConfigSet.filter(attribs);
+}
+
+bool Display::getConfigAttrib(const Config *configuration, EGLint attribute, EGLint *value)
+{
+ switch (attribute)
+ {
+ case EGL_BUFFER_SIZE: *value = configuration->bufferSize; break;
+ case EGL_ALPHA_SIZE: *value = configuration->alphaSize; break;
+ case EGL_BLUE_SIZE: *value = configuration->blueSize; break;
+ case EGL_GREEN_SIZE: *value = configuration->greenSize; break;
+ case EGL_RED_SIZE: *value = configuration->redSize; break;
+ case EGL_DEPTH_SIZE: *value = configuration->depthSize; break;
+ case EGL_STENCIL_SIZE: *value = configuration->stencilSize; break;
+ case EGL_CONFIG_CAVEAT: *value = configuration->configCaveat; break;
+ case EGL_CONFIG_ID: *value = configuration->configID; break;
+ case EGL_LEVEL: *value = configuration->level; break;
+ case EGL_NATIVE_RENDERABLE: *value = configuration->nativeRenderable; break;
+ case EGL_NATIVE_VISUAL_TYPE: *value = configuration->nativeVisualType; break;
+ case EGL_SAMPLES: *value = configuration->samples; break;
+ case EGL_SAMPLE_BUFFERS: *value = configuration->sampleBuffers; break;
+ case EGL_SURFACE_TYPE: *value = configuration->surfaceType; break;
+ case EGL_TRANSPARENT_TYPE: *value = configuration->transparentType; break;
+ case EGL_TRANSPARENT_BLUE_VALUE: *value = configuration->transparentBlueValue; break;
+ case EGL_TRANSPARENT_GREEN_VALUE: *value = configuration->transparentGreenValue; break;
+ case EGL_TRANSPARENT_RED_VALUE: *value = configuration->transparentRedValue; break;
+ case EGL_BIND_TO_TEXTURE_RGB: *value = configuration->bindToTextureRGB; break;
+ case EGL_BIND_TO_TEXTURE_RGBA: *value = configuration->bindToTextureRGBA; break;
+ case EGL_MIN_SWAP_INTERVAL: *value = configuration->minSwapInterval; break;
+ case EGL_MAX_SWAP_INTERVAL: *value = configuration->maxSwapInterval; break;
+ case EGL_LUMINANCE_SIZE: *value = configuration->luminanceSize; break;
+ case EGL_ALPHA_MASK_SIZE: *value = configuration->alphaMaskSize; break;
+ case EGL_COLOR_BUFFER_TYPE: *value = configuration->colorBufferType; break;
+ case EGL_RENDERABLE_TYPE: *value = configuration->renderableType; break;
+ case EGL_MATCH_NATIVE_PIXMAP: *value = false; UNIMPLEMENTED(); break;
+ case EGL_CONFORMANT: *value = configuration->conformant; break;
+ case EGL_MAX_PBUFFER_WIDTH: *value = configuration->maxPBufferWidth; break;
+ case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->maxPBufferHeight; break;
+ case EGL_MAX_PBUFFER_PIXELS: *value = configuration->maxPBufferPixels; break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+Error Display::createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs,
+ Surface **outSurface)
+{
+ if (mImplementation->testDeviceLost())
+ {
+ Error error = restoreLostDevice();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ rx::SurfaceImpl *surfaceImpl = nullptr;
+ Error error = mImplementation->createWindowSurface(configuration, window, attribs, &surfaceImpl);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(surfaceImpl != nullptr);
+ Surface *surface = new Surface(surfaceImpl, EGL_WINDOW_BIT, configuration, attribs);
+ mImplementation->getSurfaceSet().insert(surface);
+
+ WindowSurfaceMap *windowSurfaces = GetWindowSurfaces();
+ ASSERT(windowSurfaces && windowSurfaces->find(window) == windowSurfaces->end());
+ windowSurfaces->insert(std::make_pair(window, surface));
+
+ ASSERT(outSurface != nullptr);
+ *outSurface = surface;
+ return Error(EGL_SUCCESS);
+}
+
+Error Display::createPbufferSurface(const Config *configuration, const AttributeMap &attribs, Surface **outSurface)
+{
+ ASSERT(isInitialized());
+
+ if (mImplementation->testDeviceLost())
+ {
+ Error error = restoreLostDevice();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ rx::SurfaceImpl *surfaceImpl = nullptr;
+ Error error = mImplementation->createPbufferSurface(configuration, attribs, &surfaceImpl);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(surfaceImpl != nullptr);
+ Surface *surface = new Surface(surfaceImpl, EGL_PBUFFER_BIT, configuration, attribs);
+ mImplementation->getSurfaceSet().insert(surface);
+
+ ASSERT(outSurface != nullptr);
+ *outSurface = surface;
+ return Error(EGL_SUCCESS);
+}
+
+Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLClientBuffer shareHandle,
+ const AttributeMap &attribs, Surface **outSurface)
+{
+ ASSERT(isInitialized());
+
+ if (mImplementation->testDeviceLost())
+ {
+ Error error = restoreLostDevice();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ rx::SurfaceImpl *surfaceImpl = nullptr;
+ Error error = mImplementation->createPbufferFromClientBuffer(configuration, shareHandle, attribs, &surfaceImpl);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(surfaceImpl != nullptr);
+ Surface *surface = new Surface(surfaceImpl, EGL_PBUFFER_BIT, configuration, attribs);
+ mImplementation->getSurfaceSet().insert(surface);
+
+ ASSERT(outSurface != nullptr);
+ *outSurface = surface;
+ return Error(EGL_SUCCESS);
+}
+
+Error Display::createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs,
+ Surface **outSurface)
+{
+ ASSERT(isInitialized());
+
+ if (mImplementation->testDeviceLost())
+ {
+ Error error = restoreLostDevice();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ rx::SurfaceImpl *surfaceImpl = nullptr;
+ Error error = mImplementation->createPixmapSurface(configuration, nativePixmap, attribs, &surfaceImpl);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(surfaceImpl != nullptr);
+ Surface *surface = new Surface(surfaceImpl, EGL_PIXMAP_BIT, configuration, attribs);
+ mImplementation->getSurfaceSet().insert(surface);
+
+ ASSERT(outSurface != nullptr);
+ *outSurface = surface;
+ return Error(EGL_SUCCESS);
+}
+
+Error Display::createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs,
+ gl::Context **outContext)
+{
+ ASSERT(isInitialized());
+
+ if (mImplementation->testDeviceLost())
+ {
+ Error error = restoreLostDevice();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ gl::Context *context = nullptr;
+ Error error = mImplementation->createContext(configuration, shareContext, attribs, &context);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(context != nullptr);
+ mContextSet.insert(context);
+
+ ASSERT(outContext != nullptr);
+ *outContext = context;
+ return Error(EGL_SUCCESS);
+}
+
+Error Display::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context)
+{
+ Error error = mImplementation->makeCurrent(drawSurface, readSurface, context);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (context && drawSurface)
+ {
+ context->makeCurrent(drawSurface);
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+Error Display::restoreLostDevice()
+{
+ for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++)
+ {
+ if ((*ctx)->isResetNotificationEnabled())
+ {
+ // If reset notifications have been requested, application must delete all contexts first
+ return Error(EGL_CONTEXT_LOST);
+ }
+ }
+
+ return mImplementation->restoreLostDevice();
+}
+
+void Display::destroySurface(Surface *surface)
+{
+ 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);
+ }
+
+ mImplementation->destroySurface(surface);
+}
+
+void Display::destroyContext(gl::Context *context)
+{
+ mContextSet.erase(context);
+ SafeDelete(context);
+}
+
+bool Display::isDeviceLost() const
+{
+ ASSERT(isInitialized());
+ return mImplementation->isDeviceLost();
+}
+
+bool Display::testDeviceLost()
+{
+ ASSERT(isInitialized());
+ return mImplementation->testDeviceLost();
+}
+
+void Display::notifyDeviceLost()
+{
+ for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++)
+ {
+ (*context)->markContextLost();
+ }
+}
+
+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(gl::Context *context) const
+{
+ return mContextSet.find(context) != mContextSet.end();
+}
+
+bool Display::isValidSurface(Surface *surface) const
+{
+ return mImplementation->getSurfaceSet().find(surface) != mImplementation->getSurfaceSet().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;
+#endif
+
+#if defined(ANGLE_ENABLE_OPENGL)
+ extensions.platformANGLEOpenGL = true;
+#endif
+
+ 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();
+}
+
+const ClientExtensions &Display::getClientExtensions()
+{
+ static const ClientExtensions clientExtensions = GenerateClientExtensions();
+ return clientExtensions;
+}
+
+const std::string &Display::getClientExtensionString()
+{
+ static const std::string clientExtensionsString = GenerateExtensionsString(getClientExtensions());
+ return clientExtensionsString;
+}
+
+void Display::initDisplayExtensions()
+{
+ mDisplayExtensions = mImplementation->getExtensions();
+ mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions);
+}
+
+bool Display::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ return mImplementation->isValidNativeWindow(window);
+}
+
+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_STORE)
+ if (display == EGL_SOFTWARE_DISPLAY_ANGLE ||
+ display == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
+ display == EGL_D3D11_ONLY_DISPLAY_ANGLE)
+ {
+ return true;
+ }
+ return (WindowFromDC(display) != NULL);
+#else
+ return true;
+#endif
+}
+
+void Display::initVendorString()
+{
+ mVendorString = mImplementation->getVendorString();
+}
+
+const DisplayExtensions &Display::getExtensions() const
+{
+ return mDisplayExtensions;
+}
+
+const std::string &Display::getExtensionString() const
+{
+ return mDisplayExtensionString;
+}
+
+const std::string &Display::getVendorString() const
+{
+ return mVendorString;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/Display.h b/src/3rdparty/angle/src/libANGLE/Display.h
new file mode 100644
index 0000000000..5ab3f9c0e9
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Display.h
@@ -0,0 +1,124 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// 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 <set>
+#include <vector>
+
+#include "libANGLE/Error.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/AttributeMap.h"
+
+namespace gl
+{
+class Context;
+}
+
+namespace rx
+{
+class DisplayImpl;
+}
+
+namespace egl
+{
+class Surface;
+
+class Display final : angle::NonCopyable
+{
+ public:
+ ~Display();
+
+ Error initialize();
+ void terminate();
+
+ static egl::Display *getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap);
+
+ static const ClientExtensions &getClientExtensions();
+ static const std::string &getClientExtensionString();
+
+ std::vector<const Config*> getConfigs(const egl::AttributeMap &attribs) const;
+ bool getConfigAttrib(const Config *configuration, EGLint attribute, EGLint *value);
+
+ 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, EGLClientBuffer shareHandle, const AttributeMap &attribs,
+ Surface **outSurface);
+ Error createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs,
+ Surface **outSurface);
+
+ Error createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs,
+ gl::Context **outContext);
+
+ Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context);
+
+ void destroySurface(egl::Surface *surface);
+ void destroyContext(gl::Context *context);
+
+ bool isInitialized() const;
+ bool isValidConfig(const Config *config) const;
+ bool isValidContext(gl::Context *context) const;
+ bool isValidSurface(egl::Surface *surface) const;
+ bool isValidNativeWindow(EGLNativeWindowType window) const;
+
+ static bool isValidNativeDisplay(EGLNativeDisplayType display);
+ static bool hasExistingWindowSurface(EGLNativeWindowType window);
+
+ bool isDeviceLost() const;
+ bool testDeviceLost();
+ void notifyDeviceLost();
+
+ const Caps &getCaps() const;
+
+ const DisplayExtensions &getExtensions() const;
+ const std::string &getExtensionString() const;
+ const std::string &getVendorString() const;
+
+ const AttributeMap &getAttributeMap() const { return mAttributeMap; }
+ EGLNativeDisplayType getNativeDisplayId() const { return mDisplayId; }
+
+ rx::DisplayImpl *getImplementation() { return mImplementation; }
+
+ private:
+ Display(EGLNativeDisplayType displayId);
+
+ void setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap);
+
+ Error restoreLostDevice();
+
+ void initDisplayExtensions();
+ void initVendorString();
+
+ rx::DisplayImpl *mImplementation;
+
+ EGLNativeDisplayType mDisplayId;
+ AttributeMap mAttributeMap;
+
+ ConfigSet mConfigSet;
+
+ typedef std::set<gl::Context*> ContextSet;
+ ContextSet mContextSet;
+
+ bool mInitialized;
+
+ Caps mCaps;
+
+ DisplayExtensions mDisplayExtensions;
+ std::string mDisplayExtensionString;
+
+ std::string mVendorString;
+};
+
+}
+
+#endif // LIBANGLE_DISPLAY_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Error.cpp b/src/3rdparty/angle/src/libANGLE/Error.cpp
new file mode 100644
index 0000000000..e17f26bec4
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Error.cpp
@@ -0,0 +1,86 @@
+//
+// Copyright (c) 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 <cstdarg>
+
+namespace gl
+{
+
+Error::Error(GLenum errorCode, const char *msg, ...)
+ : mCode(errorCode),
+ mMessage(nullptr)
+{
+ va_list vararg;
+ va_start(vararg, msg);
+ createMessageString();
+ *mMessage = FormatString(msg, vararg);
+ va_end(vararg);
+}
+
+void Error::createMessageString() const
+{
+ if (mMessage == nullptr)
+ {
+ mMessage = new std::string();
+ }
+}
+
+const std::string &Error::getMessage() const
+{
+ createMessageString();
+ return *mMessage;
+}
+
+}
+
+namespace egl
+{
+
+Error::Error(EGLint errorCode, const char *msg, ...)
+ : mCode(errorCode),
+ mID(0),
+ mMessage(nullptr)
+{
+ va_list vararg;
+ va_start(vararg, msg);
+ createMessageString();
+ *mMessage = FormatString(msg, vararg);
+ va_end(vararg);
+}
+
+Error::Error(EGLint errorCode, EGLint id, const char *msg, ...)
+ : mCode(errorCode),
+ mID(id),
+ mMessage(nullptr)
+{
+ va_list vararg;
+ va_start(vararg, msg);
+ createMessageString();
+ *mMessage = FormatString(msg, vararg);
+ va_end(vararg);
+}
+void Error::createMessageString() const
+{
+ if (mMessage == nullptr)
+ {
+ mMessage = new std::string();
+ }
+}
+
+const std::string &Error::getMessage() const
+{
+ createMessageString();
+ return *mMessage;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/Error.h b/src/3rdparty/angle/src/libANGLE/Error.h
new file mode 100644
index 0000000000..896b777567
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Error.h
@@ -0,0 +1,83 @@
+//
+// Copyright (c) 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 "angle_gl.h"
+#include "common/platform.h"
+#include <EGL/egl.h>
+
+#include <string>
+
+namespace gl
+{
+
+class Error final
+{
+ public:
+ explicit inline Error(GLenum errorCode);
+ Error(GLenum errorCode, const char *msg, ...);
+ inline Error(const Error &other);
+ inline Error(Error &&other);
+
+ inline ~Error();
+
+ inline Error &operator=(const Error &other);
+ inline Error &operator=(Error &&other);
+
+ inline GLenum getCode() const;
+ inline bool isError() const;
+
+ const std::string &getMessage() const;
+
+ private:
+ void createMessageString() const;
+
+ GLenum mCode;
+ mutable std::string *mMessage;
+};
+
+}
+
+namespace egl
+{
+
+class Error final
+{
+ public:
+ explicit inline Error(EGLint errorCode);
+ Error(EGLint errorCode, const char *msg, ...);
+ Error(EGLint errorCode, EGLint id, const char *msg, ...);
+ inline Error(const Error &other);
+ inline Error(Error &&other);
+
+ inline ~Error();
+
+ 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;
+
+ private:
+ void createMessageString() const;
+
+ EGLint mCode;
+ EGLint mID;
+ mutable std::string *mMessage;
+};
+
+}
+
+#include "Error.inl"
+
+#endif // LIBANGLE_ERROR_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Error.inl b/src/3rdparty/angle/src/libANGLE/Error.inl
new file mode 100644
index 0000000000..32e8f05828
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Error.inl
@@ -0,0 +1,163 @@
+//
+// Copyright (c) 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.inl: Inline definitions of egl::Error and gl::Error classes which encapsulate API errors
+// and optional error messages.
+
+#include "common/angleutils.h"
+
+#include <cstdarg>
+
+namespace gl
+{
+
+Error::Error(GLenum errorCode)
+ : mCode(errorCode),
+ mMessage(nullptr)
+{
+}
+
+Error::Error(const Error &other)
+ : mCode(other.mCode),
+ mMessage(nullptr)
+{
+ if (other.mMessage != nullptr)
+ {
+ createMessageString();
+ *mMessage = *(other.mMessage);
+ }
+}
+
+Error::Error(Error &&other)
+ : mCode(other.mCode),
+ mMessage(other.mMessage)
+{
+ other.mMessage = nullptr;
+}
+
+Error::~Error()
+{
+ SafeDelete(mMessage);
+}
+
+Error &Error::operator=(const Error &other)
+{
+ mCode = other.mCode;
+
+ if (other.mMessage != nullptr)
+ {
+ createMessageString();
+ *mMessage = *(other.mMessage);
+ }
+ else
+ {
+ SafeDelete(mMessage);
+ }
+
+ return *this;
+}
+
+Error &Error::operator=(Error &&other)
+{
+ mCode = other.mCode;
+ mMessage = other.mMessage;
+
+ other.mMessage = nullptr;
+
+ return *this;
+}
+
+GLenum Error::getCode() const
+{
+ return mCode;
+}
+
+bool Error::isError() const
+{
+ return (mCode != GL_NO_ERROR);
+}
+
+}
+
+namespace egl
+{
+
+Error::Error(EGLint errorCode)
+ : mCode(errorCode),
+ mID(0),
+ mMessage(nullptr)
+{
+}
+
+Error::Error(const Error &other)
+ : mCode(other.mCode),
+ mID(other.mID),
+ mMessage(nullptr)
+{
+ if (other.mMessage != nullptr)
+ {
+ createMessageString();
+ *mMessage = *(other.mMessage);
+ }
+}
+
+Error::Error(Error &&other)
+ : mCode(other.mCode),
+ mID(other.mID),
+ mMessage(other.mMessage)
+{
+ other.mMessage = nullptr;
+}
+
+Error::~Error()
+{
+ SafeDelete(mMessage);
+}
+
+Error &Error::operator=(const Error &other)
+{
+ mCode = other.mCode;
+ mID = other.mID;
+
+ if (other.mMessage != nullptr)
+ {
+ createMessageString();
+ *mMessage = *(other.mMessage);
+ }
+ else
+ {
+ SafeDelete(mMessage);
+ }
+
+ return *this;
+}
+
+Error &Error::operator=(Error &&other)
+{
+ mCode = other.mCode;
+ mID = other.mID;
+ mMessage = other.mMessage;
+
+ other.mMessage = nullptr;
+
+ return *this;
+}
+
+EGLint Error::getCode() const
+{
+ return mCode;
+}
+
+EGLint Error::getID() const
+{
+ return mID;
+}
+
+bool Error::isError() const
+{
+ return (mCode != EGL_SUCCESS);
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.cpp b/src/3rdparty/angle/src/libANGLE/Fence.cpp
index 966a327de5..8ab4cc9daa 100644
--- a/src/3rdparty/angle/src/libGLESv2/Fence.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Fence.cpp
@@ -7,10 +7,11 @@
// Fence.cpp: Implements the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence
// extension and GLES3 sync objects.
-#include "libGLESv2/Fence.h"
-#include "libGLESv2/renderer/FenceImpl.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/Fence.h"
+
+#include "libANGLE/renderer/FenceNVImpl.h"
+#include "libANGLE/renderer/FenceSyncImpl.h"
+#include "libANGLE/renderer/Renderer.h"
#include "common/utilities.h"
#include "angle_gl.h"
diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.h b/src/3rdparty/angle/src/libANGLE/Fence.h
index fd565e96a6..bcd66b6831 100644
--- a/src/3rdparty/angle/src/libGLESv2/Fence.h
+++ b/src/3rdparty/angle/src/libANGLE/Fence.h
@@ -7,13 +7,13 @@
// Fence.h: Defines the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence
// extension and GLES3 sync objects.
-#ifndef LIBGLESV2_FENCE_H_
-#define LIBGLESV2_FENCE_H_
+#ifndef LIBANGLE_FENCE_H_
+#define LIBANGLE_FENCE_H_
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
#include "common/angleutils.h"
-#include "common/RefCountObject.h"
namespace rx
{
@@ -24,7 +24,7 @@ class FenceSyncImpl;
namespace gl
{
-class FenceNV
+class FenceNV final : angle::NonCopyable
{
public:
explicit FenceNV(rx::FenceNVImpl *impl);
@@ -36,11 +36,9 @@ class FenceNV
Error finishFence();
GLboolean getStatus() const { return mStatus; }
- GLuint getCondition() const { return mCondition; }
+ GLenum getCondition() const { return mCondition; }
private:
- DISALLOW_COPY_AND_ASSIGN(FenceNV);
-
rx::FenceNVImpl *mFence;
bool mIsSet;
@@ -49,7 +47,7 @@ class FenceNV
GLenum mCondition;
};
-class FenceSync : public RefCountObject
+class FenceSync final : public RefCountObject
{
public:
explicit FenceSync(rx::FenceSyncImpl *impl, GLuint id);
@@ -60,11 +58,9 @@ class FenceSync : public RefCountObject
Error serverWait(GLbitfield flags, GLuint64 timeout);
Error getStatus(GLint *outResult) const;
- GLuint getCondition() const { return mCondition; }
+ GLenum getCondition() const { return mCondition; }
private:
- DISALLOW_COPY_AND_ASSIGN(FenceSync);
-
rx::FenceSyncImpl *mFence;
GLenum mCondition;
@@ -72,4 +68,4 @@ class FenceSync : public RefCountObject
}
-#endif // LIBGLESV2_FENCE_H_
+#endif // LIBANGLE_FENCE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp b/src/3rdparty/angle/src/libANGLE/Float16ToFloat32.cpp
index 5bf7b3fce8..5bf7b3fce8 100644
--- a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Float16ToFloat32.cpp
diff --git a/src/3rdparty/angle/src/libANGLE/Framebuffer.cpp b/src/3rdparty/angle/src/libANGLE/Framebuffer.cpp
new file mode 100644
index 0000000000..b1dd4a1b0f
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Framebuffer.cpp
@@ -0,0 +1,658 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// 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/utilities.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/FramebufferImpl.h"
+#include "libANGLE/renderer/ImplFactory.h"
+#include "libANGLE/renderer/RenderbufferImpl.h"
+#include "libANGLE/renderer/Workarounds.h"
+
+namespace gl
+{
+
+namespace
+{
+void DeleteMatchingAttachment(FramebufferAttachment *&attachment, GLenum matchType, GLuint matchId)
+{
+ if (attachment && attachment->type() == matchType && attachment->id() == matchId)
+ {
+ SafeDelete(attachment);
+ }
+}
+}
+
+Framebuffer::Data::Data(const Caps &caps)
+ : mColorAttachments(caps.maxColorAttachments, nullptr),
+ mDepthAttachment(nullptr),
+ mStencilAttachment(nullptr),
+ mDrawBufferStates(caps.maxDrawBuffers, GL_NONE),
+ mReadBufferState(GL_COLOR_ATTACHMENT0_EXT)
+{
+ mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
+}
+
+Framebuffer::Data::~Data()
+{
+ for (auto it = mColorAttachments.begin(); it != mColorAttachments.end(); ++it)
+ {
+ SafeDelete(*it);
+ }
+ SafeDelete(mDepthAttachment);
+ SafeDelete(mStencilAttachment);
+}
+
+FramebufferAttachment *Framebuffer::Data::getReadAttachment() const
+{
+ ASSERT(mReadBufferState == GL_BACK || (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15));
+ size_t readIndex = (mReadBufferState == GL_BACK ? 0 : static_cast<size_t>(mReadBufferState - GL_COLOR_ATTACHMENT0));
+ ASSERT(readIndex < mColorAttachments.size());
+ return mColorAttachments[readIndex];
+}
+
+FramebufferAttachment *Framebuffer::Data::getFirstColorAttachment() const
+{
+ for (auto it = mColorAttachments.cbegin(); it != mColorAttachments.cend(); ++it)
+ {
+ if (*it != nullptr)
+ {
+ return *it;
+ }
+ }
+
+ return nullptr;
+}
+
+FramebufferAttachment *Framebuffer::Data::getDepthOrStencilAttachment() const
+{
+ return (mDepthAttachment != nullptr ? mDepthAttachment : mStencilAttachment);
+}
+
+Framebuffer::Framebuffer(const Caps &caps, rx::ImplFactory *factory, GLuint id)
+ : mData(caps),
+ mImpl(nullptr),
+ mId(id)
+{
+ if (mId == 0)
+ {
+ mImpl = factory->createDefaultFramebuffer(mData);
+ }
+ else
+ {
+ mImpl = factory->createFramebuffer(mData);
+ }
+ ASSERT(mImpl != nullptr);
+}
+
+Framebuffer::~Framebuffer()
+{
+ SafeDelete(mImpl);
+}
+
+void Framebuffer::detachTexture(GLuint textureId)
+{
+ detachResourceById(GL_TEXTURE, textureId);
+}
+
+void Framebuffer::detachRenderbuffer(GLuint renderbufferId)
+{
+ detachResourceById(GL_RENDERBUFFER, renderbufferId);
+}
+
+void Framebuffer::detachResourceById(GLenum resourceType, GLuint resourceId)
+{
+ for (auto it = mData.mColorAttachments.begin(); it != mData.mColorAttachments.end(); ++it)
+ {
+ DeleteMatchingAttachment(*it, resourceType, resourceId);
+ }
+
+ DeleteMatchingAttachment(mData.mDepthAttachment, resourceType, resourceId);
+ DeleteMatchingAttachment(mData.mStencilAttachment, resourceType, resourceId);
+}
+
+FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
+{
+ ASSERT(colorAttachment < mData.mColorAttachments.size());
+ return mData.mColorAttachments[colorAttachment];
+}
+
+FramebufferAttachment *Framebuffer::getDepthbuffer() const
+{
+ return mData.mDepthAttachment;
+}
+
+FramebufferAttachment *Framebuffer::getStencilbuffer() const
+{
+ return mData.mStencilAttachment;
+}
+
+FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
+{
+ return (hasValidDepthStencil() ? mData.mDepthAttachment : NULL);
+}
+
+FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
+{
+ return mData.getDepthOrStencilAttachment();
+}
+
+FramebufferAttachment *Framebuffer::getReadColorbuffer() const
+{
+ return mData.getReadAttachment();
+}
+
+GLenum Framebuffer::getReadColorbufferType() const
+{
+ FramebufferAttachment *readAttachment = mData.getReadAttachment();
+ return (readAttachment ? readAttachment->type() : GL_NONE);
+}
+
+FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
+{
+ return mData.getFirstColorAttachment();
+}
+
+FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
+{
+ if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
+ {
+ return getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
+ }
+ else
+ {
+ switch (attachment)
+ {
+ case GL_COLOR:
+ case GL_BACK:
+ return getColorbuffer(0);
+ case GL_DEPTH:
+ case GL_DEPTH_ATTACHMENT:
+ return getDepthbuffer();
+ case GL_STENCIL:
+ case GL_STENCIL_ATTACHMENT:
+ return getStencilbuffer();
+ case GL_DEPTH_STENCIL:
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ return getDepthStencilBuffer();
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+ }
+}
+
+GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
+{
+ ASSERT(colorAttachment < mData.mDrawBufferStates.size());
+ return mData.mDrawBufferStates[colorAttachment];
+}
+
+void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers)
+{
+ auto &drawStates = mData.mDrawBufferStates;
+
+ ASSERT(count <= drawStates.size());
+ std::copy(buffers, buffers + count, drawStates.begin());
+ std::fill(drawStates.begin() + count, drawStates.end(), GL_NONE);
+ mImpl->setDrawBuffers(count, buffers);
+}
+
+GLenum Framebuffer::getReadBufferState() const
+{
+ return mData.mReadBufferState;
+}
+
+void Framebuffer::setReadBuffer(GLenum buffer)
+{
+ ASSERT(buffer == GL_BACK || buffer == GL_NONE ||
+ (buffer >= GL_COLOR_ATTACHMENT0 &&
+ (buffer - GL_COLOR_ATTACHMENT0) < mData.mColorAttachments.size()));
+ mData.mReadBufferState = buffer;
+ mImpl->setReadBuffer(buffer);
+}
+
+bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
+{
+ ASSERT(colorAttachment < mData.mColorAttachments.size());
+ return (mData.mColorAttachments[colorAttachment] &&
+ mData.mDrawBufferStates[colorAttachment] != GL_NONE);
+}
+
+bool Framebuffer::hasEnabledColorAttachment() const
+{
+ for (size_t colorAttachment = 0; colorAttachment < mData.mColorAttachments.size(); ++colorAttachment)
+ {
+ if (isEnabledColorAttachment(colorAttachment))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool Framebuffer::hasStencil() const
+{
+ return (mData.mStencilAttachment && mData.mStencilAttachment->getStencilSize() > 0);
+}
+
+bool Framebuffer::usingExtendedDrawBuffers() const
+{
+ for (size_t colorAttachment = 1; colorAttachment < mData.mColorAttachments.size(); ++colorAttachment)
+ {
+ if (isEnabledColorAttachment(colorAttachment))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+GLenum Framebuffer::checkStatus(const gl::Data &data) const
+{
+ // The default framebuffer *must* always be complete, though it may not be
+ // subject to the same rules as application FBOs. ie, it could have 0x0 size.
+ if (mId == 0)
+ {
+ return GL_FRAMEBUFFER_COMPLETE;
+ }
+
+ int width = 0;
+ int height = 0;
+ unsigned int colorbufferSize = 0;
+ int samples = -1;
+ bool missingAttachment = true;
+
+ for (auto it = mData.mColorAttachments.cbegin(); it != mData.mColorAttachments.cend(); ++it)
+ {
+ const auto &colorAttachment = *it;
+ if (colorAttachment != nullptr)
+ {
+ if (colorAttachment->getWidth() == 0 || colorAttachment->getHeight() == 0)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+
+ GLenum internalformat = colorAttachment->getInternalFormat();
+ const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
+ if (colorAttachment->type() == GL_TEXTURE)
+ {
+ if (!formatCaps.renderable)
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+
+ if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+ }
+ else if (colorAttachment->type() == GL_RENDERBUFFER)
+ {
+ if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+ }
+
+ if (!missingAttachment)
+ {
+ // all color attachments must have the same width and height
+ if (colorAttachment->getWidth() != width || colorAttachment->getHeight() != height)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
+
+ // 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.
+ if (colorAttachment->getSamples() != samples)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
+ }
+
+ // 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 (data.clientVersion < 3)
+ {
+ if (formatInfo.pixelBytes != colorbufferSize)
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+ }
+ }
+ else
+ {
+ width = colorAttachment->getWidth();
+ height = colorAttachment->getHeight();
+ samples = colorAttachment->getSamples();
+ colorbufferSize = formatInfo.pixelBytes;
+ missingAttachment = false;
+ }
+ }
+ }
+
+ const FramebufferAttachment *depthAttachment = mData.mDepthAttachment;
+ if (depthAttachment != nullptr)
+ {
+ if (depthAttachment->getWidth() == 0 || depthAttachment->getHeight() == 0)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+
+ GLenum internalformat = depthAttachment->getInternalFormat();
+ const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
+ if (depthAttachment->type() == GL_TEXTURE)
+ {
+ // depth texture attachments require OES/ANGLE_depth_texture
+ if (!data.extensions->depthTextures)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+
+ if (!formatCaps.renderable)
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+
+ if (formatInfo.depthBits == 0)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+ }
+ else if (depthAttachment->type() == GL_RENDERBUFFER)
+ {
+ if (!formatCaps.renderable || formatInfo.depthBits == 0)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+ }
+
+ if (missingAttachment)
+ {
+ width = depthAttachment->getWidth();
+ height = depthAttachment->getHeight();
+ samples = depthAttachment->getSamples();
+ missingAttachment = false;
+ }
+ else if (width != depthAttachment->getWidth() || height != depthAttachment->getHeight())
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
+ else if (samples != depthAttachment->getSamples())
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
+ }
+ }
+
+ const FramebufferAttachment *stencilAttachment = mData.mStencilAttachment;
+ if (stencilAttachment)
+ {
+ if (stencilAttachment->getWidth() == 0 || stencilAttachment->getHeight() == 0)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+
+ GLenum internalformat = stencilAttachment->getInternalFormat();
+ const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
+ if (stencilAttachment->type() == GL_TEXTURE)
+ {
+ // texture stencil attachments come along as part
+ // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
+ if (!data.extensions->depthTextures)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+
+ if (!formatCaps.renderable)
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+
+ if (formatInfo.stencilBits == 0)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+ }
+ else if (stencilAttachment->type() == GL_RENDERBUFFER)
+ {
+ if (!formatCaps.renderable || formatInfo.stencilBits == 0)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+ }
+
+ if (missingAttachment)
+ {
+ width = stencilAttachment->getWidth();
+ height = stencilAttachment->getHeight();
+ samples = stencilAttachment->getSamples();
+ missingAttachment = false;
+ }
+ else if (width != stencilAttachment->getWidth() || height != stencilAttachment->getHeight())
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
+ else if (samples != stencilAttachment->getSamples())
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
+ }
+ }
+
+ // 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 (depthAttachment && stencilAttachment && !hasValidDepthStencil())
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+
+ // we need to have at least one attachment to be complete
+ if (missingAttachment)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+ }
+
+ return mImpl->checkStatus();
+}
+
+Error Framebuffer::invalidate(size_t count, const GLenum *attachments)
+{
+ return mImpl->invalidate(count, attachments);
+}
+
+Error Framebuffer::invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area)
+{
+ return mImpl->invalidateSub(count, attachments, area);
+}
+
+Error Framebuffer::clear(const gl::Data &data, GLbitfield mask)
+{
+ return mImpl->clear(data, mask);
+}
+
+Error Framebuffer::clearBufferfv(const State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values)
+{
+ return mImpl->clearBufferfv(state, buffer, drawbuffer, values);
+}
+
+Error Framebuffer::clearBufferuiv(const State &state, GLenum buffer, GLint drawbuffer, const GLuint *values)
+{
+ return mImpl->clearBufferuiv(state, buffer, drawbuffer, values);
+}
+
+Error Framebuffer::clearBufferiv(const State &state, GLenum buffer, GLint drawbuffer, const GLint *values)
+{
+ return mImpl->clearBufferiv(state, buffer, drawbuffer, values);
+}
+
+Error Framebuffer::clearBufferfi(const State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+{
+ return mImpl->clearBufferfi(state, buffer, drawbuffer, depth, stencil);
+}
+
+GLenum Framebuffer::getImplementationColorReadFormat() const
+{
+ return mImpl->getImplementationColorReadFormat();
+}
+
+GLenum Framebuffer::getImplementationColorReadType() const
+{
+ return mImpl->getImplementationColorReadType();
+}
+
+Error Framebuffer::readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const
+{
+ return mImpl->readPixels(state, area, format, type, pixels);
+}
+
+Error Framebuffer::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
+ GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer)
+{
+ return mImpl->blit(state, sourceArea, destArea, mask, filter, sourceFramebuffer);
+}
+
+int Framebuffer::getSamples(const gl::Data &data) const
+{
+ if (checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
+ {
+ // for a complete framebuffer, all attachments must have the same sample count
+ // in this case return the first nonzero sample size
+ for (auto it = mData.mColorAttachments.cbegin(); it != mData.mColorAttachments.cend(); ++it)
+ {
+ if (*it != nullptr)
+ {
+ return (*it)->getSamples();
+ }
+ }
+ }
+
+ return 0;
+}
+
+bool Framebuffer::hasValidDepthStencil() const
+{
+ // A valid depth-stencil attachment has the same resource bound to both the
+ // depth and stencil attachment points.
+ return (mData.mDepthAttachment && mData.mStencilAttachment &&
+ mData.mDepthAttachment->type() == mData.mStencilAttachment->type() &&
+ mData.mDepthAttachment->id() == mData.mStencilAttachment->id());
+}
+
+void Framebuffer::setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex)
+{
+ setAttachment(attachment, new TextureAttachment(attachment, texture, imageIndex));
+}
+
+void Framebuffer::setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer)
+{
+ setAttachment(attachment, new RenderbufferAttachment(attachment, renderbuffer));
+}
+
+void Framebuffer::setNULLAttachment(GLenum attachment)
+{
+ setAttachment(attachment, NULL);
+}
+
+void Framebuffer::setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj)
+{
+ if (attachment >= GL_COLOR_ATTACHMENT0 && attachment < (GL_COLOR_ATTACHMENT0 + mData.mColorAttachments.size()))
+ {
+ size_t colorAttachment = attachment - GL_COLOR_ATTACHMENT0;
+ SafeDelete(mData.mColorAttachments[colorAttachment]);
+ mData.mColorAttachments[colorAttachment] = attachmentObj;
+ mImpl->setColorAttachment(colorAttachment, attachmentObj);
+ }
+ else if (attachment == GL_BACK)
+ {
+ SafeDelete(mData.mColorAttachments[0]);
+ mData.mColorAttachments[0] = attachmentObj;
+ mImpl->setColorAttachment(0, attachmentObj);
+ }
+ else if (attachment == GL_DEPTH_ATTACHMENT || attachment == GL_DEPTH)
+ {
+ SafeDelete(mData.mDepthAttachment);
+ mData.mDepthAttachment = attachmentObj;
+ mImpl->setDepthAttachment(attachmentObj);
+ }
+ else if (attachment == GL_STENCIL_ATTACHMENT || attachment == GL_STENCIL)
+ {
+ SafeDelete(mData.mStencilAttachment);
+ mData.mStencilAttachment = attachmentObj;
+ mImpl->setStencilAttachment(attachmentObj);
+ }
+ else if (attachment == GL_DEPTH_STENCIL_ATTACHMENT || attachment == GL_DEPTH_STENCIL)
+ {
+ SafeDelete(mData.mDepthAttachment);
+ SafeDelete(mData.mStencilAttachment);
+
+ // ensure this is a legitimate depth+stencil format
+ if (attachmentObj && attachmentObj->getDepthSize() > 0 && attachmentObj->getStencilSize() > 0)
+ {
+ mData.mDepthAttachment = attachmentObj;
+ mImpl->setDepthAttachment(attachmentObj);
+
+ // Make a new attachment object to ensure we do not double-delete
+ // See angle issue 686
+ if (attachmentObj->type() == GL_TEXTURE)
+ {
+ mData.mStencilAttachment = new TextureAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getTexture(),
+ *attachmentObj->getTextureImageIndex());
+ mImpl->setStencilAttachment(mData.mStencilAttachment);
+ }
+ else if (attachmentObj->type() == GL_RENDERBUFFER)
+ {
+ mData.mStencilAttachment = new RenderbufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getRenderbuffer());
+ mImpl->setStencilAttachment(mData.mStencilAttachment);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+}
+
+DefaultFramebuffer::DefaultFramebuffer(const Caps &caps, rx::ImplFactory *factory, egl::Surface *surface)
+ : Framebuffer(caps, factory, 0)
+{
+ const egl::Config *config = surface->getConfig();
+
+ setAttachment(GL_BACK, new DefaultAttachment(GL_BACK, surface));
+
+ if (config->depthSize > 0)
+ {
+ setAttachment(GL_DEPTH, new DefaultAttachment(GL_DEPTH, surface));
+ }
+ if (config->stencilSize > 0)
+ {
+ setAttachment(GL_STENCIL, new DefaultAttachment(GL_STENCIL, surface));
+ }
+
+ GLenum drawBufferState = GL_BACK;
+ setDrawBuffers(1, &drawBufferState);
+
+ setReadBuffer(GL_BACK);
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/Framebuffer.h b/src/3rdparty/angle/src/libANGLE/Framebuffer.h
new file mode 100644
index 0000000000..8b24cf984e
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Framebuffer.h
@@ -0,0 +1,144 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// 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/angleutils.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
+
+namespace rx
+{
+class ImplFactory;
+class FramebufferImpl;
+class RenderbufferImpl;
+struct Workarounds;
+}
+
+namespace egl
+{
+class Surface;
+}
+
+namespace gl
+{
+class FramebufferAttachment;
+class Renderbuffer;
+class State;
+class Texture;
+class TextureCapsMap;
+struct Caps;
+struct Data;
+struct Extensions;
+struct ImageIndex;
+struct Rectangle;
+
+typedef std::vector<FramebufferAttachment *> AttachmentList;
+
+class Framebuffer
+{
+ public:
+
+ class Data final : angle::NonCopyable
+ {
+ public:
+ explicit Data(const Caps &caps);
+ ~Data();
+
+ FramebufferAttachment *getReadAttachment() const;
+ FramebufferAttachment *getFirstColorAttachment() const;
+ FramebufferAttachment *getDepthOrStencilAttachment() const;
+
+ AttachmentList mColorAttachments;
+ FramebufferAttachment *mDepthAttachment;
+ FramebufferAttachment *mStencilAttachment;
+
+ std::vector<GLenum> mDrawBufferStates;
+ GLenum mReadBufferState;
+ };
+
+ Framebuffer(const Caps &caps, rx::ImplFactory *factory, GLuint id);
+ virtual ~Framebuffer();
+
+ const rx::FramebufferImpl *getImplementation() const { return mImpl; }
+ rx::FramebufferImpl *getImplementation() { return mImpl; }
+
+ GLuint id() const { return mId; }
+
+ void setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex);
+ void setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer);
+ void setNULLAttachment(GLenum attachment);
+
+ void detachTexture(GLuint texture);
+ void detachRenderbuffer(GLuint renderbuffer);
+
+ FramebufferAttachment *getColorbuffer(unsigned int colorAttachment) const;
+ FramebufferAttachment *getDepthbuffer() const;
+ FramebufferAttachment *getStencilbuffer() const;
+ FramebufferAttachment *getDepthStencilBuffer() const;
+ FramebufferAttachment *getDepthOrStencilbuffer() const;
+ FramebufferAttachment *getReadColorbuffer() const;
+ GLenum getReadColorbufferType() const;
+ FramebufferAttachment *getFirstColorbuffer() const;
+
+ FramebufferAttachment *getAttachment(GLenum attachment) const;
+
+ GLenum getDrawBufferState(unsigned int colorAttachment) const;
+ void setDrawBuffers(size_t count, const GLenum *buffers);
+
+ GLenum getReadBufferState() const;
+ void setReadBuffer(GLenum buffer);
+
+ bool isEnabledColorAttachment(unsigned int colorAttachment) const;
+ bool hasEnabledColorAttachment() const;
+ bool hasStencil() const;
+ int getSamples(const gl::Data &data) const;
+ bool usingExtendedDrawBuffers() const;
+
+ GLenum checkStatus(const gl::Data &data) const;
+ bool hasValidDepthStencil() const;
+
+ Error invalidate(size_t count, const GLenum *attachments);
+ Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area);
+
+ Error clear(const gl::Data &data, GLbitfield mask);
+ Error clearBufferfv(const State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values);
+ Error clearBufferuiv(const State &state, GLenum buffer, GLint drawbuffer, const GLuint *values);
+ Error clearBufferiv(const State &state, GLenum buffer, GLint drawbuffer, const GLint *values);
+ Error clearBufferfi(const State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+
+ GLenum getImplementationColorReadFormat() const;
+ GLenum getImplementationColorReadType() const;
+ Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const;
+
+ Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
+ GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer);
+
+ protected:
+ void setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj);
+ void detachResourceById(GLenum resourceType, GLuint resourceId);
+
+ Data mData;
+ rx::FramebufferImpl *mImpl;
+ GLuint mId;
+};
+
+class DefaultFramebuffer : public Framebuffer
+{
+ public:
+ DefaultFramebuffer(const gl::Caps &caps, rx::ImplFactory *factory, egl::Surface *surface);
+};
+
+}
+
+#endif // LIBANGLE_FRAMEBUFFER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp b/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.cpp
index 894884a6d8..e56fc750ad 100644
--- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp
+++ b/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.cpp
@@ -7,15 +7,15 @@
// 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 "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/renderer/RenderTarget.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/d3d/TextureStorage.h"
+#include "libANGLE/FramebufferAttachment.h"
#include "common/utilities.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/FramebufferImpl.h"
namespace gl
{
@@ -33,47 +33,42 @@ FramebufferAttachment::~FramebufferAttachment()
GLuint FramebufferAttachment::getRedSize() const
{
- return (GetInternalFormatInfo(getInternalFormat()).redBits > 0) ? GetInternalFormatInfo(getActualFormat()).redBits : 0;
+ return GetInternalFormatInfo(getInternalFormat()).redBits;
}
GLuint FramebufferAttachment::getGreenSize() const
{
- return (GetInternalFormatInfo(getInternalFormat()).greenBits > 0) ? GetInternalFormatInfo(getActualFormat()).greenBits : 0;
+ return GetInternalFormatInfo(getInternalFormat()).greenBits;
}
GLuint FramebufferAttachment::getBlueSize() const
{
- return (GetInternalFormatInfo(getInternalFormat()).blueBits > 0) ? GetInternalFormatInfo(getActualFormat()).blueBits : 0;
+ return GetInternalFormatInfo(getInternalFormat()).blueBits;
}
GLuint FramebufferAttachment::getAlphaSize() const
{
- return (GetInternalFormatInfo(getInternalFormat()).alphaBits > 0) ? GetInternalFormatInfo(getActualFormat()).alphaBits : 0;
+ return GetInternalFormatInfo(getInternalFormat()).alphaBits;
}
GLuint FramebufferAttachment::getDepthSize() const
{
- return (GetInternalFormatInfo(getInternalFormat()).depthBits > 0) ? GetInternalFormatInfo(getActualFormat()).depthBits : 0;
+ return GetInternalFormatInfo(getInternalFormat()).depthBits;
}
GLuint FramebufferAttachment::getStencilSize() const
{
- return (GetInternalFormatInfo(getInternalFormat()).stencilBits > 0) ? GetInternalFormatInfo(getActualFormat()).stencilBits : 0;
+ return GetInternalFormatInfo(getInternalFormat()).stencilBits;
}
GLenum FramebufferAttachment::getComponentType() const
{
- return GetInternalFormatInfo(getActualFormat()).componentType;
+ return GetInternalFormatInfo(getInternalFormat()).componentType;
}
GLenum FramebufferAttachment::getColorEncoding() const
{
- return GetInternalFormatInfo(getActualFormat()).colorEncoding;
-}
-
-bool FramebufferAttachment::isTexture() const
-{
- return (type() != GL_RENDERBUFFER);
+ return GetInternalFormatInfo(getInternalFormat()).colorEncoding;
}
///// TextureAttachment Implementation ////////
@@ -102,27 +97,22 @@ GLuint TextureAttachment::id() const
GLsizei TextureAttachment::getWidth() const
{
- return mTexture->getWidth(mIndex);
+ return mTexture->getWidth(mIndex.type, mIndex.mipIndex);
}
GLsizei TextureAttachment::getHeight() const
{
- return mTexture->getHeight(mIndex);
+ return mTexture->getHeight(mIndex.type, mIndex.mipIndex);
}
GLenum TextureAttachment::getInternalFormat() const
{
- return mTexture->getInternalFormat(mIndex);
-}
-
-GLenum TextureAttachment::getActualFormat() const
-{
- return mTexture->getActualFormat(mIndex);
+ return mTexture->getInternalFormat(mIndex.type, mIndex.mipIndex);
}
GLenum TextureAttachment::type() const
{
- return mIndex.type;
+ return GL_TEXTURE;
}
GLint TextureAttachment::mipLevel() const
@@ -130,12 +120,17 @@ GLint TextureAttachment::mipLevel() const
return mIndex.mipIndex;
}
+GLenum TextureAttachment::cubeMapFace() const
+{
+ return IsCubeMapTextureTarget(mIndex.type) ? mIndex.type : GL_NONE;
+}
+
GLint TextureAttachment::layer() const
{
return mIndex.layerIndex;
}
-Texture *TextureAttachment::getTexture()
+Texture *TextureAttachment::getTexture() const
{
return mTexture.get();
}
@@ -145,7 +140,7 @@ const ImageIndex *TextureAttachment::getTextureImageIndex() const
return &mIndex;
}
-Renderbuffer *TextureAttachment::getRenderbuffer()
+Renderbuffer *TextureAttachment::getRenderbuffer() const
{
UNREACHABLE();
return NULL;
@@ -180,11 +175,6 @@ GLenum RenderbufferAttachment::getInternalFormat() const
return mRenderbuffer->getInternalFormat();
}
-GLenum RenderbufferAttachment::getActualFormat() const
-{
- return mRenderbuffer->getActualFormat();
-}
-
GLsizei RenderbufferAttachment::getSamples() const
{
return mRenderbuffer->getSamples();
@@ -205,12 +195,17 @@ GLint RenderbufferAttachment::mipLevel() const
return 0;
}
+GLenum RenderbufferAttachment::cubeMapFace() const
+{
+ return GL_NONE;
+}
+
GLint RenderbufferAttachment::layer() const
{
return 0;
}
-Texture *RenderbufferAttachment::getTexture()
+Texture *RenderbufferAttachment::getTexture() const
{
UNREACHABLE();
return NULL;
@@ -222,9 +217,86 @@ const ImageIndex *RenderbufferAttachment::getTextureImageIndex() const
return NULL;
}
-Renderbuffer *RenderbufferAttachment::getRenderbuffer()
+Renderbuffer *RenderbufferAttachment::getRenderbuffer() const
{
return mRenderbuffer.get();
}
+
+DefaultAttachment::DefaultAttachment(GLenum binding, egl::Surface *surface)
+ : FramebufferAttachment(binding)
+{
+ mSurface.set(surface);
+}
+
+DefaultAttachment::~DefaultAttachment()
+{
+ mSurface.set(nullptr);
+}
+
+GLsizei DefaultAttachment::getWidth() const
+{
+ return mSurface->getWidth();
+}
+
+GLsizei DefaultAttachment::getHeight() const
+{
+ return mSurface->getHeight();
+}
+
+GLenum DefaultAttachment::getInternalFormat() const
+{
+ const egl::Config *config = mSurface->getConfig();
+ return (getBinding() == GL_BACK ? config->renderTargetFormat : config->depthStencilFormat);
+}
+
+GLsizei DefaultAttachment::getSamples() const
+{
+ const egl::Config *config = mSurface->getConfig();
+ return config->samples;
+}
+
+GLuint DefaultAttachment::id() const
+{
+ return 0;
+}
+
+GLenum DefaultAttachment::type() const
+{
+ return GL_FRAMEBUFFER_DEFAULT;
+}
+
+GLint DefaultAttachment::mipLevel() const
+{
+ return 0;
+}
+
+GLenum DefaultAttachment::cubeMapFace() const
+{
+ return GL_NONE;
+}
+
+GLint DefaultAttachment::layer() const
+{
+ return 0;
+}
+
+Texture *DefaultAttachment::getTexture() const
+{
+ UNREACHABLE();
+ return NULL;
+}
+
+const ImageIndex *DefaultAttachment::getTextureImageIndex() const
+{
+ UNREACHABLE();
+ return NULL;
+}
+
+Renderbuffer *DefaultAttachment::getRenderbuffer() const
+{
+ UNREACHABLE();
+ return NULL;
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h b/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.h
index 8d2dafa7ee..0662130931 100644
--- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h
+++ b/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.h
@@ -7,12 +7,13 @@
// 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 LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
-#define LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
+#ifndef LIBANGLE_FRAMEBUFFERATTACHMENT_H_
+#define LIBANGLE_FRAMEBUFFERATTACHMENT_H_
+
+#include "libANGLE/Texture.h"
+#include "libANGLE/RefCountObject.h"
#include "common/angleutils.h"
-#include "common/RefCountObject.h"
-#include "Texture.h"
#include "angle_gl.h"
@@ -26,7 +27,7 @@ class Renderbuffer;
// Note: Our old naming scheme used the term "Renderbuffer" for both GL renderbuffers and for
// framebuffer attachments, which confused their usage.
-class FramebufferAttachment
+class FramebufferAttachment : angle::NonCopyable
{
public:
explicit FramebufferAttachment(GLenum binding);
@@ -41,10 +42,9 @@ class FramebufferAttachment
GLuint getStencilSize() const;
GLenum getComponentType() const;
GLenum getColorEncoding() const;
- bool isTexture() const;
- bool isTextureWithId(GLuint textureId) const { return isTexture() && id() == textureId; }
- bool isRenderbufferWithId(GLuint renderbufferId) const { return !isTexture() && id() == renderbufferId; }
+ bool isTextureWithId(GLuint textureId) const { return type() == GL_TEXTURE && id() == textureId; }
+ bool isRenderbufferWithId(GLuint renderbufferId) const { return type() == GL_RENDERBUFFER && id() == renderbufferId; }
GLenum getBinding() const { return mBinding; }
@@ -52,21 +52,19 @@ class FramebufferAttachment
virtual GLsizei getWidth() const = 0;
virtual GLsizei getHeight() const = 0;
virtual GLenum getInternalFormat() const = 0;
- virtual GLenum getActualFormat() const = 0;
virtual GLsizei getSamples() const = 0;
virtual GLuint id() const = 0;
virtual GLenum type() const = 0;
virtual GLint mipLevel() const = 0;
+ virtual GLenum cubeMapFace() const = 0;
virtual GLint layer() const = 0;
- virtual Texture *getTexture() = 0;
+ virtual Texture *getTexture() const = 0;
virtual const ImageIndex *getTextureImageIndex() const = 0;
- virtual Renderbuffer *getRenderbuffer() = 0;
+ virtual Renderbuffer *getRenderbuffer() const = 0;
private:
- DISALLOW_COPY_AND_ASSIGN(FramebufferAttachment);
-
GLenum mBinding;
};
@@ -82,19 +80,17 @@ class TextureAttachment : public FramebufferAttachment
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
- virtual GLenum getActualFormat() const;
virtual GLenum type() const;
virtual GLint mipLevel() const;
+ virtual GLenum cubeMapFace() const;
virtual GLint layer() const;
- virtual Texture *getTexture();
+ virtual Texture *getTexture() const;
virtual const ImageIndex *getTextureImageIndex() const;
- virtual Renderbuffer *getRenderbuffer();
+ virtual Renderbuffer *getRenderbuffer() const;
private:
- DISALLOW_COPY_AND_ASSIGN(TextureAttachment);
-
BindingPointer<Texture> mTexture;
ImageIndex mIndex;
};
@@ -109,24 +105,50 @@ class RenderbufferAttachment : public FramebufferAttachment
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
- virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const;
virtual GLuint id() const;
virtual GLenum type() const;
virtual GLint mipLevel() const;
+ virtual GLenum cubeMapFace() const;
virtual GLint layer() const;
- virtual Texture *getTexture();
+ virtual Texture *getTexture() const;
virtual const ImageIndex *getTextureImageIndex() const;
- virtual Renderbuffer *getRenderbuffer();
+ virtual Renderbuffer *getRenderbuffer() const;
private:
- DISALLOW_COPY_AND_ASSIGN(RenderbufferAttachment);
-
BindingPointer<Renderbuffer> mRenderbuffer;
};
+class DefaultAttachment : public FramebufferAttachment
+{
+ public:
+ DefaultAttachment(GLenum binding, egl::Surface *surface);
+
+ virtual ~DefaultAttachment();
+
+ virtual GLsizei getWidth() const;
+ virtual GLsizei getHeight() const;
+ virtual GLenum getInternalFormat() const;
+ virtual GLsizei getSamples() const;
+
+ virtual GLuint id() const;
+ virtual GLenum type() const;
+ virtual GLint mipLevel() const;
+ virtual GLenum cubeMapFace() const;
+ virtual GLint layer() const;
+
+ virtual Texture *getTexture() const;
+ virtual const ImageIndex *getTextureImageIndex() const;
+ virtual Renderbuffer *getRenderbuffer() const;
+
+ const egl::Surface *getSurface() const { return mSurface.get(); }
+
+ private:
+ BindingPointer<egl::Surface> mSurface;
+};
+
}
-#endif // LIBGLESV2_FRAMEBUFFERATTACHMENT_H_
+#endif // LIBANGLE_FRAMEBUFFERATTACHMENT_H_
diff --git a/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp b/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
new file mode 100644
index 0000000000..59d3966758
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp
@@ -0,0 +1,133 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// HandleAllocator.cpp: Implements the gl::HandleAllocator class, which is used
+// to allocate GL handles.
+
+#include "libANGLE/HandleAllocator.h"
+
+#include <algorithm>
+
+#include "common/debug.h"
+
+namespace gl
+{
+
+struct HandleAllocator::HandleRangeComparator
+{
+ bool operator()(const HandleRange &range, GLuint handle) const
+ {
+ return (handle < range.begin);
+ }
+};
+
+HandleAllocator::HandleAllocator() : mBaseValue(1), mNextValue(1)
+{
+ mUnallocatedList.push_back(HandleRange(1, std::numeric_limits<GLuint>::max() - 1));
+}
+
+HandleAllocator::HandleAllocator(GLuint maximumHandleValue) : mBaseValue(1), mNextValue(1)
+{
+ 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, constant time.
+ if (!mReleasedList.empty())
+ {
+ GLuint reusedHandle = mReleasedList.back();
+ mReleasedList.pop_back();
+ return reusedHandle;
+ }
+
+ // Allocate from unallocated list, constant time.
+ auto listIt = mUnallocatedList.begin();
+
+ GLuint freeListHandle = listIt->begin;
+ ASSERT(freeListHandle > 0);
+
+ listIt->begin++;
+ if (listIt->begin == listIt->end)
+ {
+ mUnallocatedList.erase(listIt);
+ }
+
+ return freeListHandle;
+}
+
+void HandleAllocator::release(GLuint handle)
+{
+ // Add to released list, constant time.
+ mReleasedList.push_back(handle);
+}
+
+void HandleAllocator::reserve(GLuint handle)
+{
+ // 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);
+ 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 + 1 == end)
+ {
+ mUnallocatedList.erase(boundIt);
+ }
+ else if (handle == begin)
+ {
+ boundIt->begin++;
+ }
+ else
+ {
+ ASSERT(handle == end);
+ boundIt->end--;
+ }
+ return;
+ }
+
+ // need to split the range
+ auto placementIt = mUnallocatedList.erase(boundIt);
+
+ if (begin != handle)
+ {
+ placementIt = mUnallocatedList.insert(placementIt, HandleRange(begin, handle));
+ }
+ if (handle + 1 != end)
+ {
+ mUnallocatedList.insert(placementIt, HandleRange(handle + 1, end));
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/HandleAllocator.h b/src/3rdparty/angle/src/libANGLE/HandleAllocator.h
new file mode 100644
index 0000000000..c22f2ba61a
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/HandleAllocator.h
@@ -0,0 +1,63 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// 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"
+
+#include <stack>
+
+namespace gl
+{
+
+class HandleAllocator final : angle::NonCopyable
+{
+ public:
+ // Maximum handle = MAX_UINT-1
+ HandleAllocator();
+ // Specify maximum handle value
+ HandleAllocator(GLuint maximumHandleValue);
+
+ ~HandleAllocator();
+
+ void setBaseHandle(GLuint value);
+
+ GLuint allocate();
+ void release(GLuint handle);
+ void reserve(GLuint handle);
+
+ private:
+ GLuint mBaseValue;
+ GLuint mNextValue;
+ typedef std::vector<GLuint> HandleList;
+ HandleList mFreeValues;
+
+ 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 stack.
+ std::vector<HandleRange> mUnallocatedList;
+ std::vector<GLuint> mReleasedList;
+};
+
+}
+
+#endif // LIBANGLE_HANDLEALLOCATOR_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp b/src/3rdparty/angle/src/libANGLE/ImageIndex.cpp
index b45cd9c169..ac7302d121 100644
--- a/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp
+++ b/src/3rdparty/angle/src/libANGLE/ImageIndex.cpp
@@ -6,8 +6,8 @@
// ImageIndex.cpp: Implementation for ImageIndex methods.
-#include "libGLESv2/ImageIndex.h"
-#include "libGLESv2/Texture.h"
+#include "libANGLE/ImageIndex.h"
+#include "libANGLE/Constants.h"
#include "common/utilities.h"
namespace gl
@@ -34,8 +34,8 @@ ImageIndex ImageIndex::Make2D(GLint mipIndex)
ImageIndex ImageIndex::MakeCube(GLenum target, GLint mipIndex)
{
- ASSERT(gl::IsCubemapTextureTarget(target));
- return ImageIndex(target, mipIndex, TextureCubeMap::targetToLayerIndex(target));
+ ASSERT(gl::IsCubeMapTextureTarget(target));
+ return ImageIndex(target, mipIndex, CubeMapTextureTargetToLayerIndex(target));
}
ImageIndex ImageIndex::Make2DArray(GLint mipIndex, GLint layerIndex)
@@ -48,11 +48,33 @@ ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex)
return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex);
}
+ImageIndex ImageIndex::MakeGeneric(GLenum target, GLint mipIndex)
+{
+ GLint layerIndex = IsCubeMapTextureTarget(target) ? CubeMapTextureTargetToLayerIndex(target) : ENTIRE_LEVEL;
+ return ImageIndex(target, mipIndex, layerIndex);
+}
+
ImageIndex ImageIndex::MakeInvalid()
{
return ImageIndex(GL_NONE, -1, -1);
}
+bool ImageIndex::operator<(const ImageIndex &other) const
+{
+ if (type != other.type)
+ {
+ return type < other.type;
+ }
+ else if (mipIndex != other.mipIndex)
+ {
+ return mipIndex < other.mipIndex;
+ }
+ else
+ {
+ return layerIndex < other.layerIndex;
+ }
+}
+
ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn)
: type(typeIn),
mipIndex(mipIndexIn),
@@ -134,7 +156,7 @@ ImageIndex ImageIndexIterator::current() const
if (mType == GL_TEXTURE_CUBE_MAP)
{
- value.type = TextureCubeMap::layerIndexToTarget(mCurrentLayer);
+ value.type = LayerIndexToCubeMapTextureTarget(mCurrentLayer);
}
return value;
diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.h b/src/3rdparty/angle/src/libANGLE/ImageIndex.h
index 8bb14fd555..820c650f20 100644
--- a/src/3rdparty/angle/src/libGLESv2/ImageIndex.h
+++ b/src/3rdparty/angle/src/libANGLE/ImageIndex.h
@@ -6,22 +6,24 @@
// ImageIndex.h: A helper struct for indexing into an Image array
-#ifndef LIBGLESV2_IMAGE_INDEX_H_
-#define LIBGLESV2_IMAGE_INDEX_H_
+#ifndef LIBANGLE_IMAGE_INDEX_H_
+#define LIBANGLE_IMAGE_INDEX_H_
-#include "angle_gl.h"
#include "common/mathutil.h"
+#include "angle_gl.h"
+
namespace gl
{
+class ImageIndexIterator;
+
struct ImageIndex
{
GLenum type;
GLint mipIndex;
GLint layerIndex;
- ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
ImageIndex(const ImageIndex &other);
ImageIndex &operator=(const ImageIndex &other);
@@ -31,9 +33,18 @@ struct ImageIndex
static ImageIndex MakeCube(GLenum target, GLint mipIndex);
static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex);
static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL);
+ static ImageIndex MakeGeneric(GLenum target, GLint mipIndex);
+
static ImageIndex MakeInvalid();
static const GLint ENTIRE_LEVEL = static_cast<GLint>(-1);
+
+ bool operator<(const ImageIndex &other) const;
+
+ private:
+ friend class ImageIndexIterator;
+
+ ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
};
class ImageIndexIterator
@@ -65,4 +76,4 @@ class ImageIndexIterator
}
-#endif // LIBGLESV2_IMAGE_INDEX_H_
+#endif // LIBANGLE_IMAGE_INDEX_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Platform.cpp b/src/3rdparty/angle/src/libANGLE/Platform.cpp
new file mode 100644
index 0000000000..ab75bbba5a
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Platform.cpp
@@ -0,0 +1,35 @@
+//
+// 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/Platform.h>
+
+#include "common/debug.h"
+
+namespace
+{
+angle::Platform *currentPlatform = nullptr;
+}
+
+// static
+ANGLE_EXPORT angle::Platform *ANGLEPlatformCurrent()
+{
+ return currentPlatform;
+}
+
+// static
+ANGLE_EXPORT void ANGLEPlatformInitialize(angle::Platform *platformImpl)
+{
+ ASSERT(platformImpl != nullptr);
+ currentPlatform = platformImpl;
+}
+
+// static
+ANGLE_EXPORT void ANGLEPlatformShutdown()
+{
+ currentPlatform = nullptr;
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libANGLE/Program.cpp
index 6d64b38b56..daf0a403f0 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Program.cpp
@@ -7,30 +7,24 @@
// 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 "libGLESv2/BinaryStream.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/renderer/ShaderExecutable.h"
+#include "libANGLE/Program.h"
+
+#include <algorithm>
#include "common/debug.h"
-#include "common/version.h"
-#include "common/utilities.h"
#include "common/platform.h"
-
-#include "libGLESv2/main.h"
-#include "libGLESv2/Shader.h"
-#include "libGLESv2/Program.h"
-#include "libGLESv2/renderer/ProgramImpl.h"
-#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/Buffer.h"
-#include "common/blocklayout.h"
-#include "common/features.h"
+#include "common/utilities.h"
+#include "common/version.h"
+#include "compiler/translator/blocklayout.h"
+#include "libANGLE/Data.h"
+#include "libANGLE/ResourceManager.h"
+#include "libANGLE/features.h"
+#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/renderer/ProgramImpl.h"
namespace gl
{
+const char * const g_fakepath = "C:\\fakepath";
namespace
{
@@ -53,353 +47,403 @@ unsigned int ParseAndStripArrayIndex(std::string* name)
}
-VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
- : name(name), element(element), index(index)
+AttributeBindings::AttributeBindings()
{
}
-LinkedVarying::LinkedVarying()
+AttributeBindings::~AttributeBindings()
{
}
-LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName,
- unsigned int semanticIndex, unsigned int semanticIndexCount)
- : name(name), type(type), size(size), semanticName(semanticName), semanticIndex(semanticIndex), semanticIndexCount(semanticIndexCount)
+InfoLog::InfoLog() : mInfoLog(NULL)
{
}
-LinkResult::LinkResult(bool linkSuccess, const Error &error)
- : linkSuccess(linkSuccess),
- error(error)
+InfoLog::~InfoLog()
{
+ delete[] mInfoLog;
}
-unsigned int ProgramBinary::mCurrentSerial = 1;
-ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
- : RefCountObject(0),
- mProgram(impl),
- mValidated(false),
- mSerial(issueSerial())
+int InfoLog::getLength() const
{
- ASSERT(impl);
-
- for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
+ if (!mInfoLog)
{
- mSemanticIndex[index] = -1;
+ return 0;
+ }
+ else
+ {
+ return strlen(mInfoLog) + 1;
}
}
-ProgramBinary::~ProgramBinary()
+void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog)
{
- reset();
- SafeDelete(mProgram);
-}
+ int index = 0;
-unsigned int ProgramBinary::getSerial() const
-{
- return mSerial;
-}
+ if (bufSize > 0)
+ {
+ if (mInfoLog)
+ {
+ index = std::min(bufSize - 1, (int)strlen(mInfoLog));
+ memcpy(infoLog, mInfoLog, index);
+ }
-unsigned int ProgramBinary::issueSerial()
-{
- return mCurrentSerial++;
+ infoLog[index] = '\0';
+ }
+
+ if (length)
+ {
+ *length = index;
+ }
}
-GLuint ProgramBinary::getAttributeLocation(const char *name)
+// append a santized 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)
{
- if (name)
+ std::string msg(message);
+
+ size_t found;
+ do
{
- for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
+ found = msg.find(g_fakepath);
+ if (found != std::string::npos)
{
- if (mLinkedAttribute[index].name == std::string(name))
- {
- return index;
- }
+ msg.erase(found, strlen(g_fakepath));
}
}
+ while (found != std::string::npos);
- return -1;
+ append("%s", msg.c_str());
}
-int ProgramBinary::getSemanticIndex(int attributeIndex)
+void InfoLog::append(const char *format, ...)
{
- ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
+ if (!format)
+ {
+ return;
+ }
- return mSemanticIndex[attributeIndex];
-}
+ va_list vararg;
+ va_start(vararg, format);
+ size_t infoLength = vsnprintf(NULL, 0, format, vararg);
+ va_end(vararg);
-// Returns one more than the highest sampler index used.
-GLint ProgramBinary::getUsedSamplerRange(SamplerType type)
-{
- return mProgram->getUsedSamplerRange(type);
-}
+ char *logPointer = NULL;
-bool ProgramBinary::usesPointSize() const
-{
- return mProgram->usesPointSize();
+ if (!mInfoLog)
+ {
+ mInfoLog = new char[infoLength + 2];
+ logPointer = mInfoLog;
+ }
+ else
+ {
+ size_t currentlogLength = strlen(mInfoLog);
+ char *newLog = new char[currentlogLength + infoLength + 2];
+ strcpy(newLog, mInfoLog);
+
+ delete[] mInfoLog;
+ mInfoLog = newLog;
+
+ logPointer = mInfoLog + currentlogLength;
+ }
+
+ va_start(vararg, format);
+ vsnprintf(logPointer, infoLength, format, vararg);
+ va_end(vararg);
+
+ logPointer[infoLength] = 0;
+ strcpy(logPointer + infoLength, "\n");
}
-GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
+void InfoLog::reset()
{
- return mProgram->getSamplerMapping(type, samplerIndex, caps);
+ if (mInfoLog)
+ {
+ delete [] mInfoLog;
+ mInfoLog = NULL;
+ }
}
-GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
+VariableLocation::VariableLocation()
+ : name(), element(0), index(0)
{
- return mProgram->getSamplerTextureType(type, samplerIndex);
}
-GLint ProgramBinary::getUniformLocation(std::string name)
+VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
+ : name(name), element(element), index(index)
{
- return mProgram->getUniformLocation(name);
}
-GLuint ProgramBinary::getUniformIndex(std::string name)
+LinkedVarying::LinkedVarying()
{
- return mProgram->getUniformIndex(name);
}
-GLuint ProgramBinary::getUniformBlockIndex(std::string name)
+LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName,
+ unsigned int semanticIndex, unsigned int semanticIndexCount)
+ : name(name), type(type), size(size), semanticName(semanticName), semanticIndex(semanticIndex), semanticIndexCount(semanticIndexCount)
{
- return mProgram->getUniformBlockIndex(name);
}
-UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex)
+Program::Program(rx::ProgramImpl *impl, ResourceManager *manager, GLuint handle)
+ : mProgram(impl),
+ mValidated(false),
+ mTransformFeedbackVaryings(),
+ mTransformFeedbackBufferMode(GL_NONE),
+ mFragmentShader(NULL),
+ mVertexShader(NULL),
+ mLinked(false),
+ mDeleteStatus(false),
+ mRefCount(0),
+ mResourceManager(manager),
+ mHandle(handle)
{
- return mProgram->getUniformBlockByIndex(blockIndex);
+ ASSERT(mProgram);
+
+ resetUniformBlockBindings();
+ unlink();
}
-GLint ProgramBinary::getFragDataLocation(const char *name) const
+Program::~Program()
{
- std::string baseName(name);
- unsigned int arrayIndex;
- arrayIndex = ParseAndStripArrayIndex(&baseName);
+ unlink(true);
- for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++)
+ if (mVertexShader != NULL)
{
- const VariableLocation &outputVariable = locationIt->second;
-
- if (outputVariable.name == baseName && (arrayIndex == GL_INVALID_INDEX || arrayIndex == outputVariable.element))
- {
- return static_cast<GLint>(locationIt->first);
- }
+ mVertexShader->release();
}
- return -1;
-}
-
-size_t ProgramBinary::getTransformFeedbackVaryingCount() const
-{
- return mProgram->getTransformFeedbackLinkedVaryings().size();
-}
+ if (mFragmentShader != NULL)
+ {
+ mFragmentShader->release();
+ }
-const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const
-{
- return mProgram->getTransformFeedbackLinkedVaryings()[idx];
+ SafeDelete(mProgram);
}
-GLenum ProgramBinary::getTransformFeedbackBufferMode() const
+bool Program::attachShader(Shader *shader)
{
- return mProgram->getTransformFeedbackBufferMode();
-}
-
-void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) {
- mProgram->setUniform1fv(location, count, v);
-}
-
-void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) {
- mProgram->setUniform2fv(location, count, v);
-}
-
-void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) {
- mProgram->setUniform3fv(location, count, v);
-}
+ if (shader->getType() == GL_VERTEX_SHADER)
+ {
+ if (mVertexShader)
+ {
+ return false;
+ }
-void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) {
- mProgram->setUniform4fv(location, count, v);
-}
+ mVertexShader = shader;
+ mVertexShader->addRef();
+ }
+ else if (shader->getType() == GL_FRAGMENT_SHADER)
+ {
+ if (mFragmentShader)
+ {
+ return false;
+ }
-void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) {
- mProgram->setUniform1iv(location, count, v);
-}
+ mFragmentShader = shader;
+ mFragmentShader->addRef();
+ }
+ else UNREACHABLE();
-void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) {
- mProgram->setUniform2iv(location, count, v);
+ return true;
}
-void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) {
- mProgram->setUniform3iv(location, count, v);
-}
+bool Program::detachShader(Shader *shader)
+{
+ if (shader->getType() == GL_VERTEX_SHADER)
+ {
+ if (mVertexShader != shader)
+ {
+ return false;
+ }
-void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) {
- mProgram->setUniform4iv(location, count, v);
-}
+ mVertexShader->release();
+ mVertexShader = NULL;
+ }
+ else if (shader->getType() == GL_FRAGMENT_SHADER)
+ {
+ if (mFragmentShader != shader)
+ {
+ return false;
+ }
-void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) {
- mProgram->setUniform1uiv(location, count, v);
-}
+ mFragmentShader->release();
+ mFragmentShader = NULL;
+ }
+ else UNREACHABLE();
-void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) {
- mProgram->setUniform2uiv(location, count, v);
+ return true;
}
-void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) {
- mProgram->setUniform3uiv(location, count, v);
+int Program::getAttachedShadersCount() const
+{
+ return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0);
}
-void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) {
- mProgram->setUniform4uiv(location, count, v);
-}
+void AttributeBindings::bindAttributeLocation(GLuint index, const char *name)
+{
+ if (index < MAX_VERTEX_ATTRIBS)
+ {
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ mAttributeBinding[i].erase(name);
+ }
-void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix2fv(location, count, transpose, v);
+ mAttributeBinding[index].insert(name);
+ }
}
-void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix3fv(location, count, transpose, v);
+void Program::bindAttributeLocation(GLuint index, const char *name)
+{
+ mAttributeBindings.bindAttributeLocation(index, name);
}
-void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix4fv(location, count, transpose, v);
-}
+// Links the HLSL code of the vertex and pixel shader by matching up their varyings,
+// compiling them into binaries, determining the attribute mappings, and collecting
+// a list of uniforms
+Error Program::link(const Data &data)
+{
+ unlink(false);
-void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix2x3fv(location, count, transpose, v);
-}
+ mInfoLog.reset();
+ resetUniformBlockBindings();
-void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix2x4fv(location, count, transpose, v);
-}
+ if (!mFragmentShader || !mFragmentShader->isCompiled())
+ {
+ return Error(GL_NO_ERROR);
+ }
+ ASSERT(mFragmentShader->getType() == GL_FRAGMENT_SHADER);
-void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix3x2fv(location, count, transpose, v);
-}
+ if (!mVertexShader || !mVertexShader->isCompiled())
+ {
+ return Error(GL_NO_ERROR);
+ }
+ ASSERT(mVertexShader->getType() == GL_VERTEX_SHADER);
-void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix3x4fv(location, count, transpose, v);
-}
+ if (!linkAttributes(mInfoLog, mAttributeBindings, mVertexShader))
+ {
+ return Error(GL_NO_ERROR);
+ }
-void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix4x2fv(location, count, transpose, v);
-}
+ int registers;
+ std::vector<LinkedVarying> linkedVaryings;
+ rx::LinkResult result = mProgram->link(data, mInfoLog, mFragmentShader, mVertexShader, mTransformFeedbackVaryings, mTransformFeedbackBufferMode,
+ &registers, &linkedVaryings, &mOutputVariables);
+ if (result.error.isError() || !result.linkSuccess)
+ {
+ return result.error;
+ }
-void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
- mProgram->setUniformMatrix4x3fv(location, count, transpose, v);
-}
+ if (!mProgram->linkUniforms(mInfoLog, *mVertexShader, *mFragmentShader, *data.caps))
+ {
+ return Error(GL_NO_ERROR);
+ }
-void ProgramBinary::getUniformfv(GLint location, GLfloat *v) {
- mProgram->getUniformfv(location, v);
-}
+ if (!linkUniformBlocks(mInfoLog, *mVertexShader, *mFragmentShader, *data.caps))
+ {
+ return Error(GL_NO_ERROR);
+ }
-void ProgramBinary::getUniformiv(GLint location, GLint *v) {
- mProgram->getUniformiv(location, v);
-}
+ if (!gatherTransformFeedbackLinkedVaryings(mInfoLog, linkedVaryings, mTransformFeedbackVaryings,
+ mTransformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps))
+ {
+ return Error(GL_NO_ERROR);
+ }
-void ProgramBinary::getUniformuiv(GLint location, GLuint *v) {
- mProgram->getUniformuiv(location, v);
-}
+ // TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called,
+ // however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling.
+ result = mProgram->compileProgramExecutables(mInfoLog, mFragmentShader, mVertexShader, registers);
+ if (result.error.isError() || !result.linkSuccess)
+ {
+ mInfoLog.append("Failed to create D3D shaders.");
+ unlink(false);
+ return result.error;
+ }
-void ProgramBinary::updateSamplerMapping()
-{
- return mProgram->updateSamplerMapping();
+ mLinked = true;
+ return gl::Error(GL_NO_ERROR);
}
-// Applies all the uniforms set for this program object to the renderer
-Error ProgramBinary::applyUniforms()
+int AttributeBindings::getAttributeBinding(const std::string &name) const
{
- return mProgram->applyUniforms();
-}
+ for (int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
+ {
+ if (mAttributeBinding[location].find(name) != mAttributeBinding[location].end())
+ {
+ return location;
+ }
+ }
-Error ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps)
-{
- return mProgram->applyUniformBuffers(boundBuffers, caps);
+ return -1;
}
-bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
+// Returns the program object to an unlinked state, before re-linking, or at destruction
+void Program::unlink(bool destroy)
{
- std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
- std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
-
- for (size_t fragVaryingIndex = 0; fragVaryingIndex < fragmentVaryings.size(); fragVaryingIndex++)
+ if (destroy) // Object being destructed
{
- PackedVarying *input = &fragmentVaryings[fragVaryingIndex];
- bool matched = false;
-
- // Built-in varyings obey special rules
- if (input->isBuiltIn())
+ if (mFragmentShader)
{
- continue;
+ mFragmentShader->release();
+ mFragmentShader = NULL;
}
- for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
+ if (mVertexShader)
{
- PackedVarying *output = &vertexVaryings[vertVaryingIndex];
- if (output->name == input->name)
- {
- if (!linkValidateVaryings(infoLog, output->name, *input, *output))
- {
- return false;
- }
+ mVertexShader->release();
+ mVertexShader = NULL;
+ }
+ }
- output->registerIndex = input->registerIndex;
- output->columnIndex = input->columnIndex;
+ std::fill(mLinkedAttribute, mLinkedAttribute + ArraySize(mLinkedAttribute), sh::Attribute());
+ mOutputVariables.clear();
- matched = true;
- break;
- }
- }
+ mProgram->reset();
- // We permit unmatched, unreferenced varyings
- if (!matched && input->staticUse)
- {
- infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
- return false;
- }
- }
+ mValidated = false;
- return true;
+ mLinked = false;
}
-LinkResult ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
+bool Program::isLinked()
{
-#if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_DISABLED
- return LinkResult(false, Error(GL_NO_ERROR));
+ return mLinked;
+}
+
+Error Program::loadBinary(GLenum binaryFormat, const void *binary, GLsizei length)
+{
+ unlink(false);
+
+#if ANGLE_PROGRAM_BINARY_LOAD != ANGLE_ENABLED
+ return Error(GL_NO_ERROR);
#else
ASSERT(binaryFormat == mProgram->getBinaryFormat());
- reset();
-
BinaryInputStream stream(binary, length);
GLenum format = stream.readInt<GLenum>();
if (format != mProgram->getBinaryFormat())
{
- infoLog.append("Invalid program binary format.");
- return LinkResult(false, Error(GL_NO_ERROR));
+ mInfoLog.append("Invalid program binary format.");
+ return Error(GL_NO_ERROR);
}
int majorVersion = stream.readInt<int>();
int minorVersion = stream.readInt<int>();
if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION)
{
- infoLog.append("Invalid program binary version.");
- return LinkResult(false, Error(GL_NO_ERROR));
+ mInfoLog.append("Invalid program binary version.");
+ return Error(GL_NO_ERROR);
}
unsigned char commitString[ANGLE_COMMIT_HASH_SIZE];
stream.readBytes(commitString, ANGLE_COMMIT_HASH_SIZE);
if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0)
{
- infoLog.append("Invalid program binary version.");
- return LinkResult(false, Error(GL_NO_ERROR));
- }
-
- int compileFlags = stream.readInt<int>();
- if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
- {
- infoLog.append("Mismatched compilation flags.");
- return LinkResult(false, Error(GL_NO_ERROR));
+ mInfoLog.append("Invalid program binary version.");
+ return Error(GL_NO_ERROR);
}
for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
@@ -408,22 +452,21 @@ LinkResult ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void
stream.readString(&mLinkedAttribute[i].name);
stream.readInt(&mProgram->getShaderAttributes()[i].type);
stream.readString(&mProgram->getShaderAttributes()[i].name);
- stream.readInt(&mSemanticIndex[i]);
+ stream.readInt(&mProgram->getSemanticIndexes()[i]);
}
- initAttributesByLayout();
-
- LinkResult result = mProgram->load(infoLog, &stream);
+ rx::LinkResult result = mProgram->load(mInfoLog, &stream);
if (result.error.isError() || !result.linkSuccess)
{
- return result;
+ return result.error;
}
- return LinkResult(true, Error(GL_NO_ERROR));
+ mLinked = true;
+ return Error(GL_NO_ERROR);
#endif // #if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_ENABLED
}
-Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
+Error Program::saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) const
{
if (binaryFormat)
{
@@ -436,7 +479,6 @@ Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, G
stream.writeInt(ANGLE_MAJOR_VERSION);
stream.writeInt(ANGLE_MINOR_VERSION);
stream.writeBytes(reinterpret_cast<const unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE);
- stream.writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
{
@@ -444,10 +486,14 @@ Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, G
stream.writeString(mLinkedAttribute[i].name);
stream.writeInt(mProgram->getShaderAttributes()[i].type);
stream.writeString(mProgram->getShaderAttributes()[i].name);
- stream.writeInt(mSemanticIndex[i]);
+ stream.writeInt(mProgram->getSemanticIndexes()[i]);
}
- mProgram->save(&stream);
+ gl::Error error = mProgram->save(&stream);
+ if (error.isError())
+ {
+ return error;
+ }
GLsizei streamLength = stream.length();
const void *streamData = stream.data();
@@ -467,7 +513,7 @@ Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, G
if (binary)
{
- char *ptr = (char*) binary;
+ char *ptr = reinterpret_cast<char*>(binary);
memcpy(ptr, streamData, streamLength);
ptr += streamLength;
@@ -483,10 +529,10 @@ Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, G
return Error(GL_NO_ERROR);
}
-GLint ProgramBinary::getLength()
+GLint Program::getBinaryLength() const
{
GLint length;
- Error error = save(NULL, NULL, INT_MAX, &length);
+ Error error = saveBinary(NULL, NULL, std::numeric_limits<GLint>::max(), &length);
if (error.isError())
{
return 0;
@@ -495,169 +541,742 @@ GLint ProgramBinary::getLength()
return length;
}
-LinkResult ProgramBinary::link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings,
- Shader *fragmentShader, Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings,
- GLenum transformFeedbackBufferMode)
+void Program::release()
{
- if (!fragmentShader || !fragmentShader->isCompiled())
+ mRefCount--;
+
+ if (mRefCount == 0 && mDeleteStatus)
{
- return LinkResult(false, Error(GL_NO_ERROR));
+ mResourceManager->deleteProgram(mHandle);
}
- ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
+}
+
+void Program::addRef()
+{
+ mRefCount++;
+}
- if (!vertexShader || !vertexShader->isCompiled())
+unsigned int Program::getRefCount() const
+{
+ return mRefCount;
+}
+
+int Program::getInfoLogLength() const
+{
+ return mInfoLog.getLength();
+}
+
+void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
+{
+ return mInfoLog.getLog(bufSize, length, infoLog);
+}
+
+void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
+{
+ int total = 0;
+
+ if (mVertexShader)
{
- return LinkResult(false, Error(GL_NO_ERROR));
- }
- ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
+ if (total < maxCount)
+ {
+ shaders[total] = mVertexShader->getHandle();
+ }
- reset();
+ total++;
+ }
- int registers;
- std::vector<LinkedVarying> linkedVaryings;
- LinkResult result = mProgram->link(data, infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, transformFeedbackBufferMode,
- &registers, &linkedVaryings, &mOutputVariables);
- if (result.error.isError() || !result.linkSuccess)
+ if (mFragmentShader)
{
- return result;
+ if (total < maxCount)
+ {
+ shaders[total] = mFragmentShader->getHandle();
+ }
+
+ total++;
}
- if (!linkAttributes(infoLog, attributeBindings, vertexShader))
+ if (count)
{
- return LinkResult(false, Error(GL_NO_ERROR));
+ *count = total;
}
+}
- if (!mProgram->linkUniforms(infoLog, *vertexShader, *fragmentShader, *data.caps))
+GLuint Program::getAttributeLocation(const std::string &name)
+{
+ for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
{
- return LinkResult(false, Error(GL_NO_ERROR));
+ if (mLinkedAttribute[index].name == name)
+ {
+ return index;
+ }
}
- if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, *data.caps))
+ return static_cast<GLuint>(-1);
+}
+
+int Program::getSemanticIndex(int attributeIndex)
+{
+ ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
+
+ return mProgram->getSemanticIndexes()[attributeIndex];
+}
+
+void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+{
+ if (mLinked)
{
- return LinkResult(false, Error(GL_NO_ERROR));
+ // Skip over inactive attributes
+ unsigned int activeAttribute = 0;
+ unsigned int attribute;
+ for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
+ {
+ if (mLinkedAttribute[attribute].name.empty())
+ {
+ continue;
+ }
+
+ if (activeAttribute == index)
+ {
+ break;
+ }
+
+ activeAttribute++;
+ }
+
+ if (bufsize > 0)
+ {
+ const char *string = mLinkedAttribute[attribute].name.c_str();
+
+ strncpy(name, string, bufsize);
+ name[bufsize - 1] = '\0';
+
+ if (length)
+ {
+ *length = strlen(name);
+ }
+ }
+
+ *size = 1; // Always a single 'type' instance
+
+ *type = mLinkedAttribute[attribute].type;
+ }
+ else
+ {
+ if (bufsize > 0)
+ {
+ name[0] = '\0';
+ }
+
+ if (length)
+ {
+ *length = 0;
+ }
+
+ *type = GL_NONE;
+ *size = 1;
}
+}
- if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
- transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps))
+GLint Program::getActiveAttributeCount()
+{
+ int count = 0;
+
+ if (mLinked)
{
- return LinkResult(false, Error(GL_NO_ERROR));
+ for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ if (!mLinkedAttribute[attributeIndex].name.empty())
+ {
+ count++;
+ }
+ }
}
- // TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called,
- // however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling.
- result = mProgram->compileProgramExecutables(infoLog, fragmentShader, vertexShader, registers);
- if (result.error.isError() || !result.linkSuccess)
+ return count;
+}
+
+GLint Program::getActiveAttributeMaxLength()
+{
+ int maxLength = 0;
+
+ if (mLinked)
{
- infoLog.append("Failed to create D3D shaders.");
- reset();
- return result;
+ for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ if (!mLinkedAttribute[attributeIndex].name.empty())
+ {
+ maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength);
+ }
+ }
}
- return LinkResult(true, Error(GL_NO_ERROR));
+ return maxLength;
}
-bool ProgramBinary::linkUniformBlocks(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
- const gl::Caps &caps)
+// Returns one more than the highest sampler index used.
+GLint Program::getUsedSamplerRange(SamplerType type)
{
- const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
- const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
+ return mProgram->getUsedSamplerRange(type);
+}
- // Check that interface blocks defined in the vertex and fragment shaders are identical
- typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap;
- UniformBlockMap linkedUniformBlocks;
+bool Program::usesPointSize() const
+{
+ return mProgram->usesPointSize();
+}
- for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
+GLint Program::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
+{
+ return mProgram->getSamplerMapping(type, samplerIndex, caps);
+}
+
+GLenum Program::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
+{
+ return mProgram->getSamplerTextureType(type, samplerIndex);
+}
+
+GLint Program::getFragDataLocation(const std::string &name) const
+{
+ std::string baseName(name);
+ unsigned int arrayIndex = ParseAndStripArrayIndex(&baseName);
+ for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++)
{
- const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
- linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
+ const VariableLocation &outputVariable = locationIt->second;
+ if (outputVariable.name == baseName && (arrayIndex == GL_INVALID_INDEX || arrayIndex == outputVariable.element))
+ {
+ return static_cast<GLint>(locationIt->first);
+ }
}
+ return -1;
+}
- for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
+void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+{
+ if (mLinked)
{
- const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
- UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
- if (entry != linkedUniformBlocks.end())
+ ASSERT(index < mProgram->getUniforms().size()); // index must be smaller than getActiveUniformCount()
+ LinkedUniform *uniform = mProgram->getUniforms()[index];
+
+ if (bufsize > 0)
{
- const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
- if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
+ std::string string = uniform->name;
+ if (uniform->isArray())
{
- return false;
+ string += "[0]";
+ }
+
+ strncpy(name, string.c_str(), bufsize);
+ name[bufsize - 1] = '\0';
+
+ if (length)
+ {
+ *length = strlen(name);
}
}
+
+ *size = uniform->elementCount();
+ *type = uniform->type;
}
+ else
+ {
+ if (bufsize > 0)
+ {
+ name[0] = '\0';
+ }
- for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
+ if (length)
+ {
+ *length = 0;
+ }
+
+ *size = 0;
+ *type = GL_NONE;
+ }
+}
+
+GLint Program::getActiveUniformCount()
+{
+ if (mLinked)
{
- const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
+ return mProgram->getUniforms().size();
+ }
+ else
+ {
+ return 0;
+ }
+}
- // Note: shared and std140 layouts are always considered active
- if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
+GLint Program::getActiveUniformMaxLength()
+{
+ int maxLength = 0;
+
+ if (mLinked)
+ {
+ unsigned int numUniforms = mProgram->getUniforms().size();
+ for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
{
- if (!mProgram->defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
+ if (!mProgram->getUniforms()[uniformIndex]->name.empty())
{
- return false;
+ int length = (int)(mProgram->getUniforms()[uniformIndex]->name.length() + 1);
+ if (mProgram->getUniforms()[uniformIndex]->isArray())
+ {
+ length += 3; // Counting in "[0]".
+ }
+ maxLength = std::max(length, maxLength);
}
}
}
- for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
+ return maxLength;
+}
+
+GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
+{
+ const gl::LinkedUniform& uniform = *mProgram->getUniforms()[index];
+ switch (pname)
{
- const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
+ case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type);
+ case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.elementCount());
+ case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
+ case GL_UNIFORM_BLOCK_INDEX: return uniform.blockIndex;
+ case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset;
+ case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
+ case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
+ case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return 0;
+}
- // Note: shared and std140 layouts are always considered active
- if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
+bool Program::isValidUniformLocation(GLint location) const
+{
+ ASSERT(rx::IsIntegerCastSafe<GLint>(mProgram->getUniformIndices().size()));
+ return (location >= 0 && location < static_cast<GLint>(mProgram->getUniformIndices().size()));
+}
+
+LinkedUniform *Program::getUniformByLocation(GLint location) const
+{
+ return mProgram->getUniformByLocation(location);
+}
+
+LinkedUniform *Program::getUniformByName(const std::string &name) const
+{
+ return mProgram->getUniformByName(name);
+}
+
+GLint Program::getUniformLocation(const std::string &name)
+{
+ return mProgram->getUniformLocation(name);
+}
+
+GLuint Program::getUniformIndex(const std::string &name)
+{
+ return mProgram->getUniformIndex(name);
+}
+
+void Program::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mProgram->setUniform1fv(location, count, v);
+}
+
+void Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mProgram->setUniform2fv(location, count, v);
+}
+
+void Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mProgram->setUniform3fv(location, count, v);
+}
+
+void Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ mProgram->setUniform4fv(location, count, v);
+}
+
+void Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
+{
+ mProgram->setUniform1iv(location, count, v);
+}
+
+void Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
+{
+ mProgram->setUniform2iv(location, count, v);
+}
+
+void Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
+{
+ mProgram->setUniform3iv(location, count, v);
+}
+
+void Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
+{
+ mProgram->setUniform4iv(location, count, v);
+}
+
+void Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mProgram->setUniform1uiv(location, count, v);
+}
+
+void Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mProgram->setUniform2uiv(location, count, v);
+}
+
+void Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mProgram->setUniform3uiv(location, count, v);
+}
+
+void Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ mProgram->setUniform4uiv(location, count, v);
+}
+
+void Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix2fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix3fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix4fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix2x3fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix2x4fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix3x2fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix3x4fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix4x2fv(location, count, transpose, v);
+}
+
+void Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v)
+{
+ mProgram->setUniformMatrix4x3fv(location, count, transpose, v);
+}
+
+void Program::getUniformfv(GLint location, GLfloat *v)
+{
+ mProgram->getUniformfv(location, v);
+}
+
+void Program::getUniformiv(GLint location, GLint *v)
+{
+ mProgram->getUniformiv(location, v);
+}
+
+void Program::getUniformuiv(GLint location, GLuint *v)
+{
+ mProgram->getUniformuiv(location, v);
+}
+
+// Applies all the uniforms set for this program object to the renderer
+Error Program::applyUniforms()
+{
+ return mProgram->applyUniforms();
+}
+
+Error Program::applyUniformBuffers(const gl::Data &data)
+{
+ return mProgram->applyUniformBuffers(data, mUniformBlockBindings);
+}
+
+void Program::flagForDeletion()
+{
+ mDeleteStatus = true;
+}
+
+bool Program::isFlaggedForDeletion() const
+{
+ return mDeleteStatus;
+}
+
+void Program::validate(const Caps &caps)
+{
+ mInfoLog.reset();
+ mValidated = false;
+
+ if (mLinked)
+ {
+ applyUniforms();
+ mValidated = mProgram->validateSamplers(&mInfoLog, caps);
+ }
+ else
+ {
+ mInfoLog.append("Program has not been successfully linked.");
+ }
+}
+
+bool Program::validateSamplers(InfoLog *infoLog, const Caps &caps)
+{
+ return mProgram->validateSamplers(infoLog, caps);
+}
+
+bool Program::isValidated() const
+{
+ return mValidated;
+}
+
+void Program::updateSamplerMapping()
+{
+ return mProgram->updateSamplerMapping();
+}
+
+GLuint Program::getActiveUniformBlockCount()
+{
+ return mProgram->getUniformBlocks().size();
+}
+
+void Program::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const
+{
+ ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
+
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
+
+ if (bufSize > 0)
+ {
+ std::string string = uniformBlock.name;
+
+ if (uniformBlock.isArrayElement())
{
- if (!mProgram->defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
+ string += ArrayString(uniformBlock.elementIndex);
+ }
+
+ strncpy(uniformBlockName, string.c_str(), bufSize);
+ uniformBlockName[bufSize - 1] = '\0';
+
+ if (length)
+ {
+ *length = strlen(uniformBlockName);
+ }
+ }
+}
+
+void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
+{
+ ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
+
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
+
+ switch (pname)
+ {
+ case GL_UNIFORM_BLOCK_DATA_SIZE:
+ *params = static_cast<GLint>(uniformBlock.dataSize);
+ break;
+ case GL_UNIFORM_BLOCK_NAME_LENGTH:
+ *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));
+ break;
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+ *params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());
+ break;
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+ {
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
{
- return false;
+ params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]);
}
}
+ break;
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+ *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());
+ break;
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+ *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());
+ break;
+ default: UNREACHABLE();
}
+}
- return true;
+GLint Program::getActiveUniformBlockMaxLength()
+{
+ int maxLength = 0;
+
+ if (mLinked)
+ {
+ unsigned int numUniformBlocks = mProgram->getUniformBlocks().size();
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
+ {
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
+ if (!uniformBlock.name.empty())
+ {
+ const int length = uniformBlock.name.length() + 1;
+
+ // Counting in "[0]".
+ const int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);
+
+ maxLength = std::max(length + arrayLength, maxLength);
+ }
+ }
+ }
+
+ return maxLength;
}
-bool ProgramBinary::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
- const sh::InterfaceBlock &fragmentInterfaceBlock)
+GLuint Program::getUniformBlockIndex(const std::string &name)
{
- const char* blockName = vertexInterfaceBlock.name.c_str();
+ return mProgram->getUniformBlockIndex(name);
+}
- // validate blocks for the same member types
- if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size())
+const UniformBlock *Program::getUniformBlockByIndex(GLuint index) const
+{
+ return mProgram->getUniformBlockByIndex(index);
+}
+
+void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+{
+ mUniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
+}
+
+GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
+{
+ return mUniformBlockBindings[uniformBlockIndex];
+}
+
+void Program::resetUniformBlockBindings()
+{
+ for (unsigned int blockId = 0; blockId < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; blockId++)
{
- infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName);
- return false;
+ mUniformBlockBindings[blockId] = 0;
}
+}
- if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize)
+void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)
+{
+ mTransformFeedbackVaryings.resize(count);
+ for (GLsizei i = 0; i < count; i++)
{
- infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName);
- return false;
+ mTransformFeedbackVaryings[i] = varyings[i];
}
- if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout)
+ mTransformFeedbackBufferMode = bufferMode;
+}
+
+void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const
+{
+ if (mLinked)
{
- infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName);
- return false;
+ ASSERT(index < mProgram->getTransformFeedbackLinkedVaryings().size());
+ const LinkedVarying &varying = mProgram->getTransformFeedbackLinkedVaryings()[index];
+ GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
+ if (length)
+ {
+ *length = lastNameIdx;
+ }
+ if (size)
+ {
+ *size = varying.size;
+ }
+ if (type)
+ {
+ *type = varying.type;
+ }
+ if (name)
+ {
+ memcpy(name, varying.name.c_str(), lastNameIdx);
+ name[lastNameIdx] = '\0';
+ }
}
+}
- const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size();
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
+GLsizei Program::getTransformFeedbackVaryingCount() const
+{
+ if (mLinked)
{
- const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex];
- const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
+ return static_cast<GLsizei>(mProgram->getTransformFeedbackLinkedVaryings().size());
+ }
+ else
+ {
+ return 0;
+ }
+}
- if (vertexMember.name != fragmentMember.name)
+GLsizei Program::getTransformFeedbackVaryingMaxLength() const
+{
+ if (mLinked)
+ {
+ GLsizei maxSize = 0;
+ for (size_t i = 0; i < mProgram->getTransformFeedbackLinkedVaryings().size(); i++)
{
- infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')",
- blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str());
- return false;
+ const LinkedVarying &varying = mProgram->getTransformFeedbackLinkedVaryings()[i];
+ maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
}
- std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
- if (!gl::ProgramBinary::linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
+ return maxSize;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+GLenum Program::getTransformFeedbackBufferMode() const
+{
+ return mTransformFeedbackBufferMode;
+}
+
+bool Program::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
+{
+ std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
+ std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
+
+ for (size_t fragVaryingIndex = 0; fragVaryingIndex < fragmentVaryings.size(); fragVaryingIndex++)
+ {
+ PackedVarying *input = &fragmentVaryings[fragVaryingIndex];
+ bool matched = false;
+
+ // Built-in varyings obey special rules
+ if (input->isBuiltIn())
{
+ continue;
+ }
+
+ for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
+ {
+ PackedVarying *output = &vertexVaryings[vertVaryingIndex];
+ if (output->name == input->name)
+ {
+ if (!linkValidateVaryings(infoLog, output->name, *input, *output))
+ {
+ return false;
+ }
+
+ output->registerIndex = input->registerIndex;
+ output->columnIndex = input->columnIndex;
+
+ matched = true;
+ break;
+ }
+ }
+
+ // We permit unmatched, unreferenced varyings
+ if (!matched && input->staticUse)
+ {
+ infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str());
return false;
}
}
@@ -665,11 +1284,25 @@ bool ProgramBinary::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::I
return true;
}
-// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
-bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader)
+bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
{
- const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+ if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
+ {
+ return false;
+ }
+
+ if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout)
+ {
+ infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
+ return false;
+ }
+ return true;
+}
+
+// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
+bool Program::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader)
+{
unsigned int usedLocations = 0;
const std::vector<sh::Attribute> &shaderAttributes = vertexShader->getActiveAttributes();
@@ -744,21 +1377,111 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
{
- int index = vertexShaderD3D->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
+ int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
int rows = VariableRegisterCount(mLinkedAttribute[attributeIndex].type);
for (int r = 0; r < rows; r++)
{
- mSemanticIndex[attributeIndex++] = index++;
+ mProgram->getSemanticIndexes()[attributeIndex++] = index++;
}
}
- initAttributesByLayout();
+ return true;
+}
+bool Program::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
+{
+ const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
+ const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
+ // Check that interface blocks defined in the vertex and fragment shaders are identical
+ typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap;
+ UniformBlockMap linkedUniformBlocks;
+ for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
+ {
+ const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
+ linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
+ }
+ for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
+ {
+ const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
+ UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
+ if (entry != linkedUniformBlocks.end())
+ {
+ const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
+ if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
+ {
+ return false;
+ }
+ }
+ }
+ for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
+ {
+ const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
+ // Note: shared and std140 layouts are always considered active
+ if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
+ {
+ if (!mProgram->defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
+ {
+ return false;
+ }
+ }
+ }
+ for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
+ {
+ const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
+ // Note: shared and std140 layouts are always considered active
+ if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
+ {
+ if (!mProgram->defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
+ {
+ return false;
+ }
+ }
+ }
return true;
}
-bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable,
+bool Program::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
+ const sh::InterfaceBlock &fragmentInterfaceBlock)
+{
+ const char* blockName = vertexInterfaceBlock.name.c_str();
+ // validate blocks for the same member types
+ if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size())
+ {
+ infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName);
+ return false;
+ }
+ if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize)
+ {
+ infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName);
+ return false;
+ }
+ if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout)
+ {
+ infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName);
+ return false;
+ }
+ const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size();
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
+ {
+ const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex];
+ const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex];
+ if (vertexMember.name != fragmentMember.name)
+ {
+ infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')",
+ blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str());
+ return false;
+ }
+ std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
+ if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, const sh::ShaderVariable &vertexVariable,
const sh::ShaderVariable &fragmentVariable, bool validatePrecision)
{
if (vertexVariable.type != fragmentVariable.type)
@@ -808,7 +1531,7 @@ bool ProgramBinary::linkValidateVariablesBase(InfoLog &infoLog, const std::strin
return true;
}
-bool ProgramBinary::linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
+bool Program::linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform)
{
if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
{
@@ -818,14 +1541,14 @@ bool ProgramBinary::linkValidateUniforms(InfoLog &infoLog, const std::string &un
return true;
}
-bool ProgramBinary::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying)
+bool Program::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying)
{
if (!linkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false))
{
return false;
}
- if (vertexVarying.interpolation != fragmentVarying.interpolation)
+ if (!sh::InterpolationTypesMatch(vertexVarying.interpolation, fragmentVarying.interpolation))
{
infoLog.append("Interpolation types for %s differ between vertex and fragment shaders", varyingName.c_str());
return false;
@@ -834,27 +1557,11 @@ bool ProgramBinary::linkValidateVaryings(InfoLog &infoLog, const std::string &va
return true;
}
-bool ProgramBinary::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform)
-{
- if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true))
- {
- return false;
- }
-
- if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout)
- {
- infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str());
- return false;
- }
-
- return true;
-}
-
-bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
- const std::vector<std::string> &transformFeedbackVaryingNames,
- GLenum transformFeedbackBufferMode,
- std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
- const Caps &caps) const
+bool Program::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
+ const std::vector<std::string> &transformFeedbackVaryingNames,
+ GLenum transformFeedbackBufferMode,
+ std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
+ const Caps &caps) const
{
size_t totalComponents = 0;
@@ -907,327 +1614,4 @@ bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, cons
return true;
}
-bool ProgramBinary::isValidated() const
-{
- return mValidated;
-}
-
-void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
-{
- // Skip over inactive attributes
- unsigned int activeAttribute = 0;
- unsigned int attribute;
- for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
- {
- if (mLinkedAttribute[attribute].name.empty())
- {
- continue;
- }
-
- if (activeAttribute == index)
- {
- break;
- }
-
- activeAttribute++;
- }
-
- if (bufsize > 0)
- {
- const char *string = mLinkedAttribute[attribute].name.c_str();
-
- strncpy(name, string, bufsize);
- name[bufsize - 1] = '\0';
-
- if (length)
- {
- *length = strlen(name);
- }
- }
-
- *size = 1; // Always a single 'type' instance
-
- *type = mLinkedAttribute[attribute].type;
-}
-
-GLint ProgramBinary::getActiveAttributeCount() const
-{
- int count = 0;
-
- for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- if (!mLinkedAttribute[attributeIndex].name.empty())
- {
- count++;
- }
- }
-
- return count;
-}
-
-GLint ProgramBinary::getActiveAttributeMaxLength() const
-{
- int maxLength = 0;
-
- for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- if (!mLinkedAttribute[attributeIndex].name.empty())
- {
- maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength);
- }
- }
-
- return maxLength;
-}
-
-void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
-{
- ASSERT(index < mProgram->getUniforms().size()); // index must be smaller than getActiveUniformCount()
-
- if (bufsize > 0)
- {
- std::string string = mProgram->getUniforms()[index]->name;
-
- if (mProgram->getUniforms()[index]->isArray())
- {
- string += "[0]";
- }
-
- strncpy(name, string.c_str(), bufsize);
- name[bufsize - 1] = '\0';
-
- if (length)
- {
- *length = strlen(name);
- }
- }
-
- *size = mProgram->getUniforms()[index]->elementCount();
-
- *type = mProgram->getUniforms()[index]->type;
-}
-
-GLint ProgramBinary::getActiveUniformCount() const
-{
- return mProgram->getUniforms().size();
-}
-
-GLint ProgramBinary::getActiveUniformMaxLength() const
-{
- int maxLength = 0;
-
- unsigned int numUniforms = mProgram->getUniforms().size();
- for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
- {
- if (!mProgram->getUniforms()[uniformIndex]->name.empty())
- {
- int length = (int)(mProgram->getUniforms()[uniformIndex]->name.length() + 1);
- if (mProgram->getUniforms()[uniformIndex]->isArray())
- {
- length += 3; // Counting in "[0]".
- }
- maxLength = std::max(length, maxLength);
- }
- }
-
- return maxLength;
-}
-
-GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const
-{
- const gl::LinkedUniform& uniform = *mProgram->getUniforms()[index];
-
- switch (pname)
- {
- case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type);
- case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.elementCount());
- case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
- case GL_UNIFORM_BLOCK_INDEX: return uniform.blockIndex;
-
- case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset;
- case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
- case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
- case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
-
- default:
- UNREACHABLE();
- break;
- }
- return 0;
-}
-
-bool ProgramBinary::isValidUniformLocation(GLint location) const
-{
- ASSERT(rx::IsIntegerCastSafe<GLint>(mProgram->getUniformIndices().size()));
- return (location >= 0 && location < static_cast<GLint>(mProgram->getUniformIndices().size()));
-}
-
-LinkedUniform *ProgramBinary::getUniformByLocation(GLint location) const
-{
- return mProgram->getUniformByLocation(location);
-}
-
-LinkedUniform *ProgramBinary::getUniformByName(const std::string &name) const
-{
- return mProgram->getUniformByName(name);
-}
-
-void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const
-{
- ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
-
- const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
-
- if (bufSize > 0)
- {
- std::string string = uniformBlock.name;
-
- if (uniformBlock.isArrayElement())
- {
- string += ArrayString(uniformBlock.elementIndex);
- }
-
- strncpy(uniformBlockName, string.c_str(), bufSize);
- uniformBlockName[bufSize - 1] = '\0';
-
- if (length)
- {
- *length = strlen(uniformBlockName);
- }
- }
-}
-
-void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
-{
- ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
-
- const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
-
- switch (pname)
- {
- case GL_UNIFORM_BLOCK_DATA_SIZE:
- *params = static_cast<GLint>(uniformBlock.dataSize);
- break;
- case GL_UNIFORM_BLOCK_NAME_LENGTH:
- *params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));
- break;
- case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
- *params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());
- break;
- case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
- {
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
- {
- params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]);
- }
- }
- break;
- case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
- *params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());
- break;
- case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
- *params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());
- break;
- default: UNREACHABLE();
- }
-}
-
-GLuint ProgramBinary::getActiveUniformBlockCount() const
-{
- return mProgram->getUniformBlocks().size();
-}
-
-GLuint ProgramBinary::getActiveUniformBlockMaxLength() const
-{
- unsigned int maxLength = 0;
-
- unsigned int numUniformBlocks = mProgram->getUniformBlocks().size();
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
- {
- const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
- if (!uniformBlock.name.empty())
- {
- const unsigned int length = uniformBlock.name.length() + 1;
-
- // Counting in "[0]".
- const unsigned int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);
-
- maxLength = std::max(length + arrayLength, maxLength);
- }
- }
-
- return maxLength;
-}
-
-void ProgramBinary::validate(InfoLog &infoLog, const Caps &caps)
-{
- applyUniforms();
- if (!validateSamplers(&infoLog, caps))
- {
- mValidated = false;
- }
- else
- {
- mValidated = true;
- }
-}
-
-bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
-{
- return mProgram->validateSamplers(infoLog, caps);
-}
-
-struct AttributeSorter
-{
- AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS])
- : originalIndices(semanticIndices)
- {
- }
-
- bool operator()(int a, int b)
- {
- if (originalIndices[a] == -1) return false;
- if (originalIndices[b] == -1) return true;
- return (originalIndices[a] < originalIndices[b]);
- }
-
- const int (&originalIndices)[MAX_VERTEX_ATTRIBS];
-};
-
-void ProgramBinary::initAttributesByLayout()
-{
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- mAttributesByLayout[i] = i;
- }
-
- std::sort(&mAttributesByLayout[0], &mAttributesByLayout[MAX_VERTEX_ATTRIBS], AttributeSorter(mSemanticIndex));
-}
-
-void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const
-{
- rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS];
-
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- oldTranslatedAttributes[i] = attributes[i];
- }
-
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- int oldIndex = mAttributesByLayout[i];
- sortedSemanticIndices[i] = oldIndex;
- attributes[i] = oldTranslatedAttributes[oldIndex];
- }
-}
-
-void ProgramBinary::reset()
-{
- mOutputVariables.clear();
-
- mProgram->reset();
-
- mValidated = false;
-}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h b/src/3rdparty/angle/src/libANGLE/Program.h
index 3142d66c6d..38fc83d29d 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
+++ b/src/3rdparty/angle/src/libANGLE/Program.h
@@ -7,60 +7,79 @@
// 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 LIBGLESV2_PROGRAM_BINARY_H_
-#define LIBGLESV2_PROGRAM_BINARY_H_
+#ifndef LIBANGLE_PROGRAM_H_
+#define LIBANGLE_PROGRAM_H_
-#include "common/RefCountObject.h"
-#include "angletypes.h"
-#include "common/mathutil.h"
-#include "libGLESv2/Uniform.h"
-#include "libGLESv2/Shader.h"
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/renderer/d3d/VertexDataManager.h"
-#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
-#include "angle_gl.h"
+#include "common/angleutils.h"
-#include <string>
-#include <vector>
-
-namespace sh
-{
-class HLSLBlockEncoder;
-}
-
-#include <GLES3/gl3.h>
#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
+#include <GLSLANG/ShaderLang.h>
-#include <string>
#include <vector>
+#include <string>
+#include <set>
namespace rx
{
-class ShaderExecutable;
+class Renderer;
+class Renderer;
struct TranslatedAttribute;
-class UniformStorage;
class ProgramImpl;
}
namespace gl
{
struct Caps;
+struct Data;
+class ResourceManager;
class Shader;
class InfoLog;
class AttributeBindings;
class Buffer;
class Framebuffer;
-struct Data;
+struct UniformBlock;
+struct LinkedUniform;
+
+extern const char * const g_fakepath;
+
+class AttributeBindings
+{
+ public:
+ AttributeBindings();
+ ~AttributeBindings();
+
+ void bindAttributeLocation(GLuint index, const char *name);
+ int getAttributeBinding(const std::string &name) const;
+
+ private:
+ std::set<std::string> mAttributeBinding[MAX_VERTEX_ATTRIBS];
+};
+
+class InfoLog : angle::NonCopyable
+{
+ public:
+ InfoLog();
+ ~InfoLog();
+
+ int getLength() const;
+ void getLog(GLsizei bufSize, GLsizei *length, char *infoLog);
+
+ void appendSanitized(const char *message);
+ void append(const char *info, ...);
+ void reset();
+ private:
+ char *mInfoLog;
+};
// Struct used for correlating uniforms/elements of uniform arrays to handles
struct VariableLocation
{
- VariableLocation()
- {
- }
-
+ VariableLocation();
VariableLocation(const std::string &name, unsigned int element, unsigned int index);
std::string name;
@@ -72,7 +91,7 @@ struct LinkedVarying
{
LinkedVarying();
LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName,
- unsigned int semanticIndex, unsigned int semanticIndexCount);
+ unsigned int semanticIndex, unsigned int semanticIndexCount);
// Original GL name
std::string name;
@@ -86,35 +105,58 @@ struct LinkedVarying
unsigned int semanticIndexCount;
};
-struct LinkResult
-{
- bool linkSuccess;
- Error error;
-
- LinkResult(bool linkSuccess, const Error &error);
-};
-
-// This is the result of linking a program. It is the state that would be passed to ProgramBinary.
-class ProgramBinary : public RefCountObject
+class Program : angle::NonCopyable
{
public:
- explicit ProgramBinary(rx::ProgramImpl *impl);
- ~ProgramBinary();
+ Program(rx::ProgramImpl *impl, ResourceManager *manager, GLuint handle);
+ ~Program();
+
+ GLuint id() const { return mHandle; }
rx::ProgramImpl *getImplementation() { return mProgram; }
const rx::ProgramImpl *getImplementation() const { return mProgram; }
- GLuint getAttributeLocation(const char *name);
+ bool attachShader(Shader *shader);
+ bool detachShader(Shader *shader);
+ int getAttachedShadersCount() const;
+
+ void bindAttributeLocation(GLuint index, const char *name);
+
+ Error link(const Data &data);
+ bool isLinked();
+
+ Error loadBinary(GLenum binaryFormat, const void *binary, GLsizei length);
+ Error saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) const;
+ GLint getBinaryLength() const;
+
+ int getInfoLogLength() const;
+ void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
+ void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
+
+ GLuint getAttributeLocation(const std::string &name);
int getSemanticIndex(int attributeIndex);
+ void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+ GLint getActiveAttributeCount();
+ GLint getActiveAttributeMaxLength();
+
GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps);
GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLint getUsedSamplerRange(SamplerType type);
bool usesPointSize() const;
- GLint getUniformLocation(std::string name);
- GLuint getUniformIndex(std::string name);
- GLuint getUniformBlockIndex(std::string name);
+ GLint getFragDataLocation(const std::string &name) const;
+
+ void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+ GLint getActiveUniformCount();
+ GLint getActiveUniformMaxLength();
+ GLint getActiveUniformi(GLuint index, GLenum pname) const;
+ bool isValidUniformLocation(GLint location) const;
+ LinkedUniform *getUniformByLocation(GLint location) const;
+ LinkedUniform *getUniformByName(const std::string &name) const;
+
+ GLint getUniformLocation(const std::string &name);
+ GLuint getUniformIndex(const std::string &name);
void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
@@ -142,59 +184,44 @@ class ProgramBinary : public RefCountObject
void getUniformuiv(GLint location, GLuint *params);
Error applyUniforms();
- Error applyUniformBuffers(const std::vector<Buffer*> boundBuffers, const Caps &caps);
-
- LinkResult load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
- Error save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
- GLint getLength();
-
- LinkResult link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings,
- Shader *fragmentShader, Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings,
- GLenum transformFeedbackBufferMode);
-
- void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
- GLint getActiveAttributeCount() const;
- GLint getActiveAttributeMaxLength() const;
-
- void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
- GLint getActiveUniformCount() const;
- GLint getActiveUniformMaxLength() const;
- GLint getActiveUniformi(GLuint index, GLenum pname) const;
- bool isValidUniformLocation(GLint location) const;
- LinkedUniform *getUniformByLocation(GLint location) const;
- LinkedUniform *getUniformByName(const std::string &name) const;
+ Error applyUniformBuffers(const gl::Data &data);
void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const;
void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const;
- GLuint getActiveUniformBlockCount() const;
- GLuint getActiveUniformBlockMaxLength() const;
- UniformBlock *getUniformBlockByIndex(GLuint blockIndex);
+ GLuint getActiveUniformBlockCount();
+ GLint getActiveUniformBlockMaxLength();
- GLint getFragDataLocation(const char *name) const;
-
- size_t getTransformFeedbackVaryingCount() const;
- const LinkedVarying &getTransformFeedbackVarying(size_t idx) const;
- GLenum getTransformFeedbackBufferMode() const;
+ GLuint getUniformBlockIndex(const std::string &name);
- void validate(InfoLog &infoLog, const Caps &caps);
- bool validateSamplers(InfoLog *infoLog, const Caps &caps);
- bool isValidated() const;
- void updateSamplerMapping();
+ void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+ GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
- unsigned int getSerial() const;
+ const UniformBlock *getUniformBlockByIndex(GLuint index) const;
- void initAttributesByLayout();
- void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) 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;
static bool linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader);
static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
- private:
- DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
+ void addRef();
+ void release();
+ unsigned int getRefCount() const;
+ void flagForDeletion();
+ bool isFlaggedForDeletion() const;
- void reset();
+ void validate(const Caps &caps);
+ bool validateSamplers(InfoLog *infoLog, const Caps &caps);
+ bool isValidated() const;
+ void updateSamplerMapping();
+
+ private:
+ void unlink(bool destroy = false);
+ void resetUniformBlockBindings();
bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader);
bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
@@ -219,19 +246,31 @@ class ProgramBinary : public RefCountObject
rx::ProgramImpl *mProgram;
sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
- int mSemanticIndex[MAX_VERTEX_ATTRIBS];
- int mAttributesByLayout[MAX_VERTEX_ATTRIBS];
std::map<int, VariableLocation> mOutputVariables;
bool mValidated;
- const unsigned int mSerial;
+ Shader *mFragmentShader;
+ Shader *mVertexShader;
- static unsigned int issueSerial();
- static unsigned int mCurrentSerial;
-};
+ AttributeBindings mAttributeBindings;
+
+ GLuint mUniformBlockBindings[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
+
+ std::vector<std::string> mTransformFeedbackVaryings;
+ GLenum mTransformFeedbackBufferMode;
+ bool mLinked;
+ bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use
+
+ unsigned int mRefCount;
+
+ ResourceManager *mResourceManager;
+ const GLuint mHandle;
+
+ InfoLog mInfoLog;
+};
}
-#endif // LIBGLESV2_PROGRAM_BINARY_H_
+#endif // LIBANGLE_PROGRAM_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Query.cpp b/src/3rdparty/angle/src/libANGLE/Query.cpp
index 4ee3525509..a402b732bf 100644
--- a/src/3rdparty/angle/src/libGLESv2/Query.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Query.cpp
@@ -6,8 +6,8 @@
// Query.cpp: Implements the gl::Query class
-#include "libGLESv2/Query.h"
-#include "libGLESv2/renderer/QueryImpl.h"
+#include "libANGLE/Query.h"
+#include "libANGLE/renderer/QueryImpl.h"
namespace gl
{
diff --git a/src/3rdparty/angle/src/libGLESv2/Query.h b/src/3rdparty/angle/src/libANGLE/Query.h
index a7ec404f85..8585fde0e2 100644
--- a/src/3rdparty/angle/src/libGLESv2/Query.h
+++ b/src/3rdparty/angle/src/libANGLE/Query.h
@@ -6,12 +6,13 @@
// Query.h: Defines the gl::Query class
-#ifndef LIBGLESV2_QUERY_H_
-#define LIBGLESV2_QUERY_H_
+#ifndef LIBANGLE_QUERY_H_
+#define LIBANGLE_QUERY_H_
+
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
-#include "libGLESv2/Error.h"
#include "common/angleutils.h"
-#include "common/RefCountObject.h"
#include "angle_gl.h"
@@ -38,11 +39,9 @@ class Query : public RefCountObject
GLenum getType() const;
private:
- DISALLOW_COPY_AND_ASSIGN(Query);
-
rx::QueryImpl *mQuery;
};
}
-#endif // LIBGLESV2_QUERY_H_
+#endif // LIBANGLE_QUERY_H_
diff --git a/src/3rdparty/angle/src/common/RefCountObject.cpp b/src/3rdparty/angle/src/libANGLE/RefCountObject.cpp
index c1ef90cdcc..b1210200cf 100644
--- a/src/3rdparty/angle/src/common/RefCountObject.cpp
+++ b/src/3rdparty/angle/src/libANGLE/RefCountObject.cpp
@@ -12,9 +12,9 @@
#include "RefCountObject.h"
RefCountObject::RefCountObject(GLuint id)
+ : mId(id),
+ mRefCount(0)
{
- mId = id;
- mRefCount = 0;
}
RefCountObject::~RefCountObject()
@@ -37,11 +37,3 @@ void RefCountObject::release() const
}
}
-void RefCountObjectBindingPointer::set(RefCountObject *newObject)
-{
- // addRef first in case newObject == mObject and this is the last reference to it.
- if (newObject != NULL) newObject->addRef();
- if (mObject != NULL) mObject->release();
-
- mObject = newObject;
-}
diff --git a/src/3rdparty/angle/src/libANGLE/RefCountObject.h b/src/3rdparty/angle/src/libANGLE/RefCountObject.h
new file mode 100644
index 0000000000..48c0338c3f
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/RefCountObject.h
@@ -0,0 +1,110 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// 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 "common/debug.h"
+
+#include "angle_gl.h"
+
+#include <cstddef>
+
+class RefCountObject : angle::NonCopyable
+{
+ public:
+ explicit RefCountObject(GLuint id);
+ virtual ~RefCountObject();
+
+ virtual void addRef() const;
+ virtual void release() const;
+
+ GLuint id() const { return mId; }
+
+ private:
+ GLuint mId;
+
+ mutable std::size_t mRefCount;
+};
+
+template <class ObjectType>
+class BindingPointer
+{
+public:
+ BindingPointer()
+ : mObject(nullptr)
+ {
+ }
+
+ BindingPointer(const BindingPointer<ObjectType> &other)
+ : mObject(nullptr)
+ {
+ set(other.mObject);
+ }
+
+ void operator=(const BindingPointer<ObjectType> &other)
+ {
+ set(other.mObject);
+ }
+
+ virtual ~BindingPointer()
+ {
+ // Objects have to be released before the resource manager is destroyed, so they must be explicitly cleaned up.
+ ASSERT(mObject == nullptr);
+ }
+
+ virtual void set(ObjectType *newObject)
+ {
+ // addRef first in case newObject == mObject and this is the last reference to it.
+ if (newObject != nullptr) reinterpret_cast<const RefCountObject*>(newObject)->addRef();
+ if (mObject != nullptr) reinterpret_cast<const RefCountObject*>(mObject)->release();
+ mObject = newObject;
+ }
+
+ ObjectType *get() const { return mObject; }
+ ObjectType *operator->() const { return mObject; }
+
+ GLuint id() const { return (mObject != nullptr) ? mObject->id() : 0; }
+ bool operator!() const { return (mObject == nullptr); }
+
+ private:
+ ObjectType *mObject;
+};
+
+template <class ObjectType>
+class OffsetBindingPointer : public BindingPointer<ObjectType>
+{
+ public:
+ OffsetBindingPointer() : mOffset(0), mSize(0) { }
+
+ void set(ObjectType *newObject) override
+ {
+ BindingPointer<ObjectType>::set(newObject);
+ mOffset = 0;
+ mSize = 0;
+ }
+
+ void set(ObjectType *newObject, GLintptr offset, GLsizeiptr size)
+ {
+ BindingPointer<ObjectType>::set(newObject);
+ mOffset = offset;
+ mSize = size;
+ }
+
+ GLintptr getOffset() const { return mOffset; }
+ GLsizeiptr getSize() const { return mSize; }
+
+ private:
+ GLintptr mOffset;
+ GLsizeiptr mSize;
+};
+
+#endif // LIBANGLE_REFCOUNTOBJECT_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp b/src/3rdparty/angle/src/libANGLE/Renderbuffer.cpp
index 911a389dfa..6a0cde812b 100644
--- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Renderbuffer.cpp
@@ -8,29 +8,25 @@
// GL renderbuffer objects and related functionality.
// [OpenGL ES 2.0.24] section 4.4.3 page 108.
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
-#include "libGLESv2/renderer/RenderTarget.h"
-#include "libGLESv2/renderer/RenderbufferImpl.h"
+#include "libANGLE/Renderbuffer.h"
#include "common/utilities.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/RenderbufferImpl.h"
namespace gl
{
Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id)
: RefCountObject(id),
- mRenderbuffer(impl)
+ mRenderbuffer(impl),
+ mWidth(0),
+ mHeight(0),
+ mInternalFormat(GL_RGBA4),
+ mSamples(0)
{
- ASSERT(mRenderbuffer);
-
- mWidth = mRenderbuffer->getWidth();
- mHeight = mRenderbuffer->getHeight();
- mInternalFormat = mRenderbuffer->getInternalFormat();
- mActualFormat = mRenderbuffer->getActualFormat();
- mSamples = mRenderbuffer->getSamples();
}
Renderbuffer::~Renderbuffer()
@@ -38,9 +34,25 @@ Renderbuffer::~Renderbuffer()
SafeDelete(mRenderbuffer);
}
-Error Renderbuffer::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
+Error Renderbuffer::setStorage(GLenum internalformat, size_t width, size_t height)
+{
+ Error error = mRenderbuffer->setStorage(internalformat, width, height);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mWidth = width;
+ mHeight = height;
+ mInternalFormat = internalformat;
+ mSamples = 0;
+
+ return Error(GL_NO_ERROR);
+}
+
+Error Renderbuffer::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height)
{
- Error error = mRenderbuffer->setStorage(width, height, internalformat, samples);
+ Error error = mRenderbuffer->setStorageMultisample(samples, internalformat, width, height);
if (error.isError())
{
return error;
@@ -50,7 +62,6 @@ Error Renderbuffer::setStorage(GLsizei width, GLsizei height, GLenum internalfor
mHeight = height;
mInternalFormat = internalformat;
mSamples = samples;
- mActualFormat = mRenderbuffer->getActualFormat();
return Error(GL_NO_ERROR);
}
@@ -61,6 +72,11 @@ rx::RenderbufferImpl *Renderbuffer::getImplementation()
return mRenderbuffer;
}
+const rx::RenderbufferImpl *Renderbuffer::getImplementation() const
+{
+ return mRenderbuffer;
+}
+
GLsizei Renderbuffer::getWidth() const
{
return mWidth;
@@ -76,11 +92,6 @@ GLenum Renderbuffer::getInternalFormat() const
return mInternalFormat;
}
-GLenum Renderbuffer::getActualFormat() const
-{
- return mActualFormat;
-}
-
GLsizei Renderbuffer::getSamples() const
{
return mSamples;
@@ -88,32 +99,32 @@ GLsizei Renderbuffer::getSamples() const
GLuint Renderbuffer::getRedSize() const
{
- return GetInternalFormatInfo(getActualFormat()).redBits;
+ return GetInternalFormatInfo(mInternalFormat).redBits;
}
GLuint Renderbuffer::getGreenSize() const
{
- return GetInternalFormatInfo(getActualFormat()).greenBits;
+ return GetInternalFormatInfo(mInternalFormat).greenBits;
}
GLuint Renderbuffer::getBlueSize() const
{
- return GetInternalFormatInfo(getActualFormat()).blueBits;
+ return GetInternalFormatInfo(mInternalFormat).blueBits;
}
GLuint Renderbuffer::getAlphaSize() const
{
- return GetInternalFormatInfo(getActualFormat()).alphaBits;
+ return GetInternalFormatInfo(mInternalFormat).alphaBits;
}
GLuint Renderbuffer::getDepthSize() const
{
- return GetInternalFormatInfo(getActualFormat()).depthBits;
+ return GetInternalFormatInfo(mInternalFormat).depthBits;
}
GLuint Renderbuffer::getStencilSize() const
{
- return GetInternalFormatInfo(getActualFormat()).stencilBits;
+ return GetInternalFormatInfo(mInternalFormat).stencilBits;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h b/src/3rdparty/angle/src/libANGLE/Renderbuffer.h
index e9f12af3ce..98c7eb0f10 100644
--- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
+++ b/src/3rdparty/angle/src/libANGLE/Renderbuffer.h
@@ -8,15 +8,15 @@
// Implements GL renderbuffer objects and related functionality.
// [OpenGL ES 2.0.24] section 4.4.3 page 108.
-#ifndef LIBGLESV2_RENDERBUFFER_H_
-#define LIBGLESV2_RENDERBUFFER_H_
+#ifndef LIBANGLE_RENDERBUFFER_H_
+#define LIBANGLE_RENDERBUFFER_H_
#include "angle_gl.h"
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
#include "common/angleutils.h"
-#include "common/RefCountObject.h"
namespace rx
{
@@ -38,14 +38,15 @@ class Renderbuffer : public RefCountObject
Renderbuffer(rx::RenderbufferImpl *impl, GLuint id);
virtual ~Renderbuffer();
- Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
+ Error setStorage(GLenum internalformat, size_t width, size_t height);
+ Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height);
rx::RenderbufferImpl *getImplementation();
+ const rx::RenderbufferImpl *getImplementation() const;
GLsizei getWidth() const;
GLsizei getHeight() const;
GLenum getInternalFormat() const;
- GLenum getActualFormat() const;
GLsizei getSamples() const;
GLuint getRedSize() const;
GLuint getGreenSize() const;
@@ -55,17 +56,14 @@ class Renderbuffer : public RefCountObject
GLuint getStencilSize() const;
private:
- DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
-
rx::RenderbufferImpl *mRenderbuffer;
GLsizei mWidth;
GLsizei mHeight;
GLenum mInternalFormat;
- GLenum mActualFormat;
GLsizei mSamples;
};
}
-#endif // LIBGLESV2_RENDERBUFFER_H_
+#endif // LIBANGLE_RENDERBUFFER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp b/src/3rdparty/angle/src/libANGLE/ResourceManager.cpp
index 38d53cad81..aaf144cfa9 100644
--- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
+++ b/src/3rdparty/angle/src/libANGLE/ResourceManager.cpp
@@ -7,21 +7,21 @@
// ResourceManager.cpp: Implements the gl::ResourceManager class, which tracks and
// retrieves objects which may be shared by multiple Contexts.
-#include "libGLESv2/ResourceManager.h"
+#include "libANGLE/ResourceManager.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/Program.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/Shader.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/Sampler.h"
-#include "libGLESv2/Fence.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Sampler.h"
+#include "libANGLE/Fence.h"
+#include "libANGLE/renderer/Renderer.h"
namespace gl
{
-ResourceManager::ResourceManager(rx::Renderer *renderer)
- : mRenderer(renderer),
+ResourceManager::ResourceManager(rx::ImplFactory *factory)
+ : mFactory(factory),
mRefCount(1)
{
}
@@ -94,7 +94,7 @@ GLuint ResourceManager::createShader(const gl::Data &data, GLenum type)
if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
{
- mShaderMap[handle] = new Shader(this, mRenderer->createShader(data, type), type, handle);
+ mShaderMap[handle] = new Shader(this, mFactory->createShader(type), type, handle);
}
else UNREACHABLE();
@@ -106,7 +106,7 @@ GLuint ResourceManager::createProgram()
{
GLuint handle = mProgramShaderHandleAllocator.allocate();
- mProgramMap[handle] = new Program(mRenderer, this, handle);
+ mProgramMap[handle] = new Program(mFactory->createProgram(), this, handle);
return handle;
}
@@ -146,7 +146,7 @@ GLuint ResourceManager::createFenceSync()
{
GLuint handle = mFenceSyncHandleAllocator.allocate();
- FenceSync *fenceSync = new FenceSync(mRenderer->createFenceSync(), handle);
+ FenceSync *fenceSync = new FenceSync(mFactory->createFenceSync(), handle);
fenceSync->addRef();
mFenceSyncMap[handle] = fenceSync;
@@ -356,56 +356,84 @@ void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
mRenderbufferMap[handle] = buffer;
}
-void ResourceManager::checkBufferAllocation(unsigned int buffer)
+void ResourceManager::checkBufferAllocation(GLuint handle)
{
- if (buffer != 0 && !getBuffer(buffer))
+ if (handle != 0)
{
- Buffer *bufferObject = new Buffer(mRenderer->createBuffer(), buffer);
- mBufferMap[buffer] = bufferObject;
- bufferObject->addRef();
- }
-}
+ auto bufferMapIt = mBufferMap.find(handle);
+ bool handleAllocated = (bufferMapIt != mBufferMap.end());
-void ResourceManager::checkTextureAllocation(GLuint texture, GLenum type)
-{
- if (!getTexture(texture) && texture != 0)
- {
- Texture *textureObject;
+ if (handleAllocated && bufferMapIt->second != nullptr)
+ {
+ return;
+ }
+
+ Buffer *buffer = new Buffer(mFactory->createBuffer(), handle);
+ buffer->addRef();
- if (type == GL_TEXTURE_2D)
+ if (handleAllocated)
{
- textureObject = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), texture);
+ bufferMapIt->second = buffer;
}
- else if (type == GL_TEXTURE_CUBE_MAP)
+ else
{
- textureObject = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), texture);
+ mBufferHandleAllocator.reserve(handle);
+ mBufferMap[handle] = buffer;
}
- else if (type == GL_TEXTURE_3D)
+ }
+}
+
+void ResourceManager::checkTextureAllocation(GLuint handle, GLenum type)
+{
+ if (handle != 0)
+ {
+ auto textureMapIt = mTextureMap.find(handle);
+ bool handleAllocated = (textureMapIt != mTextureMap.end());
+
+ if (handleAllocated && textureMapIt->second != nullptr)
{
- textureObject = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), texture);
+ return;
}
- else if (type == GL_TEXTURE_2D_ARRAY)
+
+ Texture *texture = new Texture(mFactory->createTexture(type), handle, type);
+ texture->addRef();
+
+ if (handleAllocated)
{
- textureObject = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), texture);
+ textureMapIt->second = texture;
}
else
{
- UNREACHABLE();
- return;
+ mTextureHandleAllocator.reserve(handle);
+ mTextureMap[handle] = texture;
}
-
- mTextureMap[texture] = textureObject;
- textureObject->addRef();
}
}
-void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
+void ResourceManager::checkRenderbufferAllocation(GLuint handle)
{
- if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
+ if (handle != 0)
{
- Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer->createRenderbuffer(), renderbuffer);
- mRenderbufferMap[renderbuffer] = renderbufferObject;
- renderbufferObject->addRef();
+ auto renderbufferMapIt = mRenderbufferMap.find(handle);
+ bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end());
+
+ if (handleAllocated && renderbufferMapIt->second != nullptr)
+ {
+ return;
+ }
+
+ Renderbuffer *renderbuffer = new Renderbuffer(mFactory->createRenderbuffer(), handle);
+ renderbuffer->addRef();
+
+ if (handleAllocated)
+ {
+ renderbufferMapIt->second = renderbuffer;
+ }
+ else
+ {
+ mRenderbufferHandleAllocator.reserve(handle);
+ mRenderbufferMap[handle] = renderbuffer;
+ }
}
}
@@ -416,6 +444,7 @@ void ResourceManager::checkSamplerAllocation(GLuint sampler)
Sampler *samplerObject = new Sampler(sampler);
mSamplerMap[sampler] = samplerObject;
samplerObject->addRef();
+ // Samplers cannot be created via Bind
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h b/src/3rdparty/angle/src/libANGLE/ResourceManager.h
index acad29b51d..8e95e8840a 100644
--- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
+++ b/src/3rdparty/angle/src/libANGLE/ResourceManager.h
@@ -7,20 +7,19 @@
// ResourceManager.h : Defines the ResourceManager class, which tracks objects
// shared by multiple GL contexts.
-#ifndef LIBGLESV2_RESOURCEMANAGER_H_
-#define LIBGLESV2_RESOURCEMANAGER_H_
-
-#include "common/angleutils.h"
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/HandleAllocator.h"
+#ifndef LIBANGLE_RESOURCEMANAGER_H_
+#define LIBANGLE_RESOURCEMANAGER_H_
#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/HandleAllocator.h"
-#include <unordered_map>
+#include <map>
namespace rx
{
-class Renderer;
+class ImplFactory;
}
namespace gl
@@ -34,10 +33,10 @@ class Sampler;
class FenceSync;
struct Data;
-class ResourceManager
+class ResourceManager : angle::NonCopyable
{
public:
- explicit ResourceManager(rx::Renderer *renderer);
+ explicit ResourceManager(rx::ImplFactory *factory);
~ResourceManager();
void addRef();
@@ -69,47 +68,47 @@ class ResourceManager
void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
- void checkBufferAllocation(unsigned int buffer);
- void checkTextureAllocation(GLuint texture, GLenum type);
- void checkRenderbufferAllocation(GLuint renderbuffer);
+ void checkBufferAllocation(GLuint handle);
+ void checkTextureAllocation(GLuint handle, GLenum type);
+ void checkRenderbufferAllocation(GLuint handle);
void checkSamplerAllocation(GLuint sampler);
bool isSampler(GLuint sampler);
private:
- DISALLOW_COPY_AND_ASSIGN(ResourceManager);
+ void createTextureInternal(GLuint handle);
- rx::Renderer *mRenderer;
+ rx::ImplFactory *mFactory;
std::size_t mRefCount;
- typedef std::unordered_map<GLuint, Buffer*> BufferMap;
+ typedef std::map<GLuint, Buffer*> BufferMap;
BufferMap mBufferMap;
HandleAllocator mBufferHandleAllocator;
- typedef std::unordered_map<GLuint, Shader*> ShaderMap;
+ typedef std::map<GLuint, Shader*> ShaderMap;
ShaderMap mShaderMap;
- typedef std::unordered_map<GLuint, Program*> ProgramMap;
+ typedef std::map<GLuint, Program*> ProgramMap;
ProgramMap mProgramMap;
HandleAllocator mProgramShaderHandleAllocator;
- typedef std::unordered_map<GLuint, Texture*> TextureMap;
+ typedef std::map<GLuint, Texture*> TextureMap;
TextureMap mTextureMap;
HandleAllocator mTextureHandleAllocator;
- typedef std::unordered_map<GLuint, Renderbuffer*> RenderbufferMap;
+ typedef std::map<GLuint, Renderbuffer*> RenderbufferMap;
RenderbufferMap mRenderbufferMap;
HandleAllocator mRenderbufferHandleAllocator;
- typedef std::unordered_map<GLuint, Sampler*> SamplerMap;
+ typedef std::map<GLuint, Sampler*> SamplerMap;
SamplerMap mSamplerMap;
HandleAllocator mSamplerHandleAllocator;
- typedef std::unordered_map<GLuint, FenceSync*> FenceMap;
+ typedef std::map<GLuint, FenceSync*> FenceMap;
FenceMap mFenceSyncMap;
HandleAllocator mFenceSyncHandleAllocator;
};
}
-#endif // LIBGLESV2_RESOURCEMANAGER_H_
+#endif // LIBANGLE_RESOURCEMANAGER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Sampler.cpp b/src/3rdparty/angle/src/libANGLE/Sampler.cpp
index b906e65557..d58bd5a862 100644
--- a/src/3rdparty/angle/src/libGLESv2/Sampler.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Sampler.cpp
@@ -7,8 +7,8 @@
// Sampler.cpp : Implements the Sampler class, which represents a GLES 3
// sampler object. Sampler objects store some state needed to sample textures.
-#include "libGLESv2/Sampler.h"
-#include "libGLESv2/angletypes.h"
+#include "libANGLE/Sampler.h"
+#include "libANGLE/angletypes.h"
namespace gl
{
diff --git a/src/3rdparty/angle/src/libGLESv2/Sampler.h b/src/3rdparty/angle/src/libANGLE/Sampler.h
index 257bc25d22..d33798ff15 100644
--- a/src/3rdparty/angle/src/libGLESv2/Sampler.h
+++ b/src/3rdparty/angle/src/libANGLE/Sampler.h
@@ -7,10 +7,10 @@
// Sampler.h : Defines the Sampler class, which represents a GLES 3
// sampler object. Sampler objects store some state needed to sample textures.
-#ifndef LIBGLESV2_SAMPLER_H_
-#define LIBGLESV2_SAMPLER_H_
+#ifndef LIBANGLE_SAMPLER_H_
+#define LIBANGLE_SAMPLER_H_
-#include "common/RefCountObject.h"
+#include "libANGLE/RefCountObject.h"
namespace gl
{
@@ -57,4 +57,4 @@ class Sampler : public RefCountObject
}
-#endif // LIBGLESV2_SAMPLER_H_
+#endif // LIBANGLE_SAMPLER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libANGLE/Shader.cpp
index 024ef8fb7c..7af4ff358d 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Shader.cpp
@@ -8,11 +8,11 @@
// 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 "libGLESv2/Shader.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/ShaderImpl.h"
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/ResourceManager.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/renderer/ShaderImpl.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/ResourceManager.h"
#include "common/utilities.h"
@@ -131,9 +131,9 @@ void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length,
getSourceImpl(debugInfo, bufSize, length, buffer);
}
-void Shader::compile(const gl::Data &data)
+void Shader::compile(Compiler *compiler)
{
- mCompiled = mShader->compile(data, mSource);
+ mCompiled = mShader->compile(compiler, mSource);
}
void Shader::addRef()
@@ -216,4 +216,28 @@ std::vector<sh::Attribute> &Shader::getActiveOutputVariables()
return mShader->getActiveOutputVariables();
}
+
+int Shader::getSemanticIndex(const std::string &attributeName) const
+{
+ if (!attributeName.empty())
+ {
+ const auto &activeAttributes = mShader->getActiveAttributes();
+
+ int semanticIndex = 0;
+ for (size_t attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
+ {
+ const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
+
+ if (attribute.name == attributeName)
+ {
+ return semanticIndex;
+ }
+
+ semanticIndex += gl::VariableRegisterCount(attribute.type);
+ }
+ }
+
+ return -1;
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.h b/src/3rdparty/angle/src/libANGLE/Shader.h
index 904217dab8..10e79c7499 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.h
+++ b/src/3rdparty/angle/src/libANGLE/Shader.h
@@ -9,9 +9,8 @@
// related functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section
// 3.8 page 84.
-#ifndef LIBGLESV2_SHADER_H_
-#define LIBGLESV2_SHADER_H_
-
+#ifndef LIBANGLE_SHADER_H_
+#define LIBANGLE_SHADER_H_
#include <string>
#include <list>
@@ -21,7 +20,7 @@
#include <GLSLANG/ShaderLang.h>
#include "common/angleutils.h"
-#include "libGLESv2/angletypes.h"
+#include "libANGLE/angletypes.h"
namespace rx
{
@@ -30,6 +29,7 @@ class ShaderImpl;
namespace gl
{
+class Compiler;
class ResourceManager;
struct Data;
@@ -53,7 +53,7 @@ struct PackedVarying : public sh::Varying
}
};
-class Shader
+class Shader : angle::NonCopyable
{
public:
Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLuint handle);
@@ -76,7 +76,7 @@ class Shader
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const;
- void compile(const gl::Data &data);
+ void compile(Compiler *compiler);
bool isCompiled() const { return mCompiled; }
void addRef();
@@ -97,9 +97,9 @@ class Shader
std::vector<sh::Attribute> &getActiveAttributes();
std::vector<sh::Attribute> &getActiveOutputVariables();
- private:
- DISALLOW_COPY_AND_ASSIGN(Shader);
+ int getSemanticIndex(const std::string &attributeName) const;
+ private:
static void getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer);
rx::ShaderImpl *mShader;
@@ -115,4 +115,4 @@ class Shader
}
-#endif // LIBGLESV2_SHADER_H_
+#endif // LIBANGLE_SHADER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/State.cpp b/src/3rdparty/angle/src/libANGLE/State.cpp
index b5b62f5848..4c044d2950 100644
--- a/src/3rdparty/angle/src/libGLESv2/State.cpp
+++ b/src/3rdparty/angle/src/libANGLE/State.cpp
@@ -6,16 +6,15 @@
// State.cpp: Implements the State class, encapsulating raw GL state.
-#include "libGLESv2/State.h"
+#include "libANGLE/State.h"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/Caps.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/Query.h"
-#include "libGLESv2/VertexArray.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/renderer/RenderTarget.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Query.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/formatutils.h"
namespace gl
{
@@ -36,7 +35,7 @@ void State::initialize(const Caps& caps, GLuint clientVersion)
mMaxDrawBuffers = caps.maxDrawBuffers;
mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
- setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
mDepthClearValue = 1.0f;
mStencilClearValue = 0;
@@ -76,11 +75,11 @@ void State::initialize(const Caps& caps, GLuint clientVersion)
mDepthStencil.depthMask = true;
mDepthStencil.stencilTest = false;
mDepthStencil.stencilFunc = GL_ALWAYS;
- mDepthStencil.stencilMask = -1;
- mDepthStencil.stencilWritemask = -1;
+ mDepthStencil.stencilMask = static_cast<GLuint>(-1);
+ mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
mDepthStencil.stencilBackFunc = GL_ALWAYS;
- mDepthStencil.stencilBackMask = -1;
- mDepthStencil.stencilBackWritemask = -1;
+ mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
+ mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
mDepthStencil.stencilFail = GL_KEEP;
mDepthStencil.stencilPassDepthFail = GL_KEEP;
mDepthStencil.stencilPassDepthPass = GL_KEEP;
@@ -138,11 +137,12 @@ void State::initialize(const Caps& caps, GLuint clientVersion)
mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
- mCurrentProgramId = 0;
- mCurrentProgramBinary.set(NULL);
+ mProgram = NULL;
mReadFramebuffer = NULL;
mDrawFramebuffer = NULL;
+
+ mPrimitiveRestart = false;
}
void State::reset()
@@ -163,6 +163,12 @@ void State::reset()
mArrayBuffer.set(NULL);
mRenderbuffer.set(NULL);
+ if (mProgram)
+ {
+ mProgram->release();
+ }
+ mProgram = NULL;
+
mTransformFeedback.set(NULL);
for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
@@ -187,6 +193,8 @@ void State::reset()
mPack.pixelBuffer.set(NULL);
mUnpack.pixelBuffer.set(NULL);
+
+ mProgram = NULL;
}
const RasterizerState &State::getRasterizerState() const
@@ -204,7 +212,7 @@ const DepthStencilState &State::getDepthStencilState() const
return mDepthStencil;
}
-void State::setClearColor(float red, float green, float blue, float alpha)
+void State::setColorClearValue(float red, float green, float blue, float alpha)
{
mColorClearValue.red = red;
mColorClearValue.green = green;
@@ -212,72 +220,16 @@ void State::setClearColor(float red, float green, float blue, float alpha)
mColorClearValue.alpha = alpha;
}
-void State::setClearDepth(float depth)
+void State::setDepthClearValue(float depth)
{
mDepthClearValue = depth;
}
-void State::setClearStencil(int stencil)
+void State::setStencilClearValue(int stencil)
{
mStencilClearValue = stencil;
}
-ClearParameters State::getClearParameters(GLbitfield mask) const
-{
- ClearParameters clearParams = { 0 };
- for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
- {
- clearParams.clearColor[i] = false;
- }
- clearParams.colorFClearValue = mColorClearValue;
- clearParams.colorClearType = GL_FLOAT;
- clearParams.colorMaskRed = mBlend.colorMaskRed;
- clearParams.colorMaskGreen = mBlend.colorMaskGreen;
- clearParams.colorMaskBlue = mBlend.colorMaskBlue;
- clearParams.colorMaskAlpha = mBlend.colorMaskAlpha;
- clearParams.clearDepth = false;
- clearParams.depthClearValue = mDepthClearValue;
- clearParams.clearStencil = false;
- clearParams.stencilClearValue = mStencilClearValue;
- clearParams.stencilWriteMask = mDepthStencil.stencilWritemask;
- clearParams.scissorEnabled = mScissorTest;
- clearParams.scissor = mScissor;
-
- const Framebuffer *framebufferObject = getDrawFramebuffer();
- if (mask & GL_COLOR_BUFFER_BIT)
- {
- if (framebufferObject->hasEnabledColorAttachment())
- {
- for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
- {
- clearParams.clearColor[i] = true;
- }
- }
- }
-
- if (mask & GL_DEPTH_BUFFER_BIT)
- {
- if (mDepthStencil.depthMask && framebufferObject->getDepthbuffer() != NULL)
- {
- clearParams.clearDepth = true;
- }
- }
-
- if (mask & GL_STENCIL_BUFFER_BIT)
- {
- if (framebufferObject->getStencilbuffer() != NULL)
- {
- GLenum stencilActualFormat = framebufferObject->getStencilbuffer()->getActualFormat();
- if (GetInternalFormatInfo(stencilActualFormat).stencilBits > 0)
- {
- clearParams.clearStencil = true;
- }
- }
- }
-
- return clearParams;
-}
-
void State::setColorMask(bool red, bool green, bool blue, bool alpha)
{
mBlend.colorMaskRed = red;
@@ -527,6 +479,16 @@ void State::setDither(bool enabled)
mBlend.dither = enabled;
}
+bool State::isPrimitiveRestartEnabled() const
+{
+ return mPrimitiveRestart;
+}
+
+void State::setPrimitiveRestart(bool enabled)
+{
+ mPrimitiveRestart = enabled;
+}
+
void State::setEnableFeature(GLenum feature, bool enabled)
{
switch (feature)
@@ -540,7 +502,7 @@ void State::setEnableFeature(GLenum feature, bool enabled)
case GL_DEPTH_TEST: setDepthTest(enabled); break;
case GL_BLEND: setBlend(enabled); break;
case GL_DITHER: setDither(enabled); break;
- case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); break;
+ case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
default: UNREACHABLE();
}
@@ -559,7 +521,7 @@ bool State::getEnableFeature(GLenum feature)
case GL_DEPTH_TEST: return isDepthTestEnabled();
case GL_BLEND: return isBlendEnabled();
case GL_DITHER: return isDitherEnabled();
- case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
+ case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
default: UNREACHABLE(); return false;
}
@@ -613,12 +575,16 @@ void State::setSamplerTexture(GLenum type, Texture *texture)
Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
{
- return mSamplerTextures.at(type)[sampler].get();
+ const auto it = mSamplerTextures.find(type);
+ ASSERT(it != mSamplerTextures.end());
+ return it->second[sampler].get();
}
GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
{
- return mSamplerTextures.at(type)[sampler].id();
+ const auto it = mSamplerTextures.find(type);
+ ASSERT(it != mSamplerTextures.end());
+ return it->second[sampler].id();
}
void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
@@ -641,8 +607,10 @@ void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
BindingPointer<Texture> &binding = textureVector[textureIdx];
if (binding.id() == texture)
{
+ auto it = zeroTextures.find(textureType);
+ ASSERT(it != zeroTextures.end());
// Zero textures are the "default" textures instead of NULL
- binding.set(zeroTextures.at(textureType).get());
+ binding.set(it->second.get());
}
}
}
@@ -665,13 +633,14 @@ void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
void State::initializeZeroTextures(const TextureMap &zeroTextures)
{
- for (TextureMap::const_iterator i = zeroTextures.begin(); i != zeroTextures.end(); i++)
+ for (auto it = zeroTextures.cbegin(); it != zeroTextures.cend(); ++it)
{
- TextureBindingVector &samplerTextureArray = mSamplerTextures[i->first];
+ const auto &zeroTexture = *it;
+ auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
{
- samplerTextureArray[textureUnit].set(i->second.get());
+ samplerTextureArray[textureUnit].set(zeroTexture.second.get());
}
}
}
@@ -845,31 +814,27 @@ bool State::removeVertexArrayBinding(GLuint vertexArray)
return false;
}
-void State::setCurrentProgram(GLuint programId, Program *newProgram)
+void State::setProgram(Program *newProgram)
{
- mCurrentProgramId = programId; // set new ID before trying to delete program binary; otherwise it will only be flagged for deletion
- mCurrentProgramBinary.set(NULL);
-
- if (newProgram)
+ if (mProgram != newProgram)
{
- newProgram->addRef();
- mCurrentProgramBinary.set(newProgram->getProgramBinary());
- }
-}
+ if (mProgram)
+ {
+ mProgram->release();
+ }
-void State::setCurrentProgramBinary(ProgramBinary *binary)
-{
- mCurrentProgramBinary.set(binary);
-}
+ mProgram = newProgram;
-GLuint State::getCurrentProgramId() const
-{
- return mCurrentProgramId;
+ if (mProgram)
+ {
+ newProgram->addRef();
+ }
+ }
}
-ProgramBinary *State::getCurrentProgramBinary() const
+Program *State::getProgram() const
{
- return mCurrentProgramBinary.get();
+ return mProgram;
}
void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
@@ -882,6 +847,12 @@ TransformFeedback *State::getCurrentTransformFeedback() const
return mTransformFeedback.get();
}
+bool State::isTransformFeedbackActiveUnpaused() const
+{
+ gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
+ return curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused();
+}
+
void State::detachTransformFeedback(GLuint transformFeedback)
{
if (mTransformFeedback.id() == transformFeedback)
@@ -917,10 +888,12 @@ GLuint State::getActiveQueryId(GLenum target) const
Query *State::getActiveQuery(GLenum target) const
{
+ const auto it = mActiveQueries.find(target);
+
// All query types should already exist in the activeQueries map
- ASSERT(mActiveQueries.find(target) != mActiveQueries.end());
+ ASSERT(it != mActiveQueries.end());
- return mActiveQueries.at(target).get();
+ return it->second.get();
}
void State::setArrayBufferBinding(Buffer *buffer)
@@ -968,6 +941,20 @@ Buffer *State::getIndexedUniformBuffer(GLuint index) const
return mUniformBuffers[index].get();
}
+GLintptr State::getIndexedUniformBufferOffset(GLuint index) const
+{
+ ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
+
+ return mUniformBuffers[index].getOffset();
+}
+
+GLsizeiptr State::getIndexedUniformBufferSize(GLuint index) const
+{
+ ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
+
+ return mUniformBuffers[index].getSize();
+}
+
void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer)
{
mGenericTransformFeedbackBuffer.set(buffer);
@@ -1069,11 +1056,6 @@ void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GL
getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
}
-const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
-{
- return getVertexArray()->getVertexAttribute(attribNum);
-}
-
const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
{
ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
@@ -1110,6 +1092,11 @@ const PixelPackState &State::getPackState() const
return mPack;
}
+PixelPackState &State::getPackState()
+{
+ return mPack;
+}
+
void State::setUnpackAlignment(GLint alignment)
{
mUnpack.alignment = alignment;
@@ -1120,11 +1107,26 @@ GLint State::getUnpackAlignment() const
return mUnpack.alignment;
}
+void State::setUnpackRowLength(GLint rowLength)
+{
+ mUnpack.rowLength = rowLength;
+}
+
+GLint State::getUnpackRowLength() const
+{
+ return mUnpack.rowLength;
+}
+
const PixelUnpackState &State::getUnpackState() const
{
return mUnpack;
}
+PixelUnpackState &State::getUnpackState()
+{
+ return mUnpack;
+}
+
void State::getBooleanv(GLenum pname, GLboolean *params)
{
switch (pname)
@@ -1214,10 +1216,11 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
- case GL_CURRENT_PROGRAM: *params = mCurrentProgramId; break;
+ case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
+ case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
case GL_ACTIVE_TEXTURE: *params = (mActiveSampler + GL_TEXTURE0); break;
@@ -1243,11 +1246,13 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
case GL_SAMPLE_BUFFERS:
case GL_SAMPLES:
{
gl::Framebuffer *framebuffer = mDrawFramebuffer;
- if (framebuffer->completeness(data) == GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
{
switch (pname)
{
@@ -1342,19 +1347,19 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
break;
case GL_TEXTURE_BINDING_2D:
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
- *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
+ *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D) ;
break;
case GL_TEXTURE_BINDING_CUBE_MAP:
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
- *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
+ *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_CUBE_MAP);
break;
case GL_TEXTURE_BINDING_3D:
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
- *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
+ *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_3D);
break;
case GL_TEXTURE_BINDING_2D_ARRAY:
ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
- *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
+ *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D_ARRAY);
break;
case GL_UNIFORM_BUFFER_BINDING:
*params = mGenericUniformBuffer.id();
@@ -1442,9 +1447,10 @@ bool State::hasMappedBuffer(GLenum target) const
{
if (target == GL_ARRAY_BUFFER)
{
+ const VertexArray *vao = getVertexArray();
for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++)
{
- const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast<unsigned int>(attribIndex));
+ const gl::VertexAttribute &vertexAttrib = vao->getVertexAttribute(attribIndex);
gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
{
diff --git a/src/3rdparty/angle/src/libGLESv2/State.h b/src/3rdparty/angle/src/libANGLE/State.h
index c3e6106bd8..4370a2f16f 100644
--- a/src/3rdparty/angle/src/libGLESv2/State.h
+++ b/src/3rdparty/angle/src/libANGLE/State.h
@@ -6,18 +6,18 @@
// State.h: Defines the State class, encapsulating raw GL state
-#ifndef LIBGLESV2_STATE_H_
-#define LIBGLESV2_STATE_H_
+#ifndef LIBANGLE_STATE_H_
+#define LIBANGLE_STATE_H_
#include "common/angleutils.h"
-#include "common/RefCountObject.h"
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/TransformFeedback.h"
-#include "libGLESv2/Program.h"
-#include "libGLESv2/Sampler.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/TransformFeedback.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Sampler.h"
namespace gl
{
@@ -29,7 +29,7 @@ struct Data;
typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
-class State
+class State : angle::NonCopyable
{
public:
State();
@@ -44,10 +44,13 @@ class State
const DepthStencilState &getDepthStencilState() const;
// Clear behavior setters & state parameter block generation function
- void setClearColor(float red, float green, float blue, float alpha);
- void setClearDepth(float depth);
- void setClearStencil(int stencil);
- ClearParameters getClearParameters(GLbitfield mask) const;
+ 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);
@@ -57,6 +60,10 @@ class State
bool isRasterizerDiscardEnabled() const;
void setRasterizerDiscard(bool enabled);
+ // Primitive restart
+ bool isPrimitiveRestartEnabled() const;
+ void setPrimitiveRestart(bool enabled);
+
// Face culling state manipulation
bool isCullFaceEnabled() const;
void setCullFace(bool enabled);
@@ -167,14 +174,13 @@ class State
bool removeVertexArrayBinding(GLuint vertexArray);
// Program binding manipulation
- void setCurrentProgram(GLuint programId, Program *newProgram);
- void setCurrentProgramBinary(ProgramBinary *binary);
- GLuint getCurrentProgramId() const;
- ProgramBinary *getCurrentProgramBinary() const;
+ void setProgram(Program *newProgram);
+ Program *getProgram() const;
// Transform feedback object (not buffer) binding manipulation
void setTransformFeedbackBinding(TransformFeedback *transformFeedback);
TransformFeedback *getCurrentTransformFeedback() const;
+ bool isTransformFeedbackActiveUnpaused() const;
void detachTransformFeedback(GLuint transformFeedback);
// Query binding manipulation
@@ -194,6 +200,8 @@ class State
void setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size);
GLuint getIndexedUniformBufferId(GLuint index) const;
Buffer *getIndexedUniformBuffer(GLuint index) const;
+ GLintptr getIndexedUniformBufferOffset(GLuint index) const;
+ GLsizeiptr getIndexedUniformBufferSize(GLuint index) const;
// GL_TRANSFORM_FEEDBACK_BUFFER - Both indexed and generic targets
void setGenericTransformFeedbackBufferBinding(Buffer *buffer);
@@ -221,7 +229,6 @@ class State
void setVertexAttribi(GLuint index, const GLint values[4]);
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
- const VertexAttribute &getVertexAttribState(unsigned int attribNum) const;
const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const;
const void *getVertexAttribPointer(unsigned int attribNum) const;
@@ -231,11 +238,15 @@ class State
void setPackReverseRowOrder(bool reverseRowOrder);
bool getPackReverseRowOrder() const;
const PixelPackState &getPackState() const;
+ PixelPackState &getPackState();
// Pixel unpack state manipulation
void setUnpackAlignment(GLint alignment);
GLint getUnpackAlignment() const;
+ void setUnpackRowLength(GLint rowLength);
+ GLint getUnpackRowLength() const;
const PixelUnpackState &getUnpackState() const;
+ PixelUnpackState &getUnpackState();
// State query functions
void getBooleanv(GLenum pname, GLboolean *params);
@@ -247,8 +258,6 @@ class State
bool hasMappedBuffer(GLenum target) const;
private:
- DISALLOW_COPY_AND_ASSIGN(State);
-
// Cached values from Context's caps
GLuint mMaxDrawBuffers;
GLuint mMaxCombinedTextureImageUnits;
@@ -284,8 +293,7 @@ class State
Framebuffer *mReadFramebuffer;
Framebuffer *mDrawFramebuffer;
BindingPointer<Renderbuffer> mRenderbuffer;
- GLuint mCurrentProgramId;
- BindingPointer<ProgramBinary> mCurrentProgramBinary;
+ Program *mProgram;
typedef std::vector<VertexAttribCurrentValueData> VertexAttribVector;
VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib
@@ -317,9 +325,11 @@ class State
PixelUnpackState mUnpack;
PixelPackState mPack;
+
+ bool mPrimitiveRestart;
};
}
-#endif // LIBGLESV2_STATE_H_
+#endif // LIBANGLE_STATE_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Surface.cpp b/src/3rdparty/angle/src/libANGLE/Surface.cpp
new file mode 100644
index 0000000000..ac455f3905
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Surface.cpp
@@ -0,0 +1,166 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// 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 "libANGLE/Config.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/renderer/SurfaceImpl.h"
+
+#include <EGL/eglext.h>
+
+namespace egl
+{
+
+Surface::Surface(rx::SurfaceImpl *impl, EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes)
+ : RefCountObject(0), // id unused
+ mImplementation(impl),
+ mType(surfaceType),
+ mConfig(config),
+ mPostSubBufferRequested(false),
+ mFixedSize(false),
+ mFixedWidth(0),
+ mFixedHeight(0),
+ mTextureFormat(EGL_NO_TEXTURE),
+ mTextureTarget(EGL_NO_TEXTURE),
+ // FIXME: Determine actual pixel aspect ratio
+ mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
+ mRenderBuffer(EGL_BACK_BUFFER),
+ mSwapBehavior(EGL_BUFFER_PRESERVED),
+ mTexture(NULL)
+{
+ addRef();
+
+ mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
+
+ mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
+ if (mFixedSize)
+ {
+ mFixedWidth = attributes.get(EGL_WIDTH, 0);
+ mFixedHeight = attributes.get(EGL_HEIGHT, 0);
+ }
+
+ if (mType != EGL_WINDOW_BIT)
+ {
+ mTextureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
+ mTextureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
+ }
+}
+
+Surface::~Surface()
+{
+ if (mTexture)
+ {
+ if (mImplementation)
+ {
+ mImplementation->releaseTexImage(mTexture->id());
+ }
+ mTexture->releaseTexImage();
+ mTexture = NULL;
+ }
+
+ SafeDelete(mImplementation);
+}
+
+EGLint Surface::getType() const
+{
+ return mType;
+}
+
+Error Surface::swap()
+{
+ return mImplementation->swap();
+}
+
+Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ return mImplementation->postSubBuffer(x, y, width, height);
+}
+
+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);
+}
+
+const Config *Surface::getConfig() const
+{
+ return mConfig;
+}
+
+EGLint Surface::getPixelAspectRatio() const
+{
+ return mPixelAspectRatio;
+}
+
+EGLenum Surface::getRenderBuffer() const
+{
+ return mRenderBuffer;
+}
+
+EGLenum Surface::getSwapBehavior() const
+{
+ return mSwapBehavior;
+}
+
+EGLenum Surface::getTextureFormat() const
+{
+ return mTextureFormat;
+}
+
+EGLenum Surface::getTextureTarget() const
+{
+ return mTextureTarget;
+}
+
+EGLint Surface::isFixedSize() const
+{
+ return mFixedSize;
+}
+
+EGLint Surface::getWidth() const
+{
+ return mFixedSize ? mFixedWidth : mImplementation->getWidth();
+}
+
+EGLint Surface::getHeight() const
+{
+ return mFixedSize ? mFixedHeight : mImplementation->getHeight();
+}
+
+Error Surface::bindTexImage(gl::Texture *texture, EGLint buffer)
+{
+ ASSERT(!mTexture);
+
+ texture->bindTexImage(this);
+ mTexture = texture;
+ return mImplementation->bindTexImage(buffer);
+}
+
+Error Surface::releaseTexImage(EGLint buffer)
+{
+ ASSERT(mTexture);
+ gl::Texture *boundTexture = mTexture;
+ mTexture = NULL;
+
+ boundTexture->releaseTexImage();
+ return mImplementation->releaseTexImage(buffer);
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/Surface.h b/src/3rdparty/angle/src/libANGLE/Surface.h
new file mode 100644
index 0000000000..430bf0195d
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Surface.h
@@ -0,0 +1,98 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// 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 <EGL/egl.h>
+
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
+
+namespace gl
+{
+class Texture;
+}
+
+namespace rx
+{
+class SurfaceImpl;
+}
+
+namespace egl
+{
+class AttributeMap;
+class Display;
+struct Config;
+
+class Surface final : public RefCountObject
+{
+ public:
+ Surface(rx::SurfaceImpl *impl, EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes);
+
+ rx::SurfaceImpl *getImplementation() { return mImplementation; }
+ const rx::SurfaceImpl *getImplementation() const { return mImplementation; }
+
+ EGLint getType() const;
+
+ Error swap();
+ Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
+ Error querySurfacePointerANGLE(EGLint attribute, void **value);
+ Error bindTexImage(gl::Texture *texture, EGLint buffer);
+ Error releaseTexImage(EGLint buffer);
+
+ EGLint isPostSubBufferSupported() const;
+
+ void setSwapInterval(EGLint interval);
+
+ const Config *getConfig() const;
+
+ // width and height can change with client window resizing
+ EGLint getWidth() const;
+ EGLint getHeight() const;
+ EGLint getPixelAspectRatio() const;
+ EGLenum getRenderBuffer() const;
+ EGLenum getSwapBehavior() const;
+ EGLenum getTextureFormat() const;
+ EGLenum getTextureTarget() const;
+
+ gl::Texture *getBoundTexture() const { return mTexture; }
+
+ EGLint isFixedSize() const;
+
+ private:
+ virtual ~Surface();
+
+ rx::SurfaceImpl *mImplementation;
+
+ EGLint mType;
+
+ const egl::Config *mConfig;
+
+ bool mPostSubBufferRequested;
+
+ bool mFixedSize;
+ size_t mFixedWidth;
+ size_t mFixedHeight;
+
+ EGLenum mTextureFormat;
+ EGLenum mTextureTarget;
+
+ EGLint mPixelAspectRatio; // Display aspect ratio
+ EGLenum mRenderBuffer; // Render buffer
+ EGLenum mSwapBehavior; // Buffer swap behavior
+
+ gl::Texture *mTexture;
+};
+
+}
+
+#endif // LIBANGLE_SURFACE_H_
diff --git a/src/3rdparty/angle/src/libANGLE/Texture.cpp b/src/3rdparty/angle/src/libANGLE/Texture.cpp
new file mode 100644
index 0000000000..cd4584f694
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Texture.cpp
@@ -0,0 +1,573 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// Texture.cpp: Implements the gl::Texture class. [OpenGL ES 2.0.24] section 3.7 page 63.
+
+#include "libANGLE/Texture.h"
+#include "libANGLE/Data.h"
+#include "libANGLE/formatutils.h"
+
+#include "libANGLE/Config.h"
+#include "libANGLE/Surface.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+
+namespace gl
+{
+
+bool IsMipmapFiltered(const gl::SamplerState &samplerState)
+{
+ switch (samplerState.minFilter)
+ {
+ 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;
+ }
+}
+
+bool IsPointSampled(const gl::SamplerState &samplerState)
+{
+ return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
+}
+
+static size_t GetImageDescIndex(GLenum target, size_t level)
+{
+ return IsCubeMapTextureTarget(target) ? ((level * 6) + CubeMapTextureTargetToLayerIndex(target)) : level;
+}
+
+unsigned int Texture::mCurrentTextureSerial = 1;
+
+Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
+ : RefCountObject(id),
+ mTexture(impl),
+ mTextureSerial(issueTextureSerial()),
+ mUsage(GL_NONE),
+ mImmutableLevelCount(0),
+ mTarget(target),
+ mImageDescs(IMPLEMENTATION_MAX_TEXTURE_LEVELS * (target == GL_TEXTURE_CUBE_MAP ? 6 : 1)),
+ mCompletenessCache(),
+ mBoundSurface(NULL)
+{
+}
+
+Texture::~Texture()
+{
+ if (mBoundSurface)
+ {
+ mBoundSurface->releaseTexImage(EGL_BACK_BUFFER);
+ mBoundSurface = NULL;
+ }
+ SafeDelete(mTexture);
+}
+
+GLenum Texture::getTarget() const
+{
+ return mTarget;
+}
+
+void Texture::setUsage(GLenum usage)
+{
+ mUsage = usage;
+ getImplementation()->setUsage(usage);
+}
+
+GLenum Texture::getUsage() const
+{
+ return mUsage;
+}
+
+size_t Texture::getWidth(GLenum target, size_t level) const
+{
+ ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+ return getImageDesc(target, level).size.width;
+}
+
+size_t Texture::getHeight(GLenum target, size_t level) const
+{
+ ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+ return getImageDesc(target, level).size.height;
+}
+
+size_t Texture::getDepth(GLenum target, size_t level) const
+{
+ ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+ return getImageDesc(target, level).size.depth;
+}
+
+GLenum Texture::getInternalFormat(GLenum target, size_t level) const
+{
+ ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+ return getImageDesc(target, level).internalFormat;
+}
+
+bool Texture::isSamplerComplete(const SamplerState &samplerState, const Data &data) const
+{
+ const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), samplerState.baseLevel);
+ const TextureCaps &textureCaps = data.textureCaps->get(baseImageDesc.internalFormat);
+ if (!mCompletenessCache.cacheValid ||
+ mCompletenessCache.samplerState != samplerState ||
+ mCompletenessCache.filterable != textureCaps.filterable ||
+ mCompletenessCache.clientVersion != data.clientVersion ||
+ mCompletenessCache.supportsNPOT != data.extensions->textureNPOT)
+ {
+ mCompletenessCache.cacheValid = true;
+ mCompletenessCache.samplerState = samplerState;
+ mCompletenessCache.filterable = textureCaps.filterable;
+ mCompletenessCache.clientVersion = data.clientVersion;
+ mCompletenessCache.supportsNPOT = data.extensions->textureNPOT;
+ mCompletenessCache.samplerComplete = computeSamplerCompleteness(samplerState, data);
+ }
+ return mCompletenessCache.samplerComplete;
+}
+
+// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+bool Texture::isCubeComplete() const
+{
+ ASSERT(mTarget == GL_TEXTURE_CUBE_MAP);
+
+ const ImageDesc &baseImageDesc = getImageDesc(FirstCubeMapTextureTarget, 0);
+ if (baseImageDesc.size.width == 0 || baseImageDesc.size.width != baseImageDesc.size.height)
+ {
+ return false;
+ }
+
+ for (GLenum face = FirstCubeMapTextureTarget + 1; face <= LastCubeMapTextureTarget; face++)
+ {
+ const ImageDesc &faceImageDesc = getImageDesc(face, 0);
+ if (faceImageDesc.size.width != baseImageDesc.size.width ||
+ faceImageDesc.size.height != baseImageDesc.size.height ||
+ faceImageDesc.internalFormat != baseImageDesc.internalFormat)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+unsigned int Texture::getTextureSerial() const
+{
+ return mTextureSerial;
+}
+
+unsigned int Texture::issueTextureSerial()
+{
+ return mCurrentTextureSerial++;
+}
+
+bool Texture::isImmutable() const
+{
+ return (mImmutableLevelCount > 0);
+}
+
+int Texture::immutableLevelCount()
+{
+ return mImmutableLevelCount;
+}
+
+Error Texture::setImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size, GLenum format, GLenum type,
+ const PixelUnpackState &unpack, const uint8_t *pixels)
+{
+ ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+
+ Error error = mTexture->setImage(target, level, internalFormat, size, format, type, unpack, pixels);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ releaseTexImage();
+
+ setImageDesc(target, level, ImageDesc(size, GetSizedInternalFormat(internalFormat, type)));
+
+ return Error(GL_NO_ERROR);
+}
+
+Error Texture::setSubImage(GLenum target, size_t level, const Box &area, GLenum format, GLenum type,
+ const PixelUnpackState &unpack, const uint8_t *pixels)
+{
+ ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+
+ return mTexture->setSubImage(target, level, area, format, type, unpack, pixels);
+}
+
+Error Texture::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size,
+ const PixelUnpackState &unpack, const uint8_t *pixels)
+{
+ ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+
+ Error error = mTexture->setCompressedImage(target, level, internalFormat, size, unpack, pixels);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ releaseTexImage();
+
+ setImageDesc(target, level, ImageDesc(size, GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE)));
+
+ return Error(GL_NO_ERROR);
+}
+
+Error Texture::setCompressedSubImage(GLenum target, size_t level, const Box &area, GLenum format,
+ const PixelUnpackState &unpack, const uint8_t *pixels)
+{
+ ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+
+ return mTexture->setCompressedSubImage(target, level, area, format, unpack, pixels);
+}
+
+Error Texture::copyImage(GLenum target, size_t level, const Rectangle &sourceArea, GLenum internalFormat,
+ const Framebuffer *source)
+{
+ ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+
+ Error error = mTexture->copyImage(target, level, sourceArea, internalFormat, source);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ releaseTexImage();
+
+ setImageDesc(target, level, ImageDesc(Extents(sourceArea.width, sourceArea.height, 1),
+ GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE)));
+
+ return Error(GL_NO_ERROR);
+}
+
+Error Texture::copySubImage(GLenum target, size_t level, const Offset &destOffset, const Rectangle &sourceArea,
+ const Framebuffer *source)
+{
+ ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+
+ return mTexture->copySubImage(target, level, destOffset, sourceArea, source);
+}
+
+Error Texture::setStorage(GLenum target, size_t levels, GLenum internalFormat, const Extents &size)
+{
+ ASSERT(target == mTarget);
+
+ Error error = mTexture->setStorage(target, levels, internalFormat, size);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ releaseTexImage();
+
+ mImmutableLevelCount = levels;
+ clearImageDescs();
+ setImageDescChain(levels, size, internalFormat);
+
+ return Error(GL_NO_ERROR);
+}
+
+
+Error Texture::generateMipmaps()
+{
+ Error error = mTexture->generateMipmaps();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ releaseTexImage();
+
+ const ImageDesc &baseImageInfo = getImageDesc(getBaseImageTarget(), 0);
+ size_t mipLevels = log2(std::max(std::max(baseImageInfo.size.width, baseImageInfo.size.height), baseImageInfo.size.depth)) + 1;
+ setImageDescChain(mipLevels, baseImageInfo.size, baseImageInfo.internalFormat);
+
+ return Error(GL_NO_ERROR);
+}
+
+void Texture::setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInternalFormat)
+{
+ for (size_t level = 0; level < levels; level++)
+ {
+ Extents levelSize(std::max<size_t>(baseSize.width >> level, 1),
+ std::max<size_t>(baseSize.height >> level, 1),
+ (mTarget == GL_TEXTURE_2D_ARRAY) ? baseSize.depth : std::max<size_t>(baseSize.depth >> level, 1));
+ ImageDesc levelInfo(levelSize, sizedInternalFormat);
+
+ if (mTarget == GL_TEXTURE_CUBE_MAP)
+ {
+ for (size_t face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++)
+ {
+ setImageDesc(face, level, levelInfo);
+ }
+ }
+ else
+ {
+ setImageDesc(mTarget, level, levelInfo);
+ }
+ }
+}
+
+Texture::ImageDesc::ImageDesc()
+ : size(0, 0, 0), internalFormat(GL_NONE)
+{
+}
+
+Texture::ImageDesc::ImageDesc(const Extents &size, GLenum internalFormat)
+ : size(size),
+ internalFormat(internalFormat)
+{
+}
+
+const Texture::ImageDesc &Texture::getImageDesc(GLenum target, size_t level) const
+{
+ size_t descIndex = GetImageDescIndex(target, level);
+ ASSERT(descIndex < mImageDescs.size());
+ return mImageDescs[descIndex];
+}
+
+void Texture::setImageDesc(GLenum target, size_t level, const ImageDesc &desc)
+{
+ size_t descIndex = GetImageDescIndex(target, level);
+ ASSERT(descIndex < mImageDescs.size());
+ mImageDescs[descIndex] = desc;
+ mCompletenessCache.cacheValid = false;
+}
+
+void Texture::clearImageDesc(GLenum target, size_t level)
+{
+ setImageDesc(target, level, ImageDesc());
+}
+
+void Texture::clearImageDescs()
+{
+ for (size_t descIndex = 0; descIndex < mImageDescs.size(); descIndex++)
+ {
+ mImageDescs[descIndex] = ImageDesc();
+ }
+ mCompletenessCache.cacheValid = false;
+}
+
+void Texture::bindTexImage(egl::Surface *surface)
+{
+ ASSERT(surface);
+
+ releaseTexImage();
+ mTexture->bindTexImage(surface);
+ mBoundSurface = surface;
+
+ // Set the image info to the size and format of the surface
+ ASSERT(mTarget == GL_TEXTURE_2D);
+ Extents size(surface->getWidth(), surface->getHeight(), 1);
+ ImageDesc desc(size, surface->getConfig()->renderTargetFormat);
+ setImageDesc(mTarget, 0, desc);
+}
+
+void Texture::releaseTexImage()
+{
+ if (mBoundSurface)
+ {
+ mBoundSurface = NULL;
+ mTexture->releaseTexImage();
+
+ // Erase the image info for level 0
+ ASSERT(mTarget == GL_TEXTURE_2D);
+ clearImageDesc(mTarget, 0);
+ }
+}
+
+GLenum Texture::getBaseImageTarget() const
+{
+ return mTarget == GL_TEXTURE_CUBE_MAP ? FirstCubeMapTextureTarget : mTarget;
+}
+
+size_t Texture::getExpectedMipLevels() const
+{
+ const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), 0);
+ if (mTarget == GL_TEXTURE_3D)
+ {
+ return log2(std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height), baseImageDesc.size.depth)) + 1;
+ }
+ else
+ {
+ return log2(std::max(baseImageDesc.size.width, baseImageDesc.size.height)) + 1;
+ }
+}
+
+bool Texture::computeSamplerCompleteness(const SamplerState &samplerState, const Data &data) const
+{
+ const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), samplerState.baseLevel);
+ if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || baseImageDesc.size.depth == 0)
+ {
+ return false;
+ }
+
+ if (mTarget == GL_TEXTURE_CUBE_MAP && baseImageDesc.size.width != baseImageDesc.size.height)
+ {
+ return false;
+ }
+
+ const TextureCaps &textureCaps = data.textureCaps->get(baseImageDesc.internalFormat);
+ if (!textureCaps.filterable && !IsPointSampled(samplerState))
+ {
+ return false;
+ }
+
+ bool npotSupport = data.extensions->textureNPOT || data.clientVersion >= 3;
+ if (!npotSupport)
+ {
+ if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(baseImageDesc.size.width)) ||
+ (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(baseImageDesc.size.height)))
+ {
+ return false;
+ }
+ }
+
+ if (IsMipmapFiltered(samplerState))
+ {
+ if (!npotSupport)
+ {
+ if (!gl::isPow2(baseImageDesc.size.width) || !gl::isPow2(baseImageDesc.size.height))
+ {
+ return false;
+ }
+ }
+
+ if (!computeMipmapCompleteness(samplerState))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (mTarget == GL_TEXTURE_CUBE_MAP && !isCubeComplete())
+ {
+ 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.
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(baseImageDesc.internalFormat);
+ if (formatInfo.depthBits > 0 && data.clientVersion > 2)
+ {
+ if (samplerState.compareMode == GL_NONE)
+ {
+ if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
+ samplerState.magFilter != GL_NEAREST)
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool Texture::computeMipmapCompleteness(const gl::SamplerState &samplerState) const
+{
+ size_t expectedMipLevels = getExpectedMipLevels();
+
+ size_t maxLevel = std::min<size_t>(expectedMipLevels, samplerState.maxLevel + 1);
+
+ for (size_t level = samplerState.baseLevel; level < maxLevel; level++)
+ {
+ if (mTarget == GL_TEXTURE_CUBE_MAP)
+ {
+ for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++)
+ {
+ if (!computeLevelCompleteness(face, level, samplerState))
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ if (!computeLevelCompleteness(mTarget, level, samplerState))
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+bool Texture::computeLevelCompleteness(GLenum target, size_t level, const gl::SamplerState &samplerState) const
+{
+ ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+ if (isImmutable())
+ {
+ return true;
+ }
+
+ const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), samplerState.baseLevel);
+ if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || baseImageDesc.size.depth == 0)
+ {
+ return false;
+ }
+
+ // The base image level is complete if the width and height are positive
+ if (level == 0)
+ {
+ return true;
+ }
+
+ const ImageDesc &levelImageDesc = getImageDesc(target, level);
+ if (levelImageDesc.internalFormat != baseImageDesc.internalFormat)
+ {
+ return false;
+ }
+
+ if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> level))
+ {
+ return false;
+ }
+
+ if (levelImageDesc.size.height != std::max(1, baseImageDesc.size.height >> level))
+ {
+ return false;
+ }
+
+ if (mTarget == GL_TEXTURE_3D)
+ {
+ if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> level))
+ {
+ return false;
+ }
+ }
+ else if (mTarget == GL_TEXTURE_2D_ARRAY)
+ {
+ if (levelImageDesc.size.depth != baseImageDesc.size.depth)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+Texture::SamplerCompletenessCache::SamplerCompletenessCache()
+ : cacheValid(false),
+ samplerState(),
+ filterable(false),
+ clientVersion(0),
+ supportsNPOT(false),
+ samplerComplete(false)
+{
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/Texture.h b/src/3rdparty/angle/src/libANGLE/Texture.h
new file mode 100644
index 0000000000..b5a0717713
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/Texture.h
@@ -0,0 +1,156 @@
+//
+// Copyright (c) 2002-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.
+//
+
+// 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 "common/debug.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/renderer/TextureImpl.h"
+#include "libANGLE/Caps.h"
+
+#include "angle_gl.h"
+
+#include <vector>
+#include <map>
+
+namespace egl
+{
+class Surface;
+}
+
+namespace gl
+{
+class Framebuffer;
+struct Data;
+
+bool IsMipmapFiltered(const gl::SamplerState &samplerState);
+
+class Texture final : public RefCountObject
+{
+ public:
+ Texture(rx::TextureImpl *impl, GLuint id, GLenum target);
+
+ virtual ~Texture();
+
+ GLenum getTarget() const;
+
+ const SamplerState &getSamplerState() const { return mSamplerState; }
+ SamplerState &getSamplerState() { return mSamplerState; }
+
+ void setUsage(GLenum usage);
+ GLenum getUsage() const;
+
+ size_t getWidth(GLenum target, size_t level) const;
+ size_t getHeight(GLenum target, size_t level) const;
+ size_t getDepth(GLenum target, size_t level) const;
+ GLenum getInternalFormat(GLenum target, size_t level) const;
+
+ bool isSamplerComplete(const SamplerState &samplerState, const Data &data) const;
+ bool isCubeComplete() const;
+
+ virtual Error setImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size, GLenum format, GLenum type,
+ const PixelUnpackState &unpack, const uint8_t *pixels);
+ virtual Error setSubImage(GLenum target, size_t level, const Box &area, GLenum format, GLenum type,
+ const PixelUnpackState &unpack, const uint8_t *pixels);
+
+ virtual Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size,
+ const PixelUnpackState &unpack, const uint8_t *pixels);
+ virtual Error setCompressedSubImage(GLenum target, size_t level, const Box &area, GLenum format,
+ const PixelUnpackState &unpack, const uint8_t *pixels);
+
+ virtual Error copyImage(GLenum target, size_t level, const Rectangle &sourceArea, GLenum internalFormat,
+ const Framebuffer *source);
+ virtual Error copySubImage(GLenum target, size_t level, const Offset &destOffset, const Rectangle &sourceArea,
+ const Framebuffer *source);
+
+ virtual Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const Extents &size);
+
+ virtual Error generateMipmaps();
+
+ // Texture serials provide a unique way of identifying a Texture that isn't a raw pointer.
+ // "id" is not good enough, as Textures can be deleted, then re-allocated with the same id.
+ unsigned int getTextureSerial() const;
+
+ bool isImmutable() const;
+ GLsizei immutableLevelCount();
+
+ void bindTexImage(egl::Surface *surface);
+ void releaseTexImage();
+
+ rx::TextureImpl *getImplementation() { return mTexture; }
+ const rx::TextureImpl *getImplementation() const { return mTexture; }
+
+ static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
+
+ private:
+ static unsigned int issueTextureSerial();
+
+ rx::TextureImpl *mTexture;
+
+ SamplerState mSamplerState;
+ GLenum mUsage;
+
+ GLsizei mImmutableLevelCount;
+
+ GLenum mTarget;
+
+
+ struct ImageDesc
+ {
+ Extents size;
+ GLenum internalFormat;
+
+ ImageDesc();
+ ImageDesc(const Extents &size, GLenum internalFormat);
+ };
+
+ const unsigned int mTextureSerial;
+ static unsigned int mCurrentTextureSerial;
+
+ GLenum getBaseImageTarget() const;
+ size_t getExpectedMipLevels() const;
+
+ bool computeSamplerCompleteness(const SamplerState &samplerState, const Data &data) const;
+ bool computeMipmapCompleteness(const gl::SamplerState &samplerState) const;
+ bool computeLevelCompleteness(GLenum target, size_t level, const gl::SamplerState &samplerState) const;
+
+ const ImageDesc &getImageDesc(GLenum target, size_t level) const;
+ void setImageDesc(GLenum target, size_t level, const ImageDesc &desc);
+ void setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInternalFormat);
+ void clearImageDesc(GLenum target, size_t level);
+ void clearImageDescs();
+
+ std::vector<ImageDesc> mImageDescs;
+
+ struct SamplerCompletenessCache
+ {
+ SamplerCompletenessCache();
+
+ bool cacheValid;
+
+ // All values that affect sampler completeness that are not stored within
+ // the texture itself
+ SamplerState samplerState;
+ bool filterable;
+ GLint clientVersion;
+ bool supportsNPOT;
+
+ // Result of the sampler completeness with the above parameters
+ bool samplerComplete;
+ };
+ mutable SamplerCompletenessCache mCompletenessCache;
+
+ egl::Surface *mBoundSurface;
+};
+
+}
+
+#endif // LIBANGLE_TEXTURE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/TransformFeedback.cpp b/src/3rdparty/angle/src/libANGLE/TransformFeedback.cpp
index bfa7072326..6effaca976 100644
--- a/src/3rdparty/angle/src/libGLESv2/TransformFeedback.cpp
+++ b/src/3rdparty/angle/src/libANGLE/TransformFeedback.cpp
@@ -4,8 +4,8 @@
// found in the LICENSE file.
//
-#include "libGLESv2/TransformFeedback.h"
-#include "libGLESv2/renderer/TransformFeedbackImpl.h"
+#include "libANGLE/TransformFeedback.h"
+#include "libANGLE/renderer/TransformFeedbackImpl.h"
namespace gl
{
diff --git a/src/3rdparty/angle/src/libGLESv2/TransformFeedback.h b/src/3rdparty/angle/src/libANGLE/TransformFeedback.h
index 885a4fe172..7673db93ff 100644
--- a/src/3rdparty/angle/src/libGLESv2/TransformFeedback.h
+++ b/src/3rdparty/angle/src/libANGLE/TransformFeedback.h
@@ -4,11 +4,12 @@
// found in the LICENSE file.
//
-#ifndef LIBGLESV2_TRANSFORM_FEEDBACK_H_
-#define LIBGLESV2_TRANSFORM_FEEDBACK_H_
+#ifndef LIBANGLE_TRANSFORM_FEEDBACK_H_
+#define LIBANGLE_TRANSFORM_FEEDBACK_H_
+
+#include "libANGLE/RefCountObject.h"
#include "common/angleutils.h"
-#include "common/RefCountObject.h"
#include "angle_gl.h"
@@ -37,8 +38,6 @@ class TransformFeedback : public RefCountObject
GLboolean isPaused() const;
private:
- DISALLOW_COPY_AND_ASSIGN(TransformFeedback);
-
rx::TransformFeedbackImpl* mTransformFeedback;
GLboolean mStarted;
@@ -48,4 +47,4 @@ class TransformFeedback : public RefCountObject
}
-#endif // LIBGLESV2_TRANSFORM_FEEDBACK_H_
+#endif // LIBANGLE_TRANSFORM_FEEDBACK_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Uniform.cpp b/src/3rdparty/angle/src/libANGLE/Uniform.cpp
index bd0cd2eeec..f161b9d6bd 100644
--- a/src/3rdparty/angle/src/libGLESv2/Uniform.cpp
+++ b/src/3rdparty/angle/src/libANGLE/Uniform.cpp
@@ -4,10 +4,12 @@
// found in the LICENSE file.
//
-#include "libGLESv2/Uniform.h"
+#include "libANGLE/Uniform.h"
#include "common/utilities.h"
+#include <cstring>
+
namespace gl
{
@@ -75,7 +77,7 @@ size_t LinkedUniform::dataSize() const
bool LinkedUniform::isSampler() const
{
- return IsSampler(type);
+ return IsSamplerType(type);
}
UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize)
diff --git a/src/3rdparty/angle/src/libGLESv2/Uniform.h b/src/3rdparty/angle/src/libANGLE/Uniform.h
index 633d70bb19..dcf30f23cc 100644
--- a/src/3rdparty/angle/src/libGLESv2/Uniform.h
+++ b/src/3rdparty/angle/src/libANGLE/Uniform.h
@@ -4,24 +4,22 @@
// found in the LICENSE file.
//
-#ifndef LIBGLESV2_UNIFORM_H_
-#define LIBGLESV2_UNIFORM_H_
-
-#include "common/debug.h"
-#include "common/blocklayout.h"
-
-#include "libGLESv2/angletypes.h"
-
-#include "angle_gl.h"
+#ifndef LIBANGLE_UNIFORM_H_
+#define LIBANGLE_UNIFORM_H_
#include <string>
#include <vector>
+#include "angle_gl.h"
+#include "common/debug.h"
+#include "compiler/translator/blocklayout.h"
+#include "libANGLE/angletypes.h"
+
namespace gl
{
// Helper struct representing a single shader uniform
-struct LinkedUniform
+struct LinkedUniform : angle::NonCopyable
{
LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, const int blockIndex, const sh::BlockMemberInfo &blockInfo);
@@ -55,7 +53,7 @@ struct LinkedUniform
};
// Helper struct representing a single shader uniform block
-struct UniformBlock
+struct UniformBlock : angle::NonCopyable
{
// use GL_INVALID_INDEX for non-array elements
UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize);
@@ -76,4 +74,4 @@ struct UniformBlock
}
-#endif // LIBGLESV2_UNIFORM_H_
+#endif // LIBANGLE_UNIFORM_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/VertexArray.cpp b/src/3rdparty/angle/src/libANGLE/VertexArray.cpp
index f8ca661062..f0aded905d 100644
--- a/src/3rdparty/angle/src/libGLESv2/VertexArray.cpp
+++ b/src/3rdparty/angle/src/libANGLE/VertexArray.cpp
@@ -6,9 +6,9 @@
// Implementation of the state class for mananging GLES 3 Vertex Array Objects.
//
-#include "libGLESv2/VertexArray.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/renderer/VertexArrayImpl.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/renderer/VertexArrayImpl.h"
namespace gl
{
@@ -59,6 +59,11 @@ const VertexAttribute& VertexArray::getVertexAttribute(size_t attributeIndex) co
return mVertexAttributes[attributeIndex];
}
+const std::vector<VertexAttribute> &VertexArray::getVertexAttributes() const
+{
+ return mVertexAttributes;
+}
+
void VertexArray::setVertexAttribDivisor(GLuint index, GLuint divisor)
{
ASSERT(index < getMaxAttribs());
@@ -93,4 +98,4 @@ void VertexArray::setElementArrayBuffer(Buffer *buffer)
mVertexArray->setElementArrayBuffer(buffer);
}
-} \ No newline at end of file
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/VertexArray.h b/src/3rdparty/angle/src/libANGLE/VertexArray.h
index a724c0be1c..5c79b9953d 100644
--- a/src/3rdparty/angle/src/libGLESv2/VertexArray.h
+++ b/src/3rdparty/angle/src/libANGLE/VertexArray.h
@@ -10,12 +10,12 @@
// by the vertex processor is encapsulated in a vertex array object.
//
-#ifndef LIBGLESV2_VERTEXARRAY_H_
-#define LIBGLESV2_VERTEXARRAY_H_
+#ifndef LIBANGLE_VERTEXARRAY_H_
+#define LIBANGLE_VERTEXARRAY_H_
-#include "common/RefCountObject.h"
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/VertexAttribute.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/VertexAttribute.h"
#include <vector>
@@ -37,18 +37,22 @@ class VertexArray
GLuint id() const;
const VertexAttribute& getVertexAttribute(size_t attributeIndex) const;
+ const std::vector<VertexAttribute> &getVertexAttributes() const;
+
void detachBuffer(GLuint bufferName);
void setVertexAttribDivisor(GLuint index, GLuint divisor);
void enableAttribute(unsigned int attributeIndex, bool enabledState);
void setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
- const VertexAttribute* getVertexAttributes() const { return &mVertexAttributes[0]; }
Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); }
void setElementArrayBuffer(Buffer *buffer);
GLuint getElementArrayBufferId() const { return mElementArrayBuffer.id(); }
size_t getMaxAttribs() const { return mVertexAttributes.size(); }
+ rx::VertexArrayImpl *getImplementation() { return mVertexArray; }
+ const rx::VertexArrayImpl *getImplementation() const { return mVertexArray; }
+
private:
GLuint mId;
@@ -59,4 +63,4 @@ class VertexArray
}
-#endif // LIBGLESV2_VERTEXARRAY_H_
+#endif // LIBANGLE_VERTEXARRAY_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/VertexAttribute.cpp b/src/3rdparty/angle/src/libANGLE/VertexAttribute.cpp
index 1096856b8a..19934e7fac 100644
--- a/src/3rdparty/angle/src/libGLESv2/VertexAttribute.cpp
+++ b/src/3rdparty/angle/src/libANGLE/VertexAttribute.cpp
@@ -6,7 +6,7 @@
// Implementation of the state class for mananging GLES 3 Vertex Array Objects.
//
-#include "libGLESv2/VertexAttribute.h"
+#include "libANGLE/VertexAttribute.h"
namespace gl
{
@@ -23,6 +23,24 @@ VertexAttribute::VertexAttribute()
{
}
+bool operator==(const VertexAttribute &a, const VertexAttribute &b)
+{
+ return a.enabled == b.enabled &&
+ a.type == b.type &&
+ a.size == b.size &&
+ a.normalized == b.normalized &&
+ a.pureInteger == b.pureInteger &&
+ a.stride == b.stride &&
+ a.pointer == b.pointer &&
+ a.buffer.get() == b.buffer.get() &&
+ a.divisor == b.divisor;
+}
+
+bool operator!=(const VertexAttribute &a, const VertexAttribute &b)
+{
+ return !(a == b);
+}
+
size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib)
{
GLuint size = attrib.size;
@@ -52,4 +70,4 @@ size_t ComputeVertexAttributeStride(const VertexAttribute& attrib)
return attrib.stride ? attrib.stride : ComputeVertexAttributeTypeSize(attrib);
}
-} \ No newline at end of file
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/VertexAttribute.h b/src/3rdparty/angle/src/libANGLE/VertexAttribute.h
index e9757b618b..bdffe97466 100644
--- a/src/3rdparty/angle/src/libGLESv2/VertexAttribute.h
+++ b/src/3rdparty/angle/src/libANGLE/VertexAttribute.h
@@ -6,10 +6,10 @@
// Helper structure describing a single vertex attribute
//
-#ifndef LIBGLESV2_VERTEXATTRIBUTE_H_
-#define LIBGLESV2_VERTEXATTRIBUTE_H_
+#ifndef LIBANGLE_VERTEXATTRIBUTE_H_
+#define LIBANGLE_VERTEXATTRIBUTE_H_
-#include "libGLESv2/Buffer.h"
+#include "libANGLE/Buffer.h"
namespace gl
{
@@ -36,6 +36,9 @@ struct VertexAttribute
VertexAttribute();
};
+bool operator==(const VertexAttribute &a, const VertexAttribute &b);
+bool operator!=(const VertexAttribute &a, const VertexAttribute &b);
+
template <typename T>
T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pname)
{
@@ -116,4 +119,4 @@ struct VertexAttribCurrentValueData
}
-#endif // LIBGLESV2_VERTEXATTRIBUTE_H_
+#endif // LIBANGLE_VERTEXATTRIBUTE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp b/src/3rdparty/angle/src/libANGLE/angletypes.cpp
index 5a0cfc5ad9..16879f8041 100644
--- a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
+++ b/src/3rdparty/angle/src/libANGLE/angletypes.cpp
@@ -6,17 +6,28 @@
// angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/State.h"
-#include "libGLESv2/VertexArray.h"
-
-#include <float.h>
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/State.h"
+#include "libANGLE/VertexArray.h"
namespace gl
{
+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;
+}
+
+bool operator!=(const Rectangle &a, const Rectangle &b)
+{
+ return !(a == b);
+}
+
SamplerState::SamplerState()
: minFilter(GL_NEAREST_MIPMAP_LINEAR),
magFilter(GL_LINEAR),
@@ -26,8 +37,8 @@ SamplerState::SamplerState()
maxAnisotropy(1.0f),
baseLevel(0),
maxLevel(1000),
- minLod(-FLT_MAX),
- maxLod(FLT_MAX),
+ minLod(-1000.0f),
+ maxLod(1000.0f),
compareMode(GL_NONE),
compareFunc(GL_LEQUAL),
swizzleRed(GL_RED),
@@ -42,6 +53,31 @@ bool SamplerState::swizzleRequired() const
swizzleBlue != GL_BLUE || swizzleAlpha != GL_ALPHA;
}
+bool SamplerState::operator==(const SamplerState &other) const
+{
+ return minFilter == other.minFilter &&
+ magFilter == other.magFilter &&
+ wrapS == other.wrapS &&
+ wrapT == other.wrapT &&
+ wrapR == other.wrapR &&
+ maxAnisotropy == other.maxAnisotropy &&
+ baseLevel == other.baseLevel &&
+ maxLevel == other.maxLevel &&
+ minLod == other.minLod &&
+ maxLod == other.maxLod &&
+ compareMode == other.compareMode &&
+ compareFunc == other.compareFunc &&
+ swizzleRed == other.swizzleRed &&
+ swizzleGreen == other.swizzleGreen &&
+ swizzleBlue == other.swizzleBlue &&
+ swizzleAlpha == other.swizzleAlpha;
+}
+
+bool SamplerState::operator!=(const SamplerState &other) const
+{
+ return !(*this == other);
+}
+
static void MinMax(int a, int b, int *minimum, int *maximum)
{
if (a < b)
@@ -151,13 +187,13 @@ VertexFormat::VertexFormat(const VertexAttribute &attrib, GLenum currentValueTyp
}
void VertexFormat::GetInputLayout(VertexFormat *inputLayout,
- ProgramBinary *programBinary,
+ Program *program,
const State &state)
{
- const VertexAttribute *vertexAttributes = state.getVertexArray()->getVertexAttributes();
- for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+ const std::vector<VertexAttribute> &vertexAttributes = state.getVertexArray()->getVertexAttributes();
+ for (unsigned int attributeIndex = 0; attributeIndex < vertexAttributes.size(); attributeIndex++)
{
- int semanticIndex = programBinary->getSemanticIndex(attributeIndex);
+ int semanticIndex = program->getSemanticIndex(attributeIndex);
if (semanticIndex != -1)
{
diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.h b/src/3rdparty/angle/src/libANGLE/angletypes.h
index 78fe6b0e26..e4e08b5512 100644
--- a/src/3rdparty/angle/src/libGLESv2/angletypes.h
+++ b/src/3rdparty/angle/src/libANGLE/angletypes.h
@@ -6,17 +6,20 @@
// angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2
-#ifndef LIBGLESV2_ANGLETYPES_H_
-#define LIBGLESV2_ANGLETYPES_H_
+#ifndef LIBANGLE_ANGLETYPES_H_
+#define LIBANGLE_ANGLETYPES_H_
-#include "libGLESv2/Constants.h"
-#include "common/RefCountObject.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/RefCountObject.h"
+
+#include <stdint.h>
+#include <float.h>
namespace gl
{
class Buffer;
class State;
-class ProgramBinary;
+class Program;
struct VertexAttribute;
struct VertexAttribCurrentValueData;
@@ -38,6 +41,21 @@ struct Color
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);
+}
+
typedef Color<float> ColorF;
typedef Color<int> ColorI;
typedef Color<unsigned int> ColorUI;
@@ -53,21 +71,19 @@ struct Rectangle
Rectangle(int x_in, int y_in, int width_in, int height_in) : x(x_in), y(y_in), width(width_in), height(height_in) { }
};
+bool operator==(const Rectangle &a, const Rectangle &b);
+bool operator!=(const Rectangle &a, const Rectangle &b);
+
bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection);
-struct Box
+struct Offset
{
int x;
int y;
int z;
- int width;
- int height;
- int depth;
- 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) { }
- bool operator==(const Box &other) const;
- bool operator!=(const Box &other) const;
+ Offset() : x(0), y(0), z(0) { }
+ Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) { }
};
struct Extents
@@ -78,8 +94,27 @@ struct Extents
Extents() : width(0), height(0), depth(0) { }
Extents(int width_, int height_, int depth_) : width(width_), height(height_), depth(depth_) { }
+
+ bool empty() const { return (width * height * depth) == 0; }
+};
+
+struct Box
+{
+ int x;
+ int y;
+ int z;
+ int width;
+ int height;
+ int depth;
+
+ 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) { }
+ Box(const Offset &offset, const Extents &size) : x(offset.x), y(offset.y), z(offset.z), width(size.width), height(size.height), depth(size.depth) { }
+ bool operator==(const Box &other) const;
+ bool operator!=(const Box &other) const;
};
+
struct RasterizerState
{
bool cullFace;
@@ -162,42 +197,37 @@ struct SamplerState
GLenum swizzleAlpha;
bool swizzleRequired() const;
-};
-
-struct ClearParameters
-{
- bool clearColor[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
- ColorF colorFClearValue;
- ColorI colorIClearValue;
- ColorUI colorUIClearValue;
- GLenum colorClearType;
- bool colorMaskRed;
- bool colorMaskGreen;
- bool colorMaskBlue;
- bool colorMaskAlpha;
-
- bool clearDepth;
- float depthClearValue;
-
- bool clearStencil;
- GLint stencilClearValue;
- GLuint stencilWriteMask;
- bool scissorEnabled;
- Rectangle scissor;
+ bool operator==(const SamplerState &other) const;
+ bool operator!=(const SamplerState &other) const;
};
struct PixelUnpackState
{
BindingPointer<Buffer> pixelBuffer;
GLint alignment;
+ GLint rowLength;
+ GLint skipRows;
+ GLint skipPixels;
+ GLint imageHeight;
+ GLint skipImages;
PixelUnpackState()
- : alignment(4)
+ : alignment(4),
+ rowLength(0),
+ skipRows(0),
+ skipPixels(0),
+ imageHeight(0),
+ skipImages(0)
{}
- explicit PixelUnpackState(GLint alignmentIn)
- : alignment(alignmentIn)
+ PixelUnpackState(GLint alignmentIn, GLint rowLengthIn)
+ : alignment(alignmentIn),
+ rowLength(rowLengthIn),
+ skipRows(0),
+ skipPixels(0),
+ imageHeight(0),
+ skipImages(0)
{}
};
@@ -206,15 +236,24 @@ struct PixelPackState
BindingPointer<Buffer> pixelBuffer;
GLint alignment;
bool reverseRowOrder;
+ GLint rowLength;
+ GLint skipRows;
+ GLint skipPixels;
PixelPackState()
: alignment(4),
- reverseRowOrder(false)
+ reverseRowOrder(false),
+ rowLength(0),
+ skipRows(0),
+ skipPixels(0)
{}
explicit PixelPackState(GLint alignmentIn, bool reverseRowOrderIn)
: alignment(alignmentIn),
- reverseRowOrder(reverseRowOrderIn)
+ reverseRowOrder(reverseRowOrderIn),
+ rowLength(0),
+ skipRows(0),
+ skipPixels(0)
{}
};
@@ -231,7 +270,7 @@ struct VertexFormat
VertexFormat(const VertexAttribute &attribute, GLenum currentValueType);
static void GetInputLayout(VertexFormat *inputLayout,
- ProgramBinary *programBinary,
+ Program *program,
const State& currentValues);
bool operator==(const VertexFormat &other) const;
@@ -244,14 +283,41 @@ struct VertexFormat
namespace rx
{
-enum VertexConversionType
+enum VendorID : uint32_t
{
- VERTEX_CONVERT_NONE = 0,
- VERTEX_CONVERT_CPU = 1,
- VERTEX_CONVERT_GPU = 2,
- VERTEX_CONVERT_BOTH = 3
+ VENDOR_ID_AMD = 0x1002,
+ VENDOR_ID_INTEL = 0x8086,
+ VENDOR_ID_NVIDIA = 0x10DE,
};
+// Downcast a base implementation object (EG TextureImpl to TextureD3D)
+template <typename DestT, typename SrcT>
+inline DestT *GetAs(SrcT *src)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(DestT*, src));
+ return static_cast<DestT*>(src);
+}
+
+template <typename DestT, typename SrcT>
+inline const DestT *GetAs(const SrcT *src)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(const DestT*, src));
+ return static_cast<const DestT*>(src);
+}
+
+// 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 const DestT *GetImplAs(const SrcT *src)
+{
+ return GetAs<const DestT>(src->getImplementation());
+}
+
}
-#endif // LIBGLESV2_ANGLETYPES_H_
+#endif // LIBANGLE_ANGLETYPES_H_
diff --git a/src/3rdparty/angle/src/common/features.h b/src/3rdparty/angle/src/libANGLE/features.h
index b49a0ee852..fbe013f47d 100644
--- a/src/3rdparty/angle/src/common/features.h
+++ b/src/3rdparty/angle/src/libANGLE/features.h
@@ -4,6 +4,9 @@
// found in the LICENSE file.
//
+#ifndef LIBANGLE_FEATURES_H_
+#define LIBANGLE_FEATURES_H_
+
#define ANGLE_DISABLED 0
#define ANGLE_ENABLED 1
@@ -33,3 +36,5 @@
#if !defined(ANGLE_SHADER_DEBUG_INFO)
#define ANGLE_SHADER_DEBUG_INFO ANGLE_DISABLED
#endif
+
+#endif // LIBANGLE_FEATURES_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/formatutils.cpp b/src/3rdparty/angle/src/libANGLE/formatutils.cpp
index 8674d5337f..51e6a5a65d 100644
--- a/src/3rdparty/angle/src/libGLESv2/formatutils.cpp
+++ b/src/3rdparty/angle/src/libANGLE/formatutils.cpp
@@ -7,12 +7,10 @@
// formatutils.cpp: Queries for GL image formats.
#include "common/mathutil.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/imageformats.h"
-#include "libGLESv2/renderer/copyimage.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/renderer/Renderer.h"
namespace gl
{
@@ -21,145 +19,137 @@ namespace gl
// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
// format and type combinations.
-FormatType::FormatType()
- : internalFormat(GL_NONE),
- colorWriteFunction(NULL)
-{
-}
-
typedef std::pair<GLenum, GLenum> FormatTypePair;
-typedef std::pair<FormatTypePair, FormatType> FormatPair;
-typedef std::map<FormatTypePair, FormatType> FormatMap;
+typedef std::pair<FormatTypePair, GLenum> FormatPair;
+typedef std::map<FormatTypePair, GLenum> FormatMap;
// A helper function to insert data into the format map with fewer characters.
-static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat, ColorWriteFunction writeFunc)
+static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat)
{
- FormatType info;
- info.internalFormat = internalFormat;
- info.colorWriteFunction = writeFunc;
- map->insert(FormatPair(FormatTypePair(format, type), info));
+ map->insert(FormatPair(FormatTypePair(format, type), internalFormat));
}
FormatMap BuildFormatMap()
{
FormatMap map;
- using namespace rx;
-
- // | Format | Type | Internal format | Color write function |
- InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8, WriteColor<R8G8B8A8, GLfloat> );
- InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM, WriteColor<R8G8B8A8S, GLfloat> );
- InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, WriteColor<R4G4B4A4, GLfloat> );
- InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, WriteColor<R5G5B5A1, GLfloat> );
- InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2, WriteColor<R10G10B10A2, GLfloat> );
- InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F, WriteColor<R32G32B32A32F, GLfloat>);
- InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F, WriteColor<R16G16B16A16F, GLfloat>);
- InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F, WriteColor<R16G16B16A16F, GLfloat>);
-
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI, WriteColor<R8G8B8A8, GLuint> );
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I, WriteColor<R8G8B8A8S, GLint> );
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI, WriteColor<R16G16B16A16, GLuint> );
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I, WriteColor<R16G16B16A16S, GLint> );
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI, WriteColor<R32G32B32A32, GLuint> );
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I, WriteColor<R32G32B32A32S, GLint> );
- InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI, WriteColor<R10G10B10A2, GLuint> );
-
- InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8, WriteColor<R8G8B8, GLfloat> );
- InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM, WriteColor<R8G8B8S, GLfloat> );
- InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565, WriteColor<R5G6B5, GLfloat> );
- InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F, WriteColor<R11G11B10F, GLfloat> );
- InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5, WriteColor<R9G9B9E5, GLfloat> );
- InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F, WriteColor<R32G32B32F, GLfloat> );
- InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F, WriteColor<R16G16B16F, GLfloat> );
- InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F, WriteColor<R16G16B16F, GLfloat> );
-
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI, WriteColor<R8G8B8, GLuint> );
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I, WriteColor<R8G8B8S, GLint> );
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI, WriteColor<R16G16B16, GLuint> );
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I, WriteColor<R16G16B16S, GLint> );
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI, WriteColor<R32G32B32, GLuint> );
- InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I, WriteColor<R32G32B32S, GLint> );
-
- InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8, WriteColor<R8G8, GLfloat> );
- InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM, WriteColor<R8G8S, GLfloat> );
- InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F, WriteColor<R32G32F, GLfloat> );
- InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F, WriteColor<R16G16F, GLfloat> );
- InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F, WriteColor<R16G16F, GLfloat> );
-
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI, WriteColor<R8G8, GLuint> );
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I, WriteColor<R8G8S, GLint> );
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI, WriteColor<R16G16, GLuint> );
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I, WriteColor<R16G16S, GLint> );
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI, WriteColor<R32G32, GLuint> );
- InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I, WriteColor<R32G32S, GLint> );
-
- InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8, WriteColor<R8, GLfloat> );
- InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM, WriteColor<R8S, GLfloat> );
- InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F, WriteColor<R32F, GLfloat> );
- InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F, WriteColor<R16F, GLfloat> );
- InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F, WriteColor<R16F, GLfloat> );
-
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI, WriteColor<R8, GLuint> );
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I, WriteColor<R8S, GLint> );
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI, WriteColor<R16, GLuint> );
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I, WriteColor<R16S, GLint> );
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI, WriteColor<R32, GLuint> );
- InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I, WriteColor<R32S, GLint> );
-
- InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT, WriteColor<L8A8, GLfloat> );
- InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT, WriteColor<L8, GLfloat> );
- InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT, WriteColor<A8, GLfloat> );
- InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT, WriteColor<L32A32F, GLfloat> );
- InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT, WriteColor<L32F, GLfloat> );
- InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT, WriteColor<A32F, GLfloat> );
- InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat> );
- InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat> );
- InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT, WriteColor<L16F, GLfloat> );
- InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT, WriteColor<L16F, GLfloat> );
- InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT, WriteColor<A16F, GLfloat> );
- InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT, WriteColor<A16F, GLfloat> );
-
- InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT, WriteColor<B8G8R8A8, GLfloat> );
- InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX, WriteColor<B4G4R4A4, GLfloat> );
- InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX, WriteColor<B5G5R5A1, GLfloat> );
-
- InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8, WriteColor<R8G8B8, GLfloat> );
- InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8, WriteColor<R8G8B8A8, GLfloat> );
-
- InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, NULL );
- InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL );
- InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL );
- InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL );
-
- InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16, NULL );
- InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES, NULL );
- InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F, NULL );
-
- InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8, NULL );
-
- InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8, NULL );
- InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8, NULL );
+ // | Format | Type | Internal format |
+ InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);
+ InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM);
+ InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4);
+ InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1);
+ InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2);
+ InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F);
+ InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F);
+ InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F);
+
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI);
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I);
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI);
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I);
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI);
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I);
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI);
+
+ InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8);
+ InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM);
+ InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565);
+ InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F);
+ InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5);
+ InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F);
+ InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F);
+ InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F);
+
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI);
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I);
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI);
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I);
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI);
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I);
+
+ InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8);
+ InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM);
+ InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F);
+ InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F);
+ InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F);
+
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI);
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I);
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI);
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I);
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI);
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I);
+
+ InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8);
+ InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM);
+ InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F);
+ InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F);
+ InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F);
+
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI);
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I);
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI);
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I);
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI);
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I);
+
+ InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT);
+ InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT);
+ InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT);
+ InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT);
+ InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT);
+ InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT);
+ InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT);
+ InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT);
+ InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT);
+ InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT);
+ InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT);
+ InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT);
+
+ InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT);
+ InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX);
+ InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX);
+
+ InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8);
+ InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8);
+
+ InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
+ InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
+ InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
+ InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
+
+ InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16);
+ InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES);
+ InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F);
+
+ InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8);
+
+ InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8);
+ InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8);
return map;
}
Type::Type()
: bytes(0),
+ bytesShift(0),
specialInterpretation(false)
{
}
-// Map of sizes of input types
-typedef std::pair<GLenum, Type> TypeInfoPair;
-typedef std::map<GLenum, Type> TypeInfoMap;
-
-static inline void InsertTypeInfo(TypeInfoMap *map, GLenum type, GLuint bytes, bool specialInterpretation)
+static Type GenTypeInfo(GLuint bytes, bool specialInterpretation)
{
Type info;
info.bytes = bytes;
+ GLuint i = 0;
+ while ((1u << i) < bytes)
+ {
+ ++i;
+ }
+ info.bytesShift = i;
+ ASSERT((1u << info.bytesShift) == bytes);
info.specialInterpretation = specialInterpretation;
-
- map->insert(std::make_pair(type, info));
+ return info;
}
bool operator<(const Type& a, const Type& b)
@@ -167,34 +157,6 @@ bool operator<(const Type& a, const Type& b)
return memcmp(&a, &b, sizeof(Type)) < 0;
}
-static TypeInfoMap BuildTypeInfoMap()
-{
- TypeInfoMap map;
-
- InsertTypeInfo(&map, GL_UNSIGNED_BYTE, 1, false);
- InsertTypeInfo(&map, GL_BYTE, 1, false);
- InsertTypeInfo(&map, GL_UNSIGNED_SHORT, 2, false);
- InsertTypeInfo(&map, GL_SHORT, 2, false);
- InsertTypeInfo(&map, GL_UNSIGNED_INT, 4, false);
- InsertTypeInfo(&map, GL_INT, 4, false);
- InsertTypeInfo(&map, GL_HALF_FLOAT, 2, false);
- InsertTypeInfo(&map, GL_HALF_FLOAT_OES, 2, false);
- InsertTypeInfo(&map, GL_FLOAT, 4, false);
- InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_6_5, 2, true );
- InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4, 2, true );
- InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_5_5_1, 2, true );
- InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, 2, true );
- InsertTypeInfo(&map, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, 2, true );
- InsertTypeInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, true );
- InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8, 4, true );
- InsertTypeInfo(&map, GL_UNSIGNED_INT_10F_11F_11F_REV, 4, true );
- InsertTypeInfo(&map, GL_UNSIGNED_INT_5_9_9_9_REV, 4, true );
- InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8_OES, 4, true );
- InsertTypeInfo(&map, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, true );
-
- return map;
-}
-
// Information about internal formats
static bool AlwaysSupported(GLuint, const Extensions &)
{
@@ -454,7 +416,7 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap()
map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::depthTextures>, RequireExt<&Extensions::depthTextures>, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8, DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, &Extensions::depthTextures>, RequireESOrExtOrExt<3, &Extensions::depthTextures, &Extensions::packedDepthStencil>, AlwaysSupported )));
map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8, DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireES<3>, RequireES<3>, AlwaysSupported )));
- map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, DepthStencilFormat( 0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, RequireES<2>, RequireES<2>, NeverSupported )));
+ // STENCIL_INDEX8 is special-cased, see around the bottom of the list.
// Luminance alpha formats
// | Internal format | | L | A | Format | Type | Component type | Supported | Renderable | Filterable |
@@ -511,6 +473,13 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap()
// From GL_ANGLE_texture_compression_dxt5
map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported)));
+ // 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 | |D |S |X | Format | Type | Component type | Supported | Renderable | Filterable |
+ map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, DepthStencilFormat(0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, NeverSupported)));
+
return map;
}
@@ -536,33 +505,59 @@ static FormatSet BuildAllSizedInternalFormatSet()
return result;
}
-const FormatType &GetFormatTypeInfo(GLenum format, GLenum type)
-{
- static const FormatMap formatMap = BuildFormatMap();
- FormatMap::const_iterator iter = formatMap.find(FormatTypePair(format, type));
- if (iter != formatMap.end())
- {
- return iter->second;
- }
- else
- {
- static const FormatType defaultInfo;
- return defaultInfo;
- }
-}
-
const Type &GetTypeInfo(GLenum type)
{
- static const TypeInfoMap infoMap = BuildTypeInfoMap();
- TypeInfoMap::const_iterator iter = infoMap.find(type);
- if (iter != infoMap.end())
+ switch (type)
{
- return iter->second;
- }
- else
- {
- static const Type defaultInfo;
- return defaultInfo;
+ case GL_UNSIGNED_BYTE:
+ case GL_BYTE:
+ {
+ static const Type info = GenTypeInfo(1, false);
+ return info;
+ }
+ case GL_UNSIGNED_SHORT:
+ case GL_SHORT:
+ case GL_HALF_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ {
+ static const Type info = GenTypeInfo(2, false);
+ return info;
+ }
+ case GL_UNSIGNED_INT:
+ case GL_INT:
+ case GL_FLOAT:
+ {
+ static const Type info = GenTypeInfo(4, false);
+ return info;
+ }
+ 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 const Type info = GenTypeInfo(2, true);
+ return info;
+ }
+ 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 const Type info = GenTypeInfo(4, true);
+ return info;
+ }
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ {
+ static const Type info = GenTypeInfo(8, true);
+ return info;
+ }
+ default:
+ {
+ static const Type defaultInfo;
+ return defaultInfo;
+ }
}
}
@@ -581,18 +576,28 @@ const InternalFormat &GetInternalFormatInfo(GLenum internalFormat)
}
}
-GLuint InternalFormat::computeRowPitch(GLenum type, GLsizei width, GLint alignment) const
+GLuint InternalFormat::computeRowPitch(GLenum formatType, GLsizei width, GLint alignment, GLint rowLength) const
{
ASSERT(alignment > 0 && isPow2(alignment));
- return rx::roundUp(computeBlockSize(type, width, 1), static_cast<GLuint>(alignment));
+ GLuint rowBytes;
+ if (rowLength > 0)
+ {
+ ASSERT(!compressed);
+ rowBytes = pixelBytes * rowLength;
+ }
+ else
+ {
+ rowBytes = computeBlockSize(formatType, width, 1);
+ }
+ return rx::roundUp(rowBytes, static_cast<GLuint>(alignment));
}
-GLuint InternalFormat::computeDepthPitch(GLenum type, GLsizei width, GLsizei height, GLint alignment) const
+GLuint InternalFormat::computeDepthPitch(GLenum formatType, GLsizei width, GLsizei height, GLint alignment, GLint rowLength) const
{
- return computeRowPitch(type, width, alignment) * height;
+ return computeRowPitch(formatType, width, alignment, rowLength) * height;
}
-GLuint InternalFormat::computeBlockSize(GLenum type, GLsizei width, GLsizei height) const
+GLuint InternalFormat::computeBlockSize(GLenum formatType, GLsizei width, GLsizei height) const
{
if (compressed)
{
@@ -602,7 +607,7 @@ GLuint InternalFormat::computeBlockSize(GLenum type, GLsizei width, GLsizei heig
}
else
{
- const Type &typeInfo = GetTypeInfo(type);
+ const Type &typeInfo = GetTypeInfo(formatType);
if (typeInfo.specialInterpretation)
{
return typeInfo.bytes * width * height;
@@ -617,7 +622,23 @@ GLuint InternalFormat::computeBlockSize(GLenum type, GLsizei width, GLsizei heig
GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)
{
const InternalFormat& formatInfo = GetInternalFormatInfo(internalFormat);
- return (formatInfo.pixelBytes > 0) ? internalFormat : GetFormatTypeInfo(internalFormat, type).internalFormat;
+ if (formatInfo.pixelBytes > 0)
+ {
+ return internalFormat;
+ }
+ else
+ {
+ static const FormatMap formatMap = BuildFormatMap();
+ FormatMap::const_iterator iter = formatMap.find(FormatTypePair(internalFormat, type));
+ if (iter != formatMap.end())
+ {
+ return iter->second;
+ }
+ else
+ {
+ return GL_NONE;
+ }
+ }
}
const FormatSet &GetAllSizedInternalFormats()
diff --git a/src/3rdparty/angle/src/libANGLE/formatutils.h b/src/3rdparty/angle/src/libANGLE/formatutils.h
new file mode 100644
index 0000000000..37d4a8f8ef
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/formatutils.h
@@ -0,0 +1,81 @@
+//
+// Copyright (c) 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 "libANGLE/Caps.h"
+#include "libANGLE/angletypes.h"
+
+#include "angle_gl.h"
+
+#include <cstddef>
+#include <stdint.h>
+
+namespace gl
+{
+
+struct Type
+{
+ Type();
+
+ GLuint bytes;
+ GLuint bytesShift; // Bit shift by this value to effectively divide/multiply by "bytes" in a more optimal way
+ bool specialInterpretation;
+};
+const Type &GetTypeInfo(GLenum type);
+
+struct InternalFormat
+{
+ InternalFormat();
+
+ 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;
+
+ GLenum format;
+ GLenum type;
+
+ GLenum componentType;
+ GLenum colorEncoding;
+
+ typedef bool (*SupportCheckFunction)(GLuint, const Extensions &);
+ SupportCheckFunction textureSupport;
+ SupportCheckFunction renderSupport;
+ SupportCheckFunction filterSupport;
+
+ GLuint computeRowPitch(GLenum formatType, GLsizei width, GLint alignment, GLint rowLength) const;
+ GLuint computeDepthPitch(GLenum formatType, GLsizei width, GLsizei height, GLint alignment, GLint rowLength) const;
+ GLuint computeBlockSize(GLenum formatType, GLsizei width, GLsizei height) const;
+};
+const InternalFormat &GetInternalFormatInfo(GLenum internalFormat);
+
+GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);
+
+typedef std::set<GLenum> FormatSet;
+const FormatSet &GetAllSizedInternalFormats();
+
+}
+
+#endif // LIBANGLE_FORMATUTILS_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/queryconversions.cpp b/src/3rdparty/angle/src/libANGLE/queryconversions.cpp
index 7245902c51..460e346eac 100644
--- a/src/3rdparty/angle/src/libGLESv2/queryconversions.cpp
+++ b/src/3rdparty/angle/src/libANGLE/queryconversions.cpp
@@ -6,7 +6,7 @@
// queryconversions.cpp: Implementation of state query cast conversions
-#include "libGLESv2/Context.h"
+#include "libANGLE/Context.h"
#include "common/utilities.h"
namespace gl
diff --git a/src/3rdparty/angle/src/libGLESv2/queryconversions.h b/src/3rdparty/angle/src/libANGLE/queryconversions.h
index da7047f730..da7047f730 100644
--- a/src/3rdparty/angle/src/libGLESv2/queryconversions.h
+++ b/src/3rdparty/angle/src/libANGLE/queryconversions.h
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/BufferImpl.h
index c031effabd..9bc5eaff58 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/BufferImpl.h
@@ -6,18 +6,18 @@
// BufferImpl.h: Defines the abstract rx::BufferImpl class.
-#ifndef LIBGLESV2_RENDERER_BUFFERIMPL_H_
-#define LIBGLESV2_RENDERER_BUFFERIMPL_H_
+#ifndef LIBANGLE_RENDERER_BUFFERIMPL_H_
+#define LIBANGLE_RENDERER_BUFFERIMPL_H_
#include "common/angleutils.h"
-#include "libGLESv2/Buffer.h"
+#include "libANGLE/Buffer.h"
-#include <cstdint>
+#include <stdint.h>
namespace rx
{
-class BufferImpl
+class BufferImpl : angle::NonCopyable
{
public:
virtual ~BufferImpl() { }
@@ -27,9 +27,12 @@ class BufferImpl
virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0;
virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0;
virtual gl::Error unmap() = 0;
- virtual void markTransformFeedbackUsage() = 0;
+
+ // This method may not have a corresponding GL-backed function. It is necessary
+ // for validation, for certain indexed draw calls.
+ virtual gl::Error getData(const uint8_t **outData) = 0;
};
}
-#endif // LIBGLESV2_RENDERER_BUFFERIMPL_H_
+#endif // LIBANGLE_RENDERER_BUFFERIMPL_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/CompilerImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/CompilerImpl.h
new file mode 100644
index 0000000000..ccc78d8c2a
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/CompilerImpl.h
@@ -0,0 +1,30 @@
+//
+// Copyright (c) 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 "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() {}
+
+ virtual gl::Error release() = 0;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_COMPILERIMPL_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.cpp b/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.cpp
new file mode 100644
index 0000000000..7713ee2d6d
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.cpp
@@ -0,0 +1,58 @@
+//
+// Copyright (c) 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/Surface.h"
+
+namespace rx
+{
+
+DisplayImpl::DisplayImpl()
+ : mExtensionsInitialized(false),
+ mCapsInitialized(false)
+{
+}
+
+DisplayImpl::~DisplayImpl()
+{
+ while (!mSurfaceSet.empty())
+ {
+ destroySurface(*mSurfaceSet.begin());
+ }
+}
+
+void DisplayImpl::destroySurface(egl::Surface *surface)
+{
+ mSurfaceSet.erase(surface);
+ surface->release();
+}
+
+const egl::DisplayExtensions &DisplayImpl::getExtensions() const
+{
+ if (!mExtensionsInitialized)
+ {
+ generateExtensions(&mExtensions);
+ mExtensionsInitialized = true;
+ }
+
+ return mExtensions;
+}
+
+const egl::Caps &DisplayImpl::getCaps() const
+{
+ if (!mCapsInitialized)
+ {
+ generateCaps(&mCaps);
+ mCapsInitialized = true;
+ }
+
+ return mCaps;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.h
new file mode 100644
index 0000000000..381fa67f71
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.h
@@ -0,0 +1,99 @@
+//
+// Copyright (c) 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/angleutils.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/Renderer.h"
+
+#include <set>
+#include <vector>
+
+namespace egl
+{
+class AttributeMap;
+class Display;
+struct Config;
+class Surface;
+}
+
+namespace gl
+{
+class Context;
+}
+
+namespace rx
+{
+class SurfaceImpl;
+struct ConfigDesc;
+
+class DisplayImpl : angle::NonCopyable
+{
+ public:
+ DisplayImpl();
+ virtual ~DisplayImpl();
+
+ virtual egl::Error initialize(egl::Display *display) = 0;
+ virtual void terminate() = 0;
+
+ virtual egl::Error createWindowSurface(const egl::Config *configuration, EGLNativeWindowType window, const egl::AttributeMap &attribs,
+ SurfaceImpl **outSurface) = 0;
+ virtual egl::Error createPbufferSurface(const egl::Config *configuration, const egl::AttributeMap &attribs,
+ SurfaceImpl **outSurface) = 0;
+ virtual egl::Error createPbufferFromClientBuffer(const egl::Config *configuration, EGLClientBuffer shareHandle,
+ const egl::AttributeMap &attribs, SurfaceImpl **outSurface) = 0;
+ virtual egl::Error createPixmapSurface(const egl::Config *configuration, NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs, SurfaceImpl **outSurface) = 0;
+ virtual egl::Error createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs,
+ gl::Context **outContext) = 0;
+
+ virtual egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) = 0;
+
+ virtual egl::ConfigSet generateConfigs() const = 0;
+
+ virtual bool isDeviceLost() const = 0;
+ virtual bool testDeviceLost() = 0;
+ virtual egl::Error restoreLostDevice() = 0;
+
+ virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0;
+
+ virtual std::string getVendorString() const = 0;
+
+ const egl::Caps &getCaps() const;
+
+ typedef std::set<egl::Surface*> SurfaceSet;
+ const SurfaceSet &getSurfaceSet() const { return mSurfaceSet; }
+ SurfaceSet &getSurfaceSet() { return mSurfaceSet; }
+
+ void destroySurface(egl::Surface *surface);
+
+ const egl::DisplayExtensions &getExtensions() const;
+
+ protected:
+ // Place the surface set here so it can be accessible for handling
+ // context loss events. (It is shared between the Display and Impl.)
+ SurfaceSet mSurfaceSet;
+
+ 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;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_DISPLAYIMPL_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/FenceNVImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/FenceNVImpl.h
new file mode 100644
index 0000000000..3463921d6e
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/FenceNVImpl.h
@@ -0,0 +1,34 @@
+//
+// Copyright (c) 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 rx
+{
+
+class FenceNVImpl : angle::NonCopyable
+{
+ public:
+ FenceNVImpl() { };
+ virtual ~FenceNVImpl() { };
+
+ virtual gl::Error set() = 0;
+ virtual gl::Error test(bool flushCommandBuffer, GLboolean *outFinished) = 0;
+ virtual gl::Error finishFence(GLboolean *outFinished) = 0;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_FENCENVIMPL_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/FenceSyncImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/FenceSyncImpl.h
new file mode 100644
index 0000000000..321964113f
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/FenceSyncImpl.h
@@ -0,0 +1,35 @@
+//
+// Copyright (c) 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.
+//
+
+// FenceSyncImpl.h: Defines the rx::FenceSyncImpl class.
+
+#ifndef LIBANGLE_RENDERER_FENCESYNCIMPL_H_
+#define LIBANGLE_RENDERER_FENCESYNCIMPL_H_
+
+#include "libANGLE/Error.h"
+
+#include "common/angleutils.h"
+
+#include "angle_gl.h"
+
+namespace rx
+{
+
+class FenceSyncImpl : angle::NonCopyable
+{
+ public:
+ FenceSyncImpl() { };
+ virtual ~FenceSyncImpl() { };
+
+ virtual gl::Error set() = 0;
+ virtual gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) = 0;
+ virtual gl::Error serverWait(GLbitfield flags, GLuint64 timeout) = 0;
+ virtual gl::Error getStatus(GLint *outResult) = 0;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_FENCESYNCIMPL_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl.h
new file mode 100644
index 0000000000..728f949a0f
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl.h
@@ -0,0 +1,68 @@
+//
+// 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"
+
+namespace gl
+{
+class State;
+class Framebuffer;
+class FramebufferAttachment;
+struct Rectangle;
+}
+
+namespace rx
+{
+
+class FramebufferImpl : angle::NonCopyable
+{
+ public:
+ explicit FramebufferImpl(const gl::Framebuffer::Data &data) : mData(data) { }
+ virtual ~FramebufferImpl() { }
+
+ virtual void setColorAttachment(size_t index, const gl::FramebufferAttachment *attachment) = 0;
+ virtual void setDepthAttachment(const gl::FramebufferAttachment *attachment) = 0;
+ virtual void setStencilAttachment(const gl::FramebufferAttachment *attachment) = 0;
+ virtual void setDepthStencilAttachment(const gl::FramebufferAttachment *attachment) = 0;
+
+ virtual void setDrawBuffers(size_t count, const GLenum *buffers) = 0;
+ virtual void setReadBuffer(GLenum buffer) = 0;
+
+ virtual gl::Error invalidate(size_t count, const GLenum *attachments) = 0;
+ virtual gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) = 0;
+
+ virtual gl::Error clear(const gl::Data &data, GLbitfield mask) = 0;
+ virtual gl::Error clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) = 0;
+ virtual gl::Error clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) = 0;
+ virtual gl::Error clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) = 0;
+ virtual gl::Error clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) = 0;
+
+ virtual GLenum getImplementationColorReadFormat() const = 0;
+ virtual GLenum getImplementationColorReadType() const = 0;
+ virtual gl::Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const = 0;
+
+ virtual gl::Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
+ GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) = 0;
+
+ virtual GLenum checkStatus() const = 0;
+
+ const gl::Framebuffer::Data &getData() const { return mData; }
+
+ protected:
+ const gl::Framebuffer::Data &mData;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_FRAMEBUFFERIMPL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.h b/src/3rdparty/angle/src/libANGLE/renderer/Image.h
index 9071a88c67..62d854c9b6 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Image.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/Image.h
@@ -8,11 +8,11 @@
// renderer-specific classes which will define the interface to the underlying
// surfaces or resources.
-#ifndef LIBGLESV2_RENDERER_IMAGE_H_
-#define LIBGLESV2_RENDERER_IMAGE_H_
+#ifndef LIBANGLE_RENDERER_IMAGE_H_
+#define LIBANGLE_RENDERER_IMAGE_H_
#include "common/debug.h"
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
#include <GLES2/gl2.h>
@@ -20,6 +20,9 @@ namespace gl
{
class Framebuffer;
struct Rectangle;
+struct Extents;
+struct Box;
+struct Offset;
struct ImageIndex;
}
@@ -39,7 +42,6 @@ class Image
GLsizei getHeight() const { return mHeight; }
GLsizei getDepth() const { return mDepth; }
GLenum getInternalFormat() const { return mInternalFormat; }
- GLenum getActualFormat() const { return mActualFormat; }
GLenum getTarget() const { return mTarget; }
bool isRenderableFormat() const { return mRenderable; }
@@ -47,16 +49,13 @@ class Image
void markClean() {mDirty = false;}
virtual bool isDirty() const = 0;
- virtual bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) = 0;
+ virtual bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) = 0;
- virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input) = 0;
- virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input) = 0;
+ virtual gl::Error loadData(const gl::Box &area, GLint unpackAlignment, GLenum type, const void *input) = 0;
+ virtual gl::Error loadCompressedData(const gl::Box &area, const void *input) = 0;
- gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, gl::Framebuffer *source);
- virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source) = 0;
- virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
+ virtual gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) = 0;
+ virtual gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea,
const gl::ImageIndex &sourceIndex, TextureStorage *source) = 0;
protected:
@@ -64,7 +63,6 @@ class Image
GLsizei mHeight;
GLsizei mDepth;
GLenum mInternalFormat;
- GLenum mActualFormat;
bool mRenderable;
GLenum mTarget;
@@ -76,4 +74,4 @@ class Image
}
-#endif // LIBGLESV2_RENDERER_IMAGE_H_
+#endif // LIBANGLE_RENDERER_IMAGE_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/ImplFactory.h b/src/3rdparty/angle/src/libANGLE/renderer/ImplFactory.h
new file mode 100644
index 0000000000..d77e59f7df
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/ImplFactory.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.
+//
+// ImplFactory.h:
+// Factory interface for Impl objects.
+//
+
+#ifndef LIBANGLE_RENDERER_IMPLFACTORY_H_
+#define LIBANGLE_RENDERER_IMPLFACTORY_H_
+
+#include "libANGLE/Framebuffer.h"
+
+namespace rx
+{
+class BufferImpl;
+class CompilerImpl;
+class FenceNVImpl;
+class FenceSyncImpl;
+class FramebufferImpl;
+class ProgramImpl;
+class QueryImpl;
+class RenderbufferImpl;
+class ShaderImpl;
+class TextureImpl;
+class TransformFeedbackImpl;
+class VertexArrayImpl;
+
+class ImplFactory : angle::NonCopyable
+{
+ public:
+ ImplFactory() {}
+ virtual ~ImplFactory() {}
+
+ // Shader creation
+ virtual CompilerImpl *createCompiler(const gl::Data &data) = 0;
+ virtual ShaderImpl *createShader(GLenum type) = 0;
+ virtual ProgramImpl *createProgram() = 0;
+
+ // Framebuffer creation
+ virtual FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) = 0;
+ virtual FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) = 0;
+
+ // Texture creation
+ virtual TextureImpl *createTexture(GLenum target) = 0;
+
+ // Renderbuffer creation
+ virtual RenderbufferImpl *createRenderbuffer() = 0;
+
+ // Buffer creation
+ virtual BufferImpl *createBuffer() = 0;
+
+ // Vertex Array creation
+ virtual VertexArrayImpl *createVertexArray() = 0;
+
+ // Query and Fence creation
+ virtual QueryImpl *createQuery(GLenum type) = 0;
+ virtual FenceNVImpl *createFenceNV() = 0;
+ virtual FenceSyncImpl *createFenceSync() = 0;
+
+ // Transform Feedback creation
+ virtual TransformFeedbackImpl *createTransformFeedback() = 0;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_IMPLFACTORY_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/3rdparty/angle/src/libANGLE/renderer/IndexRangeCache.cpp
index d472e1499e..4a71cf4b45 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/IndexRangeCache.cpp
@@ -7,13 +7,11 @@
// IndexRangeCache.cpp: Defines the rx::IndexRangeCache class which stores information about
// ranges of indices.
-#include "libGLESv2/renderer/IndexRangeCache.h"
-#include "libGLESv2/formatutils.h"
+#include "libANGLE/renderer/IndexRangeCache.h"
+#include "libANGLE/formatutils.h"
#include "common/debug.h"
-#include <tuple>
-
namespace rx
{
@@ -48,10 +46,9 @@ RangeUI IndexRangeCache::ComputeRange(GLenum type, const GLvoid *indices, GLsize
}
}
-void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range,
- unsigned int streamOffset)
+void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range)
{
- mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(range, streamOffset);
+ mIndexRangeCache[IndexRange(type, offset, count)] = range;
}
void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size)
@@ -62,8 +59,8 @@ void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size)
IndexRangeMap::iterator i = mIndexRangeCache.begin();
while (i != mIndexRangeCache.end())
{
- unsigned int rangeStart = i->second.streamOffset;
- unsigned int rangeEnd = i->second.streamOffset + (gl::GetTypeInfo(i->first.type).bytes * i->first.count);
+ unsigned int rangeStart = i->first.offset;
+ unsigned int rangeEnd = i->first.offset + (gl::GetTypeInfo(i->first.type).bytes * i->first.count);
if (invalidateEnd < rangeStart || invalidateStart > rangeEnd)
{
@@ -71,25 +68,23 @@ void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size)
}
else
{
- i = mIndexRangeCache.erase(i);
+ mIndexRangeCache.erase(i++);
}
}
}
bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count,
- RangeUI *outRange, unsigned int *outStreamOffset) const
+ RangeUI *outRange) const
{
IndexRangeMap::const_iterator i = mIndexRangeCache.find(IndexRange(type, offset, count));
if (i != mIndexRangeCache.end())
{
- if (outRange) *outRange = i->second.range;
- if (outStreamOffset) *outStreamOffset = i->second.streamOffset;
+ if (outRange) *outRange = i->second;
return true;
}
else
{
if (outRange) *outRange = RangeUI(0, 0);
- if (outStreamOffset) *outStreamOffset = 0;
return false;
}
}
@@ -111,18 +106,9 @@ IndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c)
bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const
{
- return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count);
-}
-
-IndexRangeCache::IndexBounds::IndexBounds()
- : range(0, 0),
- streamOffset(0)
-{
-}
-
-IndexRangeCache::IndexBounds::IndexBounds(const RangeUI &rangeIn, unsigned int offset)
- : range(rangeIn), streamOffset(offset)
-{
+ if (type != rhs.type) return type < rhs.type;
+ if (offset != rhs.offset) return offset < rhs.offset;
+ return count < rhs.count;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h b/src/3rdparty/angle/src/libANGLE/renderer/IndexRangeCache.h
index a7d91e035b..77249f5ff6 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/IndexRangeCache.h
@@ -7,8 +7,8 @@
// IndexRangeCache.h: Defines the rx::IndexRangeCache class which stores information about
// ranges of indices.
-#ifndef LIBGLESV2_RENDERER_INDEXRANGECACHE_H_
-#define LIBGLESV2_RENDERER_INDEXRANGECACHE_H_
+#ifndef LIBANGLE_RENDERER_INDEXRANGECACHE_H_
+#define LIBANGLE_RENDERER_INDEXRANGECACHE_H_
#include "common/angleutils.h"
#include "common/mathutil.h"
@@ -23,10 +23,8 @@ namespace rx
class IndexRangeCache
{
public:
- void addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range,
- unsigned int streamOffset);
- bool findRange(GLenum type, unsigned int offset, GLsizei count, RangeUI *rangeOut,
- unsigned int *outStreamOffset) const;
+ void addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range);
+ bool findRange(GLenum type, unsigned int offset, GLsizei count, RangeUI *rangeOut) const;
void invalidateRange(unsigned int offset, unsigned int size);
void clear();
@@ -46,19 +44,10 @@ class IndexRangeCache
bool operator<(const IndexRange& rhs) const;
};
- struct IndexBounds
- {
- RangeUI range;
- unsigned int streamOffset;
-
- IndexBounds();
- IndexBounds(const RangeUI &range, unsigned int offset);
- };
-
- typedef std::map<IndexRange, IndexBounds> IndexRangeMap;
+ typedef std::map<IndexRange, RangeUI> IndexRangeMap;
IndexRangeMap mIndexRangeCache;
};
}
-#endif // LIBGLESV2_RENDERER_INDEXRANGECACHE_H
+#endif // LIBANGLE_RENDERER_INDEXRANGECACHE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp b/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.cpp
index f9fcad38a4..8fbc53768f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.cpp
@@ -6,10 +6,9 @@
// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
-#include "libGLESv2/renderer/ProgramImpl.h"
+#include "libANGLE/renderer/ProgramImpl.h"
#include "common/utilities.h"
-#include "libGLESv2/main.h"
namespace rx
{
@@ -35,6 +34,12 @@ unsigned int ParseAndStripArrayIndex(std::string* name)
}
+LinkResult::LinkResult(bool linkSuccess, const gl::Error &error)
+ : linkSuccess(linkSuccess),
+ error(error)
+{
+}
+
ProgramImpl::~ProgramImpl()
{
// Ensure that reset was called by the inherited class during destruction
@@ -137,6 +142,7 @@ GLuint ProgramImpl::getUniformBlockIndex(std::string name) const
void ProgramImpl::reset()
{
+ std::fill(mSemanticIndex, mSemanticIndex + ArraySize(mSemanticIndex), -1);
SafeDeleteContainer(mUniforms);
mUniformIndex.clear();
SafeDeleteContainer(mUniformBlocks);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.h
index 6aaa23cf89..1128ab6741 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.h
@@ -6,61 +6,50 @@
// ProgramImpl.h: Defines the abstract rx::ProgramImpl class.
-#ifndef LIBGLESV2_RENDERER_PROGRAMIMPL_H_
-#define LIBGLESV2_RENDERER_PROGRAMIMPL_H_
+#ifndef LIBANGLE_RENDERER_PROGRAMIMPL_H_
+#define LIBANGLE_RENDERER_PROGRAMIMPL_H_
#include "common/angleutils.h"
-#include "libGLESv2/BinaryStream.h"
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/Shader.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libANGLE/BinaryStream.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/renderer/Renderer.h"
#include <map>
namespace rx
{
-class ProgramImpl
+struct LinkResult
+{
+ bool linkSuccess;
+ gl::Error error;
+ LinkResult(bool linkSuccess, const gl::Error &error);
+};
+
+class ProgramImpl : angle::NonCopyable
{
public:
+ typedef int SemanticIndexArray[gl::MAX_VERTEX_ATTRIBS];
+
ProgramImpl() { }
virtual ~ProgramImpl();
- const std::vector<gl::LinkedUniform*> &getUniforms() const { return mUniforms; }
- const std::vector<gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; }
- const std::vector<gl::UniformBlock*> &getUniformBlocks() const { return mUniformBlocks; }
- const std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() const { return mTransformFeedbackLinkedVaryings; }
- const sh::Attribute *getShaderAttributes() const { return mShaderAttributes; }
-
- std::vector<gl::LinkedUniform*> &getUniforms() { return mUniforms; }
- std::vector<gl::VariableLocation> &getUniformIndices() { return mUniformIndex; }
- std::vector<gl::UniformBlock*> &getUniformBlocks() { return mUniformBlocks; }
- std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() { return mTransformFeedbackLinkedVaryings; }
- sh::Attribute *getShaderAttributes() { return mShaderAttributes; }
-
- gl::LinkedUniform *getUniformByLocation(GLint location) const;
- gl::LinkedUniform *getUniformByName(const std::string &name) const;
- gl::UniformBlock *getUniformBlockByIndex(GLuint blockIndex) const;
-
- GLint getUniformLocation(std::string name);
- GLuint getUniformIndex(std::string name);
- GLuint getUniformBlockIndex(std::string name) const;
-
virtual bool usesPointSize() const = 0;
virtual int getShaderVersion() const = 0;
virtual GLenum getTransformFeedbackBufferMode() const = 0;
virtual GLenum getBinaryFormat() = 0;
- virtual gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
+ virtual LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
virtual gl::Error save(gl::BinaryOutputStream *stream) = 0;
- virtual gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
- gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings,
- GLenum transformFeedbackBufferMode,
- int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
- std::map<int, gl::VariableLocation> *outputVariables) = 0;
+ virtual LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
+ gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables) = 0;
virtual void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) = 0;
virtual void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) = 0;
@@ -88,8 +77,6 @@ class ProgramImpl
virtual void getUniformiv(GLint location, GLint *params) = 0;
virtual void getUniformuiv(GLint location, GLuint *params) = 0;
- virtual void reset();
-
// TODO: The following functions are possibly only applicable to D3D backends. The should be carefully evaluated to
// determine if they can be removed from this interface.
virtual GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const = 0;
@@ -98,8 +85,8 @@ class ProgramImpl
virtual void updateSamplerMapping() = 0;
virtual bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) = 0;
- virtual gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- int registers) = 0;
+ virtual LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers) = 0;
virtual bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
const gl::Caps &caps) = 0;
@@ -107,21 +94,44 @@ class ProgramImpl
const gl::Caps &caps) = 0;
virtual gl::Error applyUniforms() = 0;
- virtual gl::Error applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps) = 0;
+ virtual gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) = 0;
virtual bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
unsigned int registerIndex, const gl::Caps &caps) = 0;
- protected:
- DISALLOW_COPY_AND_ASSIGN(ProgramImpl);
+ const std::vector<gl::LinkedUniform*> &getUniforms() const { return mUniforms; }
+ const std::vector<gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; }
+ const std::vector<gl::UniformBlock*> &getUniformBlocks() const { return mUniformBlocks; }
+ const std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() const { return mTransformFeedbackLinkedVaryings; }
+ const sh::Attribute *getShaderAttributes() const { return mShaderAttributes; }
+ const SemanticIndexArray &getSemanticIndexes() const { return mSemanticIndex; }
+
+ std::vector<gl::LinkedUniform*> &getUniforms() { return mUniforms; }
+ std::vector<gl::VariableLocation> &getUniformIndices() { return mUniformIndex; }
+ std::vector<gl::UniformBlock*> &getUniformBlocks() { return mUniformBlocks; }
+ std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() { return mTransformFeedbackLinkedVaryings; }
+ sh::Attribute *getShaderAttributes() { return mShaderAttributes; }
+ SemanticIndexArray &getSemanticIndexes() { return mSemanticIndex; }
+
+ gl::LinkedUniform *getUniformByLocation(GLint location) const;
+ gl::LinkedUniform *getUniformByName(const std::string &name) const;
+ gl::UniformBlock *getUniformBlockByIndex(GLuint blockIndex) const;
+
+ GLint getUniformLocation(std::string name);
+ GLuint getUniformIndex(std::string name);
+ GLuint getUniformBlockIndex(std::string name) const;
+ virtual void reset();
+
+ protected:
std::vector<gl::LinkedUniform*> mUniforms;
std::vector<gl::VariableLocation> mUniformIndex;
std::vector<gl::UniformBlock*> mUniformBlocks;
std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
+ SemanticIndexArray mSemanticIndex;
sh::Attribute mShaderAttributes[gl::MAX_VERTEX_ATTRIBS];
};
}
-#endif // LIBGLESV2_RENDERER_PROGRAMIMPL_H_
+#endif // LIBANGLE_RENDERER_PROGRAMIMPL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/QueryImpl.h
index 6b45810a3b..bed63ea1b0 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/QueryImpl.h
@@ -6,10 +6,10 @@
// QueryImpl.h: Defines the abstract rx::QueryImpl class.
-#ifndef LIBGLESV2_RENDERER_QUERYIMPL_H_
-#define LIBGLESV2_RENDERER_QUERYIMPL_H_
+#ifndef LIBANGLE_RENDERER_QUERYIMPL_H_
+#define LIBANGLE_RENDERER_QUERYIMPL_H_
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
#include "common/angleutils.h"
@@ -18,7 +18,7 @@
namespace rx
{
-class QueryImpl
+class QueryImpl : angle::NonCopyable
{
public:
explicit QueryImpl(GLenum type) { mType = type; }
@@ -32,11 +32,9 @@ class QueryImpl
GLenum getType() const { return mType; }
private:
- DISALLOW_COPY_AND_ASSIGN(QueryImpl);
-
GLenum mType;
};
}
-#endif // LIBGLESV2_RENDERER_QUERYIMPL_H_
+#endif // LIBANGLE_RENDERER_QUERYIMPL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp b/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.cpp
index 770ae8e9c6..ea5a40a21a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.cpp
@@ -6,7 +6,7 @@
// RenderbufferImpl.h: Implements the shared methods of the abstract class gl::RenderbufferImpl
-#include "libGLESv2/renderer/RenderbufferImpl.h"
+#include "libANGLE/renderer/RenderbufferImpl.h"
namespace rx
{
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.h
new file mode 100644
index 0000000000..8ce257c833
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.h
@@ -0,0 +1,33 @@
+//
+// Copyright (c) 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 "libANGLE/Error.h"
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+
+class RenderbufferImpl : angle::NonCopyable
+{
+ public:
+ RenderbufferImpl();
+ virtual ~RenderbufferImpl() = 0;
+
+ virtual gl::Error setStorage(GLenum internalformat, size_t width, size_t height) = 0;
+ virtual gl::Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) = 0;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_RENDERBUFFERIMPL_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/Renderer.cpp b/src/3rdparty/angle/src/libANGLE/renderer/Renderer.cpp
new file mode 100644
index 0000000000..fbc2ad5d1c
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/Renderer.cpp
@@ -0,0 +1,72 @@
+//
+// Copyright (c) 2012-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.
+//
+
+// Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances.
+
+#include "common/utilities.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/renderer/Renderer.h"
+
+#include <EGL/eglext.h>
+
+namespace rx
+{
+
+Renderer::Renderer()
+ : mCapsInitialized(false),
+ mWorkaroundsInitialized(false)
+{
+}
+
+Renderer::~Renderer()
+{
+}
+
+const gl::Caps &Renderer::getRendererCaps() const
+{
+ if (!mCapsInitialized)
+ {
+ generateCaps(&mCaps, &mTextureCaps, &mExtensions);
+ mCapsInitialized = true;
+ }
+
+ return mCaps;
+}
+
+const gl::TextureCapsMap &Renderer::getRendererTextureCaps() const
+{
+ if (!mCapsInitialized)
+ {
+ generateCaps(&mCaps, &mTextureCaps, &mExtensions);
+ mCapsInitialized = true;
+ }
+
+ return mTextureCaps;
+}
+
+const gl::Extensions &Renderer::getRendererExtensions() const
+{
+ if (!mCapsInitialized)
+ {
+ generateCaps(&mCaps, &mTextureCaps, &mExtensions);
+ mCapsInitialized = true;
+ }
+
+ return mExtensions;
+}
+
+const Workarounds &Renderer::getWorkarounds() const
+{
+ if (!mWorkaroundsInitialized)
+ {
+ mWorkarounds = generateWorkarounds();
+ mWorkaroundsInitialized = true;
+ }
+
+ return mWorkarounds;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/Renderer.h b/src/3rdparty/angle/src/libANGLE/renderer/Renderer.h
new file mode 100644
index 0000000000..b607fe5613
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/Renderer.h
@@ -0,0 +1,91 @@
+//
+// Copyright (c) 2012-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.
+//
+
+// Renderer.h: Defines a back-end specific class that hides the details of the
+// implementation-specific renderer.
+
+#ifndef LIBANGLE_RENDERER_RENDERER_H_
+#define LIBANGLE_RENDERER_RENDERER_H_
+
+#include "libANGLE/Caps.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Uniform.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/ImplFactory.h"
+#include "libANGLE/renderer/Workarounds.h"
+#include "common/mathutil.h"
+
+#include <stdint.h>
+
+#include <EGL/egl.h>
+
+namespace egl
+{
+class AttributeMap;
+class Display;
+class Surface;
+}
+
+namespace gl
+{
+class Buffer;
+struct Data;
+}
+
+namespace rx
+{
+struct TranslatedIndexData;
+struct Workarounds;
+class DisplayImpl;
+
+class Renderer : public ImplFactory
+{
+ public:
+ Renderer();
+ virtual ~Renderer();
+
+ virtual gl::Error flush() = 0;
+ virtual gl::Error finish() = 0;
+
+ virtual gl::Error drawArrays(const gl::Data &data, GLenum mode,
+ GLint first, GLsizei count, GLsizei instances) = 0;
+ virtual gl::Error drawElements(const gl::Data &data, GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const RangeUI &indexRange) = 0;
+
+ // lost device
+ //TODO(jmadill): investigate if this stuff is necessary in GL
+ virtual void notifyDeviceLost() = 0;
+ virtual bool isDeviceLost() const = 0;
+ virtual bool testDeviceLost() = 0;
+ virtual bool testDeviceResettable() = 0;
+
+ virtual VendorID getVendorId() const = 0;
+ virtual std::string getVendorString() const = 0;
+ virtual std::string getRendererDescription() const = 0;
+
+ // Renderer capabilities
+ const gl::Caps &getRendererCaps() const;
+ const gl::TextureCapsMap &getRendererTextureCaps() const;
+ const gl::Extensions &getRendererExtensions() const;
+ const Workarounds &getWorkarounds() const;
+
+ private:
+ virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const = 0;
+ virtual Workarounds generateWorkarounds() const = 0;
+
+ mutable bool mCapsInitialized;
+ mutable gl::Caps mCaps;
+ mutable gl::TextureCapsMap mTextureCaps;
+ mutable gl::Extensions mExtensions;
+
+ mutable bool mWorkaroundsInitialized;
+ mutable Workarounds mWorkarounds;
+};
+
+}
+#endif // LIBANGLE_RENDERER_RENDERER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/ShaderImpl.h
index cb0d360f0b..3011bc57f8 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/ShaderImpl.h
@@ -6,28 +6,29 @@
// ShaderImpl.h: Defines the abstract rx::ShaderImpl class.
-#ifndef LIBGLESV2_RENDERER_SHADERIMPL_H_
-#define LIBGLESV2_RENDERER_SHADERIMPL_H_
+#ifndef LIBANGLE_RENDERER_SHADERIMPL_H_
+#define LIBANGLE_RENDERER_SHADERIMPL_H_
#include <vector>
#include "common/angleutils.h"
-#include "libGLESv2/Shader.h"
+#include "libANGLE/Shader.h"
namespace rx
{
-class ShaderImpl
+class ShaderImpl : angle::NonCopyable
{
public:
ShaderImpl() { }
virtual ~ShaderImpl() { }
- virtual bool compile(const gl::Data &data, const std::string &source) = 0;
- virtual const std::string &getInfoLog() const = 0;
- virtual const std::string &getTranslatedSource() const = 0;
+ virtual bool compile(gl::Compiler *compiler, const std::string &source) = 0;
virtual std::string getDebugInfo() const = 0;
+ virtual const std::string &getInfoLog() const { return mInfoLog; }
+ virtual const std::string &getTranslatedSource() const { return mTranslatedSource; }
+
const std::vector<gl::PackedVarying> &getVaryings() const { return mVaryings; }
const std::vector<sh::Uniform> &getUniforms() const { return mUniforms; }
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return mInterfaceBlocks; }
@@ -41,7 +42,8 @@ class ShaderImpl
std::vector<sh::Attribute> &getActiveOutputVariables() { return mActiveOutputVariables; }
protected:
- DISALLOW_COPY_AND_ASSIGN(ShaderImpl);
+ std::string mInfoLog;
+ std::string mTranslatedSource;
std::vector<gl::PackedVarying> mVaryings;
std::vector<sh::Uniform> mUniforms;
@@ -52,4 +54,4 @@ class ShaderImpl
}
-#endif // LIBGLESV2_RENDERER_SHADERIMPL_H_
+#endif // LIBANGLE_RENDERER_SHADERIMPL_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.cpp b/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.cpp
new file mode 100644
index 0000000000..36f5fdca3f
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.cpp
@@ -0,0 +1,22 @@
+//
+// Copyright (c) 2002-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.cpp: Implementation of Surface stub method class
+
+#include "libANGLE/renderer/SurfaceImpl.h"
+
+namespace rx
+{
+
+SurfaceImpl::SurfaceImpl()
+{
+}
+
+SurfaceImpl::~SurfaceImpl()
+{
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.h
new file mode 100644
index 0000000000..ca04a42bd1
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.h
@@ -0,0 +1,48 @@
+//
+// Copyright (c) 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 "common/angleutils.h"
+#include "libANGLE/Error.h"
+
+namespace egl
+{
+class Display;
+struct Config;
+}
+
+namespace rx
+{
+
+class SurfaceImpl : angle::NonCopyable
+{
+ public:
+ SurfaceImpl();
+ virtual ~SurfaceImpl();
+
+ virtual egl::Error initialize() = 0;
+ virtual egl::Error swap() = 0;
+ virtual egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) = 0;
+ virtual egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) = 0;
+ virtual egl::Error bindTexImage(EGLint buffer) = 0;
+ virtual egl::Error releaseTexImage(EGLint buffer) = 0;
+ virtual void setSwapInterval(EGLint interval) = 0;
+
+ // width and height can change with client window resizing
+ virtual EGLint getWidth() const = 0;
+ virtual EGLint getHeight() const = 0;
+
+ virtual EGLint isPostSubBufferSupported() const = 0;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_SURFACEIMPL_H_
+
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.h
new file mode 100644
index 0000000000..d628906116
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.h
@@ -0,0 +1,72 @@
+//
+// 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 "libANGLE/Error.h"
+#include "libANGLE/ImageIndex.h"
+
+#include "common/angleutils.h"
+
+#include "angle_gl.h"
+
+#include <stdint.h>
+
+namespace egl
+{
+class Surface;
+}
+
+namespace gl
+{
+struct Box;
+struct Extents;
+struct Offset;
+struct Rectangle;
+class Framebuffer;
+struct PixelUnpackState;
+struct SamplerState;
+}
+
+namespace rx
+{
+
+class TextureImpl : angle::NonCopyable
+{
+ public:
+ virtual ~TextureImpl() {};
+
+ virtual void setUsage(GLenum usage) = 0;
+
+ virtual gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) = 0;
+ virtual gl::Error setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) = 0;
+
+ virtual gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) = 0;
+ virtual gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) = 0;
+
+ virtual gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
+ const gl::Framebuffer *source) = 0;
+ virtual gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source) = 0;
+
+ virtual gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) = 0;
+
+ virtual gl::Error generateMipmaps() = 0;
+
+ virtual void bindTexImage(egl::Surface *surface) = 0;
+ virtual void releaseTexImage() = 0;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_TEXTUREIMPL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TransformFeedbackImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl.h
index 8425604d87..8f9133cfe5 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/TransformFeedbackImpl.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl.h
@@ -6,16 +6,16 @@
// TransformFeedbackImpl.h: Defines the abstract rx::TransformFeedbackImpl class.
-#ifndef LIBGLESV2_RENDERER_TRANSFORMFEEDBACKIMPL_H_
-#define LIBGLESV2_RENDERER_TRANSFORMFEEDBACKIMPL_H_
+#ifndef LIBANGLE_RENDERER_TRANSFORMFEEDBACKIMPL_H_
+#define LIBANGLE_RENDERER_TRANSFORMFEEDBACKIMPL_H_
#include "common/angleutils.h"
-#include "libGLESv2/TransformFeedback.h"
+#include "libANGLE/TransformFeedback.h"
namespace rx
{
-class TransformFeedbackImpl
+class TransformFeedbackImpl : angle::NonCopyable
{
public:
virtual ~TransformFeedbackImpl() { }
@@ -28,4 +28,4 @@ class TransformFeedbackImpl
}
-#endif // LIBGLESV2_RENDERER_TRANSFORMFEEDBACKIMPL_H_
+#endif // LIBANGLE_RENDERER_TRANSFORMFEEDBACKIMPL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexArrayImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/VertexArrayImpl.h
index b013f9cdf4..0e25f952c2 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexArrayImpl.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/VertexArrayImpl.h
@@ -6,17 +6,17 @@
// VertexAttribImpl.h: Defines the abstract rx::VertexAttribImpl class.
-#ifndef LIBGLESV2_RENDERER_VERTEXARRAYIMPL_H_
-#define LIBGLESV2_RENDERER_VERTEXARRAYIMPL_H_
+#ifndef LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_
+#define LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_
#include "common/angleutils.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/VertexAttribute.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/VertexAttribute.h"
namespace rx
{
-class VertexArrayImpl
+class VertexArrayImpl : angle::NonCopyable
{
public:
virtual ~VertexArrayImpl() { }
@@ -29,4 +29,4 @@ class VertexArrayImpl
}
-#endif // LIBGLESV2_RENDERER_VERTEXARRAYIMPL_H_
+#endif // LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/Workarounds.h b/src/3rdparty/angle/src/libANGLE/renderer/Workarounds.h
new file mode 100644
index 0000000000..b73f4a5472
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/Workarounds.h
@@ -0,0 +1,74 @@
+//
+// Copyright (c) 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.
+//
+
+// angletypes.h: Workarounds for driver bugs and other issues.
+
+#ifndef LIBANGLE_RENDERER_WORKAROUNDS_H_
+#define LIBANGLE_RENDERER_WORKAROUNDS_H_
+
+// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate
+// independent of ANGLE's renderer. Workarounds should also be accessible
+// outside of the Renderer.
+
+namespace rx
+{
+
+struct D3DCompilerWorkarounds : angle::NonCopyable
+{
+ D3DCompilerWorkarounds()
+ : skipOptimization(false),
+ useMaxOptimization(false),
+ enableIEEEStrictness(false)
+ {}
+
+ void reset()
+ {
+ skipOptimization = false;
+ useMaxOptimization = false;
+ enableIEEEStrictness = false;
+ }
+
+ bool skipOptimization;
+ bool useMaxOptimization;
+
+ // IEEE strictness needs to be enabled for NANs to work.
+ bool enableIEEEStrictness;
+};
+
+struct Workarounds
+{
+ Workarounds()
+ : mrtPerfWorkaround(false),
+ setDataFasterThanImageUpload(false),
+ zeroMaxLodWorkaround(false),
+ useInstancedPointSpriteEmulation(false)
+ {}
+
+ // On some systems, having extra rendertargets than necessary slows down the shader.
+ // We can fix this by optimizing those out of the shader. At the same time, we can
+ // work around a bug on some nVidia drivers that they ignore "null" render targets
+ // in D3D11, by compacting the active color attachments list to omit null entries.
+ bool mrtPerfWorkaround;
+
+ bool setDataFasterThanImageUpload;
+
+ // Some renderers can't disable mipmaps on a mipmapped texture (i.e. solely sample from level zero, and ignore the other levels).
+ // D3D11 Feature Level 10+ does this by setting MaxLOD to 0.0f in the Sampler state. D3D9 sets D3DSAMP_MIPFILTER to D3DTEXF_NONE.
+ // There is no equivalent to this in D3D11 Feature Level 9_3.
+ // This causes problems when (for example) an application creates a mipmapped texture2D, but sets GL_TEXTURE_MIN_FILTER to GL_NEAREST (i.e disables mipmaps).
+ // To work around this, D3D11 FL9_3 has to create two copies of the texture. The textures' level zeros are identical, but only one texture has mips.
+ bool zeroMaxLodWorkaround;
+
+ // Some renderers do not support Geometry Shaders so the Geometry Shader-based
+ // PointSprite emulation will not work.
+ // To work around this, D3D11 FL9_3 has to use a different pointsprite
+ // emulation that is implemented using instanced quads.
+ bool useInstancedPointSpriteEmulation;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_WORKAROUNDS_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp
index dd0d3f52ad..1af8794356 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp
@@ -6,20 +6,22 @@
// BufferD3D.cpp Defines common functionality between the Buffer9 and Buffer11 classes.
-#include "libGLESv2/renderer/d3d/BufferD3D.h"
-#include "libGLESv2/renderer/d3d/VertexBuffer.h"
-#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
+#include "libANGLE/renderer/d3d/VertexBuffer.h"
namespace rx
{
unsigned int BufferD3D::mNextSerial = 1;
-BufferD3D::BufferD3D()
+BufferD3D::BufferD3D(BufferFactoryD3D *factory)
: BufferImpl(),
- mStaticVertexBuffer(NULL),
- mStaticIndexBuffer(NULL)
+ mFactory(factory),
+ mStaticVertexBuffer(nullptr),
+ mStaticIndexBuffer(nullptr),
+ mUnmodifiedDataUse(0)
{
updateSerial();
}
@@ -30,19 +32,6 @@ BufferD3D::~BufferD3D()
SafeDelete(mStaticIndexBuffer);
}
-BufferD3D *BufferD3D::makeBufferD3D(BufferImpl *buffer)
-{
- ASSERT(HAS_DYNAMIC_TYPE(BufferD3D*, buffer));
- return static_cast<BufferD3D*>(buffer);
-}
-
-BufferD3D *BufferD3D::makeFromBuffer(gl::Buffer *buffer)
-{
- BufferImpl *impl = buffer->getImplementation();
- ASSERT(impl);
- return makeBufferD3D(impl);
-}
-
void BufferD3D::updateSerial()
{
mSerial = mNextSerial++;
@@ -52,11 +41,11 @@ void BufferD3D::initializeStaticData()
{
if (!mStaticVertexBuffer)
{
- mStaticVertexBuffer = new StaticVertexBufferInterface(getRenderer());
+ mStaticVertexBuffer = new StaticVertexBufferInterface(mFactory);
}
if (!mStaticIndexBuffer)
{
- mStaticIndexBuffer = new StaticIndexBufferInterface(getRenderer());
+ mStaticIndexBuffer = new StaticIndexBufferInterface(mFactory);
}
}
@@ -66,6 +55,9 @@ void BufferD3D::invalidateStaticData()
{
SafeDelete(mStaticVertexBuffer);
SafeDelete(mStaticIndexBuffer);
+
+ // Re-init static data to track that we're in a static buffer
+ initializeStaticData();
}
mUnmodifiedDataUse = 0;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.h
index 1a1308c545..a46398f911 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.h
@@ -4,37 +4,33 @@
// found in the LICENSE file.
//
-// BufferImpl.h: Defines the abstract rx::BufferImpl class.
+// BufferD3D.h: Defines the rx::BufferD3D class, an implementation of BufferImpl.
-#ifndef LIBGLESV2_RENDERER_BUFFERD3D_H_
-#define LIBGLESV2_RENDERER_BUFFERD3D_H_
+#ifndef LIBANGLE_RENDERER_D3D_BUFFERD3D_H_
+#define LIBANGLE_RENDERER_D3D_BUFFERD3D_H_
-#include "libGLESv2/renderer/BufferImpl.h"
-#include "libGLESv2/angletypes.h"
+#include "libANGLE/renderer/BufferImpl.h"
+#include "libANGLE/angletypes.h"
-#include <cstdint>
+#include <stdint.h>
namespace rx
{
-class RendererD3D;
+class BufferFactoryD3D;
class StaticIndexBufferInterface;
class StaticVertexBufferInterface;
class BufferD3D : public BufferImpl
{
public:
- BufferD3D();
+ BufferD3D(BufferFactoryD3D *factory);
virtual ~BufferD3D();
- static BufferD3D *makeBufferD3D(BufferImpl *buffer);
- static BufferD3D *makeFromBuffer(gl::Buffer *buffer);
-
unsigned int getSerial() const { return mSerial; }
- virtual gl::Error getData(const uint8_t **outData) = 0;
virtual size_t getSize() const = 0;
virtual bool supportsDirectBinding() const = 0;
- virtual RendererD3D *getRenderer() = 0;
+ virtual void markTransformFeedbackUsage() = 0;
StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; }
StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; }
@@ -44,11 +40,12 @@ class BufferD3D : public BufferImpl
void promoteStaticUsage(int dataSize);
protected:
+ void updateSerial();
+
+ BufferFactoryD3D *mFactory;
unsigned int mSerial;
static unsigned int mNextSerial;
- void updateSerial();
-
StaticVertexBufferInterface *mStaticVertexBuffer;
StaticIndexBufferInterface *mStaticIndexBuffer;
unsigned int mUnmodifiedDataUse;
@@ -56,4 +53,4 @@ class BufferD3D : public BufferImpl
}
-#endif // LIBGLESV2_RENDERER_BUFFERIMPLD3D_H_
+#endif // LIBANGLE_RENDERER_D3D_BUFFERD3D_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp
new file mode 100644
index 0000000000..a22757cf9f
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp
@@ -0,0 +1,128 @@
+//
+// Copyright (c) 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.cpp: Implementation of the rx::CompilerD3D class.
+
+#include "libANGLE/renderer/d3d/CompilerD3D.h"
+
+#include "libANGLE/Caps.h"
+#include "libANGLE/Data.h"
+
+#include "common/debug.h"
+
+namespace rx
+{
+
+// Global count of active shader compiler handles. Needed to know when to call ShInitialize and ShFinalize.
+static size_t activeCompilerHandles = 0;
+
+CompilerD3D::CompilerD3D(const gl::Data &data, ShShaderOutput outputType)
+ : mSpec(data.clientVersion > 2 ? SH_GLES3_SPEC : SH_GLES2_SPEC),
+ mOutputType(outputType),
+ mResources(),
+ mFragmentCompiler(NULL),
+ mVertexCompiler(NULL)
+{
+ ASSERT(data.clientVersion == 2 || data.clientVersion == 3);
+
+ const gl::Caps &caps = *data.caps;
+ const gl::Extensions &extensions = *data.extensions;
+
+ ShInitBuiltInResources(&mResources);
+ mResources.MaxVertexAttribs = caps.maxVertexAttributes;
+ mResources.MaxVertexUniformVectors = caps.maxVertexUniformVectors;
+ mResources.MaxVaryingVectors = caps.maxVaryingVectors;
+ mResources.MaxVertexTextureImageUnits = caps.maxVertexTextureImageUnits;
+ mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
+ mResources.MaxTextureImageUnits = caps.maxTextureImageUnits;
+ mResources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors;
+ mResources.MaxDrawBuffers = caps.maxDrawBuffers;
+ mResources.OES_standard_derivatives = extensions.standardDerivatives;
+ mResources.EXT_draw_buffers = extensions.drawBuffers;
+ mResources.EXT_shader_texture_lod = 1;
+ // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
+ mResources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
+ mResources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
+
+ // GLSL ES 3.0 constants
+ mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4;
+ mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
+ mResources.MinProgramTexelOffset = caps.minProgramTexelOffset;
+ mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset;
+}
+
+CompilerD3D::~CompilerD3D()
+{
+ release();
+}
+
+CompilerD3D *CompilerD3D::makeCompilerD3D(CompilerImpl *compiler)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(CompilerD3D*, compiler));
+ return static_cast<CompilerD3D*>(compiler);
+}
+
+gl::Error CompilerD3D::release()
+{
+ if (mFragmentCompiler)
+ {
+ ShDestruct(mFragmentCompiler);
+ mFragmentCompiler = NULL;
+
+ ASSERT(activeCompilerHandles > 0);
+ activeCompilerHandles--;
+ }
+
+ if (mVertexCompiler)
+ {
+ ShDestruct(mVertexCompiler);
+ mVertexCompiler = NULL;
+
+ ASSERT(activeCompilerHandles > 0);
+ activeCompilerHandles--;
+ }
+
+ if (activeCompilerHandles == 0)
+ {
+ ShFinalize();
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+ShHandle CompilerD3D::getCompilerHandle(GLenum type)
+{
+ ShHandle *compiler = NULL;
+ switch (type)
+ {
+ case GL_VERTEX_SHADER:
+ compiler = &mVertexCompiler;
+ break;
+
+ case GL_FRAGMENT_SHADER:
+ compiler = &mFragmentCompiler;
+ break;
+
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+
+ if (!(*compiler))
+ {
+ if (activeCompilerHandles == 0)
+ {
+ ShInitialize();
+ }
+
+ *compiler = ShConstructCompiler(type, mSpec, mOutputType, &mResources);
+ activeCompilerHandles++;
+ }
+
+ return *compiler;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.h
new file mode 100644
index 0000000000..0f83e4f8c8
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.h
@@ -0,0 +1,48 @@
+//
+// Copyright (c) 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/Caps.h"
+
+#include "GLSLANG/ShaderLang.h"
+
+namespace gl
+{
+struct Data;
+}
+
+namespace rx
+{
+
+class CompilerD3D : public CompilerImpl
+{
+ public:
+ CompilerD3D(const gl::Data &data, ShShaderOutput outputType);
+ virtual ~CompilerD3D();
+
+ static CompilerD3D *makeCompilerD3D(CompilerImpl *compiler);
+
+ gl::Error release() override;
+
+ ShHandle getCompilerHandle(GLenum type);
+
+ private:
+ ShShaderSpec mSpec;
+ ShShaderOutput mOutputType;
+ ShBuiltInResources mResources;
+
+ ShHandle mFragmentCompiler;
+ ShHandle mVertexCompiler;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_COMPILERD3D_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp
new file mode 100644
index 0000000000..add5d62fae
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp
@@ -0,0 +1,357 @@
+//
+// Copyright (c) 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 "libANGLE/Context.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+#include "platform/Platform.h"
+
+#include <EGL/eglext.h>
+
+#if defined (ANGLE_ENABLE_D3D9)
+# include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#endif // ANGLE_ENABLE_D3D9
+
+#if defined (ANGLE_ENABLE_D3D11)
+# include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#endif // ANGLE_ENABLE_D3D11
+
+#if defined (ANGLE_TEST_CONFIG)
+# define ANGLE_DEFAULT_D3D11 1
+#endif
+
+#if !defined(ANGLE_DEFAULT_D3D11)
+// Enables use of the Direct3D 11 API for a default display, when available
+# define ANGLE_DEFAULT_D3D11 0
+#endif
+
+namespace rx
+{
+
+typedef RendererD3D *(*CreateRendererD3DFunction)(egl::Display*);
+
+template <typename RendererType>
+static RendererD3D *CreateTypedRendererD3D(egl::Display *display)
+{
+ return new RendererType(display);
+}
+
+egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer)
+{
+ ASSERT(outRenderer != nullptr);
+
+ std::vector<CreateRendererD3DFunction> rendererCreationFunctions;
+
+ const auto &attribMap = display->getAttributeMap();
+ EGLNativeDisplayType nativeDisplay = display->getNativeDisplayId();
+
+ EGLint requestedDisplayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
+
+# if defined(ANGLE_ENABLE_D3D11)
+ if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
+ nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE ||
+ requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer11>);
+ }
+# endif
+
+# if defined(ANGLE_ENABLE_D3D9)
+ if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
+ requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
+ {
+ rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer9>);
+ }
+# 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(CreateTypedRendererD3D<Renderer11>);
+# endif
+# if defined(ANGLE_ENABLE_D3D9)
+ rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer9>);
+# endif
+# else
+# if defined(ANGLE_ENABLE_D3D9)
+ rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer9>);
+# endif
+# if defined(ANGLE_ENABLE_D3D11)
+ rendererCreationFunctions.push_back(CreateTypedRendererD3D<Renderer11>);
+# endif
+# endif
+ }
+
+ egl::Error result(EGL_NOT_INITIALIZED, "No available renderers.");
+ for (size_t i = 0; i < rendererCreationFunctions.size(); i++)
+ {
+ RendererD3D *renderer = rendererCreationFunctions[i](display);
+ result = renderer->initialize();
+
+# if defined(ANGLE_ENABLE_D3D11)
+ if (renderer->getRendererClass() == RENDERER_D3D11)
+ {
+ ASSERT(result.getID() >= 0 && result.getID() < NUM_D3D11_INIT_ERRORS);
+
+ angle::Platform *platform = ANGLEPlatformCurrent();
+ platform->histogramEnumeration("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::Platform *platform = ANGLEPlatformCurrent();
+ platform->histogramEnumeration("GPU.ANGLE.D3D9InitializeResult",
+ result.getID(), NUM_D3D9_INIT_ERRORS);
+ }
+# endif
+
+ if (!result.isError())
+ {
+ *outRenderer = renderer;
+ break;
+ }
+ else
+ {
+ // Failed to create the renderer, try the next
+ SafeDelete(renderer);
+ }
+ }
+
+ return result;
+}
+
+DisplayD3D::DisplayD3D()
+ : mRenderer(nullptr)
+{
+}
+
+egl::Error DisplayD3D::createWindowSurface(const egl::Config *configuration, EGLNativeWindowType window,
+ const egl::AttributeMap &attribs, SurfaceImpl **outSurface)
+{
+ ASSERT(mRenderer != nullptr);
+
+ EGLint width = attribs.get(EGL_WIDTH, 0);
+ EGLint height = attribs.get(EGL_HEIGHT, 0);
+ EGLint fixedSize = attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE);
+
+ if (!fixedSize)
+ {
+ width = -1;
+ height = -1;
+ }
+
+ SurfaceD3D *surface = SurfaceD3D::createFromWindow(mRenderer, mDisplay, configuration, window, fixedSize,
+ width, height);
+ egl::Error error = surface->initialize();
+ if (error.isError())
+ {
+ SafeDelete(surface);
+ return error;
+ }
+
+ *outSurface = surface;
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayD3D::createPbufferSurface(const egl::Config *configuration, const egl::AttributeMap &attribs,
+ SurfaceImpl **outSurface)
+{
+ ASSERT(mRenderer != nullptr);
+
+ EGLint width = attribs.get(EGL_WIDTH, 0);
+ EGLint height = attribs.get(EGL_HEIGHT, 0);
+
+ SurfaceD3D *surface = SurfaceD3D::createOffscreen(mRenderer, mDisplay, configuration, NULL, width, height);
+ egl::Error error = surface->initialize();
+ if (error.isError())
+ {
+ SafeDelete(surface);
+ return error;
+ }
+
+ *outSurface = surface;
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayD3D::createPbufferFromClientBuffer(const egl::Config *configuration, EGLClientBuffer shareHandle,
+ const egl::AttributeMap &attribs, SurfaceImpl **outSurface)
+{
+ ASSERT(mRenderer != nullptr);
+
+ EGLint width = attribs.get(EGL_WIDTH, 0);
+ EGLint height = attribs.get(EGL_HEIGHT, 0);
+
+ SurfaceD3D *surface = SurfaceD3D::createOffscreen(mRenderer, mDisplay, configuration, shareHandle,
+ width, height);
+ egl::Error error = surface->initialize();
+ if (error.isError())
+ {
+ SafeDelete(surface);
+ return error;
+ }
+
+ *outSurface = surface;
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayD3D::createPixmapSurface(const egl::Config *configuration, NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs, SurfaceImpl **outSurface)
+{
+ ASSERT(mRenderer != nullptr);
+
+ UNIMPLEMENTED();
+ *outSurface = nullptr;
+ return egl::Error(EGL_BAD_DISPLAY);
+}
+
+egl::Error DisplayD3D::createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs,
+ gl::Context **outContext)
+{
+ ASSERT(mRenderer != nullptr);
+
+ EGLint clientVersion = attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1);
+ bool notifyResets = (attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION_EXT) == EGL_LOSE_CONTEXT_ON_RESET_EXT);
+ bool robustAccess = (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE);
+
+ *outContext = new gl::Context(config, clientVersion, shareContext, mRenderer, notifyResets, robustAccess);
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayD3D::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context)
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayD3D::initialize(egl::Display *display)
+{
+ ASSERT(mRenderer == nullptr && display != nullptr);
+ mDisplay = display;
+ return CreateRendererD3D(display, &mRenderer);
+}
+
+void DisplayD3D::terminate()
+{
+ SafeDelete(mRenderer);
+}
+
+egl::ConfigSet DisplayD3D::generateConfigs() const
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->generateConfigs();
+}
+
+bool DisplayD3D::isDeviceLost() const
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->isDeviceLost();
+}
+
+bool DisplayD3D::testDeviceLost()
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->testDeviceLost();
+}
+
+egl::Error DisplayD3D::restoreLostDevice()
+{
+ // Release surface resources to make the Reset() succeed
+ for (auto it = mSurfaceSet.cbegin(); it != mSurfaceSet.cend(); ++it)
+ {
+ const auto &surface = *it;
+ if (surface->getBoundTexture())
+ {
+ surface->releaseTexImage(EGL_BACK_BUFFER);
+ }
+ SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+ surfaceD3D->releaseSwapChain();
+ }
+
+ if (!mRenderer->resetDevice())
+ {
+ return egl::Error(EGL_BAD_ALLOC);
+ }
+
+ // Restore any surfaces that may have been lost
+ for (auto it = mSurfaceSet.cbegin(); it != mSurfaceSet.cend(); ++it)
+ {
+ const auto &surface = *it;
+ SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+
+ egl::Error error = surfaceD3D->resetSwapChain();
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+bool DisplayD3D::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ return NativeWindow::isValidNativeWindow(window);
+}
+
+void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const
+{
+ outExtensions->createContextRobustness = true;
+
+ // ANGLE-specific extensions
+ if (mRenderer->getShareHandleSupport())
+ {
+ outExtensions->d3dShareHandleClientBuffer = true;
+ outExtensions->surfaceD3DTexture2DShareHandle = true;
+ }
+
+ outExtensions->querySurfacePointer = true;
+ outExtensions->windowFixedSize = true;
+
+ if (mRenderer->getPostSubBufferSupport())
+ {
+ outExtensions->postSubBuffer = true;
+ }
+
+ outExtensions->createContext = true;
+}
+
+std::string DisplayD3D::getVendorString() const
+{
+ std::string vendorString = "Google Inc.";
+ if (mRenderer)
+ {
+ vendorString += " " + mRenderer->getVendorString();
+ }
+
+ return vendorString;
+}
+
+void DisplayD3D::generateCaps(egl::Caps *outCaps) const
+{
+ // Display must be initialized to generate caps
+ ASSERT(mRenderer != nullptr);
+
+ outCaps->textureNPOT = mRenderer->getRendererExtensions().textureNPOT;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.h
new file mode 100644
index 0000000000..f007ba9a19
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.h
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 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/renderer/DisplayImpl.h"
+
+namespace rx
+{
+class RendererD3D;
+
+class DisplayD3D : public DisplayImpl
+{
+ public:
+ DisplayD3D();
+
+ egl::Error initialize(egl::Display *display) override;
+ virtual void terminate() override;
+
+ egl::Error createWindowSurface(const egl::Config *configuration, EGLNativeWindowType window, const egl::AttributeMap &attribs,
+ SurfaceImpl **outSurface) override;
+ egl::Error createPbufferSurface(const egl::Config *configuration, const egl::AttributeMap &attribs,
+ SurfaceImpl **outSurface) override;
+ egl::Error createPbufferFromClientBuffer(const egl::Config *configuration, EGLClientBuffer shareHandle,
+ const egl::AttributeMap &attribs, SurfaceImpl **outSurface) override;
+ egl::Error createPixmapSurface(const egl::Config *configuration, NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs, SurfaceImpl **outSurface) override;
+
+ egl::Error createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs,
+ gl::Context **outContext) override;
+
+ egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) override;
+
+ egl::ConfigSet generateConfigs() const override;
+
+ bool isDeviceLost() const override;
+ bool testDeviceLost() override;
+ egl::Error restoreLostDevice() override;
+
+ bool isValidNativeWindow(EGLNativeWindowType window) const override;
+
+ std::string getVendorString() const override;
+
+ private:
+ void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
+ void generateCaps(egl::Caps *outCaps) const override;
+
+ egl::Display *mDisplay;
+
+ rx::RendererD3D *mRenderer;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
index 3d5bfe0cbe..0dbc30ae36 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
@@ -6,19 +6,18 @@
// DynamicHLSL.cpp: Implementation for link and run-time HLSL generation
//
-#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
-#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
-#include "libGLESv2/Program.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/Shader.h"
-#include "libGLESv2/formatutils.h"
+#include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include "common/utilities.h"
-#include "common/blocklayout.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/formatutils.h"
// For use with ArrayString, see angleutils.h
-META_ASSERT(GL_INVALID_INDEX == UINT_MAX);
+static_assert(GL_INVALID_INDEX == UINT_MAX, "GL_INVALID_INDEX must be equal to the max unsigned int.");
using namespace gl;
@@ -73,19 +72,18 @@ std::string HLSLTypeString(GLenum type)
return HLSLComponentTypeString(gl::VariableComponentType(type), gl::VariableComponentCount(type));
}
-const PixelShaderOutputVariable &GetOutputAtLocation(const std::vector<PixelShaderOutputVariable> &outputVariables,
+const PixelShaderOutputVariable *FindOutputAtLocation(const std::vector<PixelShaderOutputVariable> &outputVariables,
unsigned int location)
{
for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex)
{
if (outputVariables[variableIndex].outputIndex == location)
{
- return outputVariables[variableIndex];
+ return &outputVariables[variableIndex];
}
}
- UNREACHABLE();
- return outputVariables[0];
+ return NULL;
}
const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
@@ -100,11 +98,21 @@ DynamicHLSL::DynamicHLSL(RendererD3D *const renderer)
static bool packVarying(PackedVarying *varying, const int maxVaryingVectors, VaryingPacking packing)
{
- GLenum transposedType = TransposeMatrixType(varying->type);
+ // Make sure we use transposed matrix types to count registers correctly.
+ int registers = 0;
+ int elements = 0;
- // matrices within varying structs are not transposed
- int registers = (varying->isStruct() ? HLSLVariableRegisterCount(*varying) : VariableRowCount(transposedType)) * varying->elementCount();
- int elements = (varying->isStruct() ? 4 : VariableColumnCount(transposedType));
+ if (varying->isStruct())
+ {
+ registers = HLSLVariableRegisterCount(*varying, true) * varying->elementCount();
+ elements = 4;
+ }
+ else
+ {
+ GLenum transposedType = TransposeMatrixType(varying->type);
+ registers = VariableRowCount(transposedType) * varying->elementCount();
+ elements = VariableColumnCount(transposedType);
+ }
if (elements >= 2 && elements <= 4)
{
@@ -342,15 +350,16 @@ std::string DynamicHLSL::generateVaryingHLSL(const ShaderD3D *shader) const
default: UNREACHABLE();
}
- unsigned int semanticIndex = elementIndex * variableRows + varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + varying.registerIndex + row;
+ unsigned int semanticIndex = elementIndex * variableRows +
+ varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors +
+ varying.registerIndex + row;
std::string n = Str(semanticIndex);
std::string typeString;
if (varying.isStruct())
{
- // matrices within structs are not transposed, so
- // do not use the special struct prefix "rm"
+ // TODO(jmadill): pass back translated name from the shader translator
typeString = decorateVariable(varying.structName);
}
else
@@ -377,6 +386,26 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &s
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->getWorkarounds().useInstancedPointSpriteEmulation;
+
+ // 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)
+ {
+ structHLSL += " float3 spriteVertexPos : SPRITEPOSITION0;\n";
+ structHLSL += " float2 spriteTexCoord : SPRITETEXCOORD0;\n";
+ }
+
for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
const sh::Attribute &shaderAttribute = shaderAttributes[attributeIndex];
@@ -394,11 +423,31 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &s
else
{
GLenum componentType = mRenderer->getVertexComponentType(vertexFormat);
- structHLSL += " " + HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type));
+
+ if (shaderAttribute.name == "gl_InstanceID")
+ {
+ // The input type of the instance ID in HLSL (uint) differs from the one in ESSL (int).
+ structHLSL += " uint";
+ }
+ else
+ {
+ structHLSL += " " + HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type));
+ }
+ }
+
+ structHLSL += " " + decorateVariable(shaderAttribute.name) + " : ";
+
+ if (shaderAttribute.name == "gl_InstanceID")
+ {
+ structHLSL += "SV_InstanceID";
+ }
+ else
+ {
+ structHLSL += "TEXCOORD" + Str(semanticIndex);
+ semanticIndex += VariableRegisterCount(shaderAttribute.type);
}
- structHLSL += " " + decorateVariable(shaderAttribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n";
- semanticIndex += VariableRegisterCount(shaderAttribute.type);
+ structHLSL += ";\n";
// HLSL code for initialization
initHLSL += " " + decorateVariable(shaderAttribute.name) + " = ";
@@ -458,12 +507,18 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature(const std::string
{
unsigned int location = (binding - GL_COLOR_ATTACHMENT0);
- const PixelShaderOutputVariable &outputVariable = GetOutputAtLocation(outputVariables, location);
+ const PixelShaderOutputVariable *outputVariable = FindOutputAtLocation(outputVariables, location);
- declarationHLSL += " " + HLSLTypeString(outputVariable.type) + " " + outputVariable.name +
- " : " + targetSemantic + Str(layoutIndex) + ";\n";
+ // 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)
+ {
+ declarationHLSL += " " + HLSLTypeString(outputVariable->type) + " " + outputVariable->name +
+ " : " + targetSemantic + Str(layoutIndex) + ";\n";
- copyHLSL += " output." + outputVariable.name + " = " + outputVariable.source + ";\n";
+ copyHLSL += " output." + outputVariable->name + " = " + outputVariable->source + ";\n";
+ }
}
}
@@ -543,8 +598,8 @@ struct DynamicHLSL::SemanticInfo
BuiltinInfo glPointSize;
};
-DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord,
- bool pointSize, bool pixelShader) const
+DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool position, bool fragCoord,
+ bool pointCoord, bool pointSize, bool pixelShader) const
{
SemanticInfo info;
bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4);
@@ -565,7 +620,10 @@ DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool
info.dxPosition.enableSystem("POSITION");
}
- info.glPosition.enable(varyingSemantic, reservedRegisterIndex++);
+ if (position)
+ {
+ info.glPosition.enable(varyingSemantic, reservedRegisterIndex++);
+ }
if (fragCoord)
{
@@ -599,10 +657,13 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const
{
std::string linkHLSL = "{\n";
- ASSERT(info.dxPosition.enabled && info.glPosition.enabled);
-
+ ASSERT(info.dxPosition.enabled);
linkHLSL += " float4 dx_Position : " + info.dxPosition.str() + ";\n";
- linkHLSL += " float4 gl_Position : " + info.glPosition.str() + ";\n";
+
+ if (info.glPosition.enabled)
+ {
+ linkHLSL += " float4 gl_Position : " + info.glPosition.str() + ";\n";
+ }
if (info.glFragCoord.enabled)
{
@@ -614,13 +675,14 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const
linkHLSL += " float2 gl_PointCoord : " + info.glPointCoord.str() + ";\n";
}
- linkHLSL += varyingHLSL;
-
if (info.glPointSize.enabled)
{
linkHLSL += " float gl_PointSize : " + info.glPointSize.str() + ";\n";
}
+ // Do this after glPointSize, to potentially combine gl_PointCoord and gl_PointSize into the same register.
+ linkHLSL += varyingHLSL;
+
linkHLSL += "};\n";
return linkHLSL;
@@ -629,10 +691,11 @@ std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const
void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info,
std::vector<LinkedVarying> *linkedVaryings) const
{
- ASSERT(info.glPosition.enabled);
-
- linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, info.glPosition.semantic,
- info.glPosition.index, 1));
+ if (info.glPosition.enabled)
+ {
+ linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, info.glPosition.semantic,
+ info.glPosition.index, 1));
+ }
if (info.glFragCoord.enabled)
{
@@ -690,6 +753,7 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
bool usesFragCoord = fragmentShader->mUsesFragCoord;
bool usesPointCoord = fragmentShader->mUsesPointCoord;
bool usesPointSize = vertexShader->mUsesPointSize;
+ bool useInstancedPointSpriteEmulation = usesPointSize && mRenderer->getWorkarounds().useInstancedPointSpriteEmulation;
if (usesFragColor && usesFragData)
{
@@ -707,6 +771,11 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
const bool broadcast = (fragmentShader->mUsesFragColor && data.clientVersion < 3);
const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1);
+ // 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.
+ bool outputPositionFromVS = !(shaderModel >= 4 && mRenderer->getShaderModelSuffix() != "");
+
int shaderVersion = vertexShader->getShaderVersion();
if (static_cast<GLuint>(registersNeeded) > data.caps->maxVaryingVectors)
@@ -716,12 +785,29 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
}
const std::string &varyingHLSL = generateVaryingHLSL(vertexShader);
- const SemanticInfo &vertexSemantics = getSemanticInfo(registers, usesFragCoord,
- false, usesPointSize, false);
+
+ // Instanced PointSprite emulation requires that gl_PointCoord is present in the vertex shader VS_OUTPUT
+ // structure to ensure compatibility with the generated PS_INPUT of the pixel shader.
+ // GeometryShader PointSprite emulation does not require this additional entry because the
+ // GS_OUTPUT of the Geometry shader contains the pointCoord value and already matches the PS_INPUT of the
+ // generated pixel shader.
+ // The Geometry Shader point sprite implementation needs gl_PointSize to be in VS_OUTPUT and GS_INPUT.
+ // Instanced point sprites doesn't need gl_PointSize in VS_OUTPUT.
+ const SemanticInfo &vertexSemantics = getSemanticInfo(registers, outputPositionFromVS,
+ usesFragCoord, (useInstancedPointSpriteEmulation && usesPointCoord),
+ (!useInstancedPointSpriteEmulation && usesPointSize), false);
storeUserLinkedVaryings(vertexShader, linkedVaryings);
storeBuiltinLinkedVaryings(vertexSemantics, linkedVaryings);
+ // Instanced PointSprite emulation requires additional entries originally generated in the
+ // GeometryShader HLSL. These include pointsize clamp values.
+ if (useInstancedPointSpriteEmulation)
+ {
+ vertexHLSL += "static float minPointSize = " + Str((int)mRenderer->getRendererCaps().minAliasedPointSize) + ".0f;\n"
+ "static float maxPointSize = " + Str((int)mRenderer->getRendererCaps().maxAliasedPointSize) + ".0f;\n";
+ }
+
// Add stub string to be replaced when shader is dynamically defined by its layout
vertexHLSL += "\n" + VERTEX_ATTRIBUTE_STUB_STRING + "\n"
"struct VS_OUTPUT\n" + generateVaryingLinkHLSL(vertexSemantics, varyingHLSL) + "\n"
@@ -729,32 +815,40 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
"{\n"
" initAttributes(input);\n";
- if (shaderModel >= 4)
+ if (vertexShader->usesDeferredInit())
{
vertexHLSL += "\n"
- " gl_main();\n"
- "\n"
- " VS_OUTPUT output;\n"
- " output.gl_Position = gl_Position;\n"
- " output.dx_Position.x = gl_Position.x;\n"
+ " initializeDeferredGlobals();\n";
+ }
+
+ vertexHLSL += "\n"
+ " gl_main();\n"
+ "\n"
+ " VS_OUTPUT output;\n";
+
+ if (outputPositionFromVS)
+ {
+ vertexHLSL += " output.gl_Position = gl_Position;\n";
+ }
+
+ // On D3D9 or D3D11 Feature Level 9, we need to emulate large viewports using dx_ViewAdjust.
+ if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "")
+ {
+ vertexHLSL += " output.dx_Position.x = gl_Position.x;\n"
" output.dx_Position.y = -gl_Position.y;\n"
" output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
" output.dx_Position.w = gl_Position.w;\n";
}
else
{
- vertexHLSL += "\n"
- " gl_main();\n"
- "\n"
- " VS_OUTPUT output;\n"
- " output.gl_Position = gl_Position;\n"
- " output.dx_Position.x = gl_Position.x * dx_ViewAdjust.z + dx_ViewAdjust.x * gl_Position.w;\n"
+ vertexHLSL += " output.dx_Position.x = gl_Position.x * dx_ViewAdjust.z + dx_ViewAdjust.x * gl_Position.w;\n"
" output.dx_Position.y = -(gl_Position.y * dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n"
" output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
" output.dx_Position.w = gl_Position.w;\n";
}
- if (usesPointSize && shaderModel >= 3)
+ // We don't need to output gl_PointSize if we use are emulating point sprites via instancing.
+ if (usesPointSize && shaderModel >= 3 && !useInstancedPointSpriteEmulation)
{
vertexHLSL += " output.gl_PointSize = gl_PointSize;\n";
}
@@ -797,12 +891,27 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
}
}
+ // Instanced PointSprite emulation requires additional entries to calculate
+ // the final output vertex positions of the quad that represents each sprite.
+ if (useInstancedPointSpriteEmulation)
+ {
+ vertexHLSL += "\n"
+ " gl_PointSize = clamp(gl_PointSize, minPointSize, maxPointSize);\n"
+ " output.dx_Position.xyz += float3(input.spriteVertexPos.x * gl_PointSize / (dx_ViewCoords.x*2), input.spriteVertexPos.y * gl_PointSize / (dx_ViewCoords.y*2), input.spriteVertexPos.z) * output.dx_Position.w;\n";
+
+ if (usesPointCoord)
+ {
+ vertexHLSL += "\n"
+ " output.gl_PointCoord = input.spriteTexCoord;\n";
+ }
+ }
+
vertexHLSL += "\n"
" return output;\n"
"}\n";
- const SemanticInfo &pixelSemantics = getSemanticInfo(registers, usesFragCoord, usesPointCoord,
- usesPointSize, true);
+ const SemanticInfo &pixelSemantics = getSemanticInfo(registers, outputPositionFromVS, usesFragCoord, usesPointCoord,
+ (!useInstancedPointSpriteEmulation && usesPointSize), true);
pixelHLSL += "struct PS_INPUT\n" + generateVaryingLinkHLSL(pixelSemantics, varyingHLSL) + "\n";
@@ -872,12 +981,14 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
{
pixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n";
- if (shaderModel >= 4)
+ // 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.
+ if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "")
{
pixelHLSL += " gl_FragCoord.x = input.dx_Position.x;\n"
" gl_FragCoord.y = input.dx_Position.y;\n";
}
- else if (shaderModel >= 3)
+ else if (shaderModel == 3)
{
pixelHLSL += " gl_FragCoord.x = input.dx_Position.x + 0.5;\n"
" gl_FragCoord.y = input.dx_Position.y + 0.5;\n";
@@ -961,6 +1072,12 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog,
}
}
+ if (fragmentShader->usesDeferredInit())
+ {
+ pixelHLSL += "\n"
+ " initializeDeferredGlobals();\n";
+ }
+
pixelHLSL += "\n"
" gl_main();\n"
"\n"
@@ -1013,9 +1130,9 @@ std::string DynamicHLSL::generatePointSpriteHLSL(int registers, ShaderD3D *fragm
std::string geomHLSL;
- const SemanticInfo &inSemantics = getSemanticInfo(registers, fragmentShader->mUsesFragCoord,
+ const SemanticInfo &inSemantics = getSemanticInfo(registers, true, fragmentShader->mUsesFragCoord,
false, true, false);
- const SemanticInfo &outSemantics = getSemanticInfo(registers, fragmentShader->mUsesFragCoord,
+ const SemanticInfo &outSemantics = getSemanticInfo(registers, true, fragmentShader->mUsesFragCoord,
fragmentShader->mUsesPointCoord, true, false);
std::string varyingHLSL = generateVaryingHLSL(vertexShader);
@@ -1028,31 +1145,31 @@ std::string DynamicHLSL::generatePointSpriteHLSL(int registers, ShaderD3D *fragm
"struct GS_INPUT\n" + inLinkHLSL + "\n" +
"struct GS_OUTPUT\n" + outLinkHLSL + "\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 = " + Str(mRenderer->getRendererCaps().minAliasedPointSize) + ".0f;\n"
- "static float maxPointSize = " + Str(mRenderer->getRendererCaps().maxAliasedPointSize) + ".0f;\n"
- "\n"
- "[maxvertexcount(4)]\n"
- "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n"
- "{\n"
- " GS_OUTPUT output = (GS_OUTPUT)0;\n"
- " output.gl_Position = input[0].gl_Position;\n"
- " output.gl_PointSize = input[0].gl_PointSize;\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 = " + Str(mRenderer->getRendererCaps().minAliasedPointSize) + ".0f;\n"
+ "static float maxPointSize = " + Str(mRenderer->getRendererCaps().maxAliasedPointSize) + ".0f;\n"
+ "\n"
+ "[maxvertexcount(4)]\n"
+ "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n"
+ "{\n"
+ " GS_OUTPUT output = (GS_OUTPUT)0;\n"
+ " output.gl_Position = input[0].gl_Position;\n"
+ " output.gl_PointSize = input[0].gl_PointSize;\n";
for (int r = 0; r < registers; r++)
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h
index c46bbf6ce0..26ae13b342 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h
@@ -6,11 +6,11 @@
// DynamicHLSL.h: Interface for link and run-time HLSL generation
//
-#ifndef LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_
-#define LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_
+#ifndef LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
+#define LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
#include "common/angleutils.h"
-#include "libGLESv2/Constants.h"
+#include "libANGLE/Constants.h"
#include "angle_gl.h"
@@ -49,7 +49,7 @@ struct PixelShaderOutputVariable
size_t outputIndex;
};
-class DynamicHLSL
+class DynamicHLSL : angle::NonCopyable
{
public:
explicit DynamicHLSL(RendererD3D *const renderer);
@@ -74,15 +74,13 @@ class DynamicHLSL
void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
private:
- DISALLOW_COPY_AND_ASSIGN(DynamicHLSL);
-
RendererD3D *const mRenderer;
struct SemanticInfo;
std::string getVaryingSemantic(bool pointSize) const;
- SemanticInfo getSemanticInfo(int startRegisters, bool fragCoord, bool pointCoord, bool pointSize,
- bool pixelShader) const;
+ SemanticInfo getSemanticInfo(int startRegisters, bool position, bool fragCoord, bool pointCoord,
+ bool pointSize, bool pixelShader) const;
std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const;
std::string generateVaryingHLSL(const ShaderD3D *shader) const;
void storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const;
@@ -98,4 +96,4 @@ class DynamicHLSL
}
-#endif // LIBGLESV2_RENDERER_DYNAMIC_HLSL_H_
+#endif // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
new file mode 100644
index 0000000000..1a4734b269
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -0,0 +1,463 @@
+//
+// 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 "libANGLE/formatutils.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.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));
+
+ const auto &blendState = state.getBlendState();
+
+ for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+ {
+ clearParams.clearColor[i] = false;
+ }
+ clearParams.colorFClearValue = state.getColorClearValue();
+ clearParams.colorClearType = GL_FLOAT;
+ clearParams.colorMaskRed = blendState.colorMaskRed;
+ clearParams.colorMaskGreen = blendState.colorMaskGreen;
+ clearParams.colorMaskBlue = blendState.colorMaskBlue;
+ clearParams.colorMaskAlpha = blendState.colorMaskAlpha;
+ clearParams.clearDepth = false;
+ clearParams.depthClearValue = state.getDepthClearValue();
+ clearParams.clearStencil = false;
+ clearParams.stencilClearValue = state.getStencilClearValue();
+ clearParams.stencilWriteMask = state.getDepthStencilState().stencilWritemask;
+ clearParams.scissorEnabled = state.isScissorTestEnabled();
+ clearParams.scissor = state.getScissor();
+
+ const gl::Framebuffer *framebufferObject = state.getDrawFramebuffer();
+ if (mask & GL_COLOR_BUFFER_BIT)
+ {
+ if (framebufferObject->hasEnabledColorAttachment())
+ {
+ for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+ {
+ clearParams.clearColor[i] = true;
+ }
+ }
+ }
+
+ if (mask & GL_DEPTH_BUFFER_BIT)
+ {
+ if (state.getDepthStencilState().depthMask && framebufferObject->getDepthbuffer() != NULL)
+ {
+ clearParams.clearDepth = true;
+ }
+ }
+
+ if (mask & GL_STENCIL_BUFFER_BIT)
+ {
+ if (framebufferObject->getStencilbuffer() != NULL &&
+ framebufferObject->getStencilbuffer()->getStencilSize() > 0)
+ {
+ clearParams.clearStencil = true;
+ }
+ }
+
+ return clearParams;
+}
+
+}
+
+FramebufferD3D::FramebufferD3D(const gl::Framebuffer::Data &data, RendererD3D *renderer)
+ : FramebufferImpl(data),
+ mRenderer(renderer),
+ mColorAttachmentsForRender(mData.mColorAttachments.size(), nullptr),
+ mInvalidateColorAttachmentCache(true)
+{
+ ASSERT(mRenderer != nullptr);
+}
+
+FramebufferD3D::~FramebufferD3D()
+{
+}
+
+void FramebufferD3D::setColorAttachment(size_t, const gl::FramebufferAttachment *)
+{
+ mInvalidateColorAttachmentCache = true;
+}
+
+void FramebufferD3D::setDepthAttachment(const gl::FramebufferAttachment *)
+{
+}
+
+void FramebufferD3D::setStencilAttachment(const gl::FramebufferAttachment *)
+{
+}
+
+void FramebufferD3D::setDepthStencilAttachment(const gl::FramebufferAttachment *)
+{
+}
+
+void FramebufferD3D::setDrawBuffers(size_t, const GLenum *)
+{
+ mInvalidateColorAttachmentCache = true;
+}
+
+void FramebufferD3D::setReadBuffer(GLenum)
+{
+}
+
+gl::Error FramebufferD3D::invalidate(size_t, const GLenum *)
+{
+ // No-op in D3D
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error FramebufferD3D::invalidateSub(size_t, const GLenum *, const gl::Rectangle &)
+{
+ // No-op in D3D
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error FramebufferD3D::clear(const gl::Data &data, GLbitfield mask)
+{
+ const gl::State &state = *data.state;
+ ClearParameters clearParams = GetClearParameters(state, mask);
+ return clear(state, clearParams);
+}
+
+gl::Error FramebufferD3D::clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values)
+{
+ // glClearBufferfv can be called to clear the color buffer or depth buffer
+ ClearParameters clearParams = GetClearParameters(state, 0);
+
+ if (buffer == GL_COLOR)
+ {
+ for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorFClearValue = gl::ColorF(values[0], values[1], values[2], values[3]);
+ clearParams.colorClearType = GL_FLOAT;
+ }
+
+ if (buffer == GL_DEPTH)
+ {
+ clearParams.clearDepth = true;
+ clearParams.depthClearValue = values[0];
+ }
+
+ return clear(state, clearParams);
+}
+
+gl::Error FramebufferD3D::clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values)
+{
+ // glClearBufferuiv can only be called to clear a color buffer
+ ClearParameters clearParams = GetClearParameters(state, 0);
+ for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]);
+ clearParams.colorClearType = GL_UNSIGNED_INT;
+
+ return clear(state, clearParams);
+}
+
+gl::Error FramebufferD3D::clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values)
+{
+ // glClearBufferiv can be called to clear the color buffer or stencil buffer
+ ClearParameters clearParams = GetClearParameters(state, 0);
+
+ if (buffer == GL_COLOR)
+ {
+ for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorIClearValue = gl::ColorI(values[0], values[1], values[2], values[3]);
+ clearParams.colorClearType = GL_INT;
+ }
+
+ if (buffer == GL_STENCIL)
+ {
+ clearParams.clearStencil = true;
+ clearParams.stencilClearValue = values[1];
+ }
+
+ return clear(state, clearParams);
+}
+
+gl::Error FramebufferD3D::clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+{
+ // glClearBufferfi can only be called to clear a depth stencil buffer
+ ClearParameters clearParams = GetClearParameters(state, 0);
+ clearParams.clearDepth = true;
+ clearParams.depthClearValue = depth;
+ clearParams.clearStencil = true;
+ clearParams.stencilClearValue = stencil;
+
+ return clear(state, clearParams);
+}
+
+GLenum FramebufferD3D::getImplementationColorReadFormat() const
+{
+ const gl::FramebufferAttachment *readAttachment = mData.getReadAttachment();
+
+ if (readAttachment == nullptr)
+ {
+ return GL_NONE;
+ }
+
+ RenderTargetD3D *attachmentRenderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(readAttachment, &attachmentRenderTarget);
+ if (error.isError())
+ {
+ return GL_NONE;
+ }
+
+ GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget);
+ const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat);
+
+ return implementationFormatInfo.format;
+}
+
+GLenum FramebufferD3D::getImplementationColorReadType() const
+{
+ const gl::FramebufferAttachment *readAttachment = mData.getReadAttachment();
+
+ if (readAttachment == nullptr)
+ {
+ return GL_NONE;
+ }
+
+ RenderTargetD3D *attachmentRenderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(readAttachment, &attachmentRenderTarget);
+ if (error.isError())
+ {
+ return GL_NONE;
+ }
+
+ GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget);
+ const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat);
+
+ return implementationFormatInfo.type;
+}
+
+gl::Error FramebufferD3D::readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const
+{
+ const gl::PixelPackState &packState = state.getPackState();
+
+ if (packState.rowLength != 0 || packState.skipRows != 0 || packState.skipPixels != 0)
+ {
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION, "invalid pixel store parameters in readPixels");
+ }
+
+ GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, type);
+ const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(sizedInternalFormat);
+ GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, 0);
+
+ return readPixels(area, format, type, outputPitch, packState, reinterpret_cast<uint8_t*>(pixels));
+}
+
+gl::Error FramebufferD3D::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
+ GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer)
+{
+ bool blitRenderTarget = false;
+ if ((mask & GL_COLOR_BUFFER_BIT) &&
+ sourceFramebuffer->getReadColorbuffer() != nullptr &&
+ mData.getFirstColorAttachment() != nullptr)
+ {
+ blitRenderTarget = true;
+ }
+
+ bool blitStencil = false;
+ if ((mask & GL_STENCIL_BUFFER_BIT) &&
+ sourceFramebuffer->getStencilbuffer() != nullptr &&
+ mData.mStencilAttachment != nullptr)
+ {
+ blitStencil = true;
+ }
+
+ bool blitDepth = false;
+ if ((mask & GL_DEPTH_BUFFER_BIT) &&
+ sourceFramebuffer->getDepthbuffer() != nullptr &&
+ mData.mDepthAttachment != nullptr)
+ {
+ blitDepth = true;
+ }
+
+ if (blitRenderTarget || blitDepth || blitStencil)
+ {
+ const gl::Rectangle *scissor = state.isScissorTestEnabled() ? &state.getScissor() : NULL;
+ gl::Error error = blit(sourceArea, destArea, scissor, blitRenderTarget, blitDepth, blitStencil,
+ filter, sourceFramebuffer);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+GLenum FramebufferD3D::checkStatus() const
+{
+ // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
+ for (size_t colorAttachment = 0; colorAttachment < mData.mColorAttachments.size(); colorAttachment++)
+ {
+ const gl::FramebufferAttachment *attachment = mData.mColorAttachments[colorAttachment];
+ if (attachment != nullptr)
+ {
+ for (size_t prevColorAttachment = 0; prevColorAttachment < colorAttachment; prevColorAttachment++)
+ {
+ const gl::FramebufferAttachment *prevAttachment = mData.mColorAttachments[prevColorAttachment];
+ if (prevAttachment != nullptr &&
+ (attachment->id() == prevAttachment->id() &&
+ attachment->type() == prevAttachment->type()))
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+ }
+ }
+ }
+
+ return GL_FRAMEBUFFER_COMPLETE;
+}
+
+const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const Workarounds &workarounds) const
+{
+ if (!workarounds.mrtPerfWorkaround)
+ {
+ return mData.mColorAttachments;
+ }
+
+ if (!mInvalidateColorAttachmentCache)
+ {
+ return mColorAttachmentsForRender;
+ }
+
+ // Does not actually free memory
+ mColorAttachmentsForRender.clear();
+
+ for (size_t attachmentIndex = 0; attachmentIndex < mData.mColorAttachments.size(); ++attachmentIndex)
+ {
+ GLenum drawBufferState = mData.mDrawBufferStates[attachmentIndex];
+ gl::FramebufferAttachment *colorAttachment = mData.mColorAttachments[attachmentIndex];
+
+ if (colorAttachment != nullptr && drawBufferState != GL_NONE)
+ {
+ ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex));
+ mColorAttachmentsForRender.push_back(colorAttachment);
+ }
+ }
+
+ mInvalidateColorAttachmentCache = false;
+ return mColorAttachmentsForRender;
+}
+
+gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTargetD3D **outRT)
+{
+ if (attachment->type() == GL_TEXTURE)
+ {
+ gl::Texture *texture = attachment->getTexture();
+ ASSERT(texture);
+ TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
+ const gl::ImageIndex *index = attachment->getTextureImageIndex();
+ ASSERT(index);
+ return textureD3D->getRenderTarget(*index, outRT);
+ }
+ else if (attachment->type() == GL_RENDERBUFFER)
+ {
+ gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
+ ASSERT(renderbuffer);
+ RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
+ *outRT = renderbufferD3D->getRenderTarget();
+ return gl::Error(GL_NO_ERROR);
+ }
+ else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
+ {
+ const gl::DefaultAttachment *defaultAttachment = static_cast<const gl::DefaultAttachment *>(attachment);
+ const egl::Surface *surface = defaultAttachment->getSurface();
+ ASSERT(surface);
+ const SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+ ASSERT(surfaceD3D);
+
+ if (defaultAttachment->getBinding() == GL_BACK)
+ {
+ *outRT = surfaceD3D->getSwapChain()->getColorRenderTarget();
+ }
+ else
+ {
+ *outRT = surfaceD3D->getSwapChain()->getDepthStencilRenderTarget();
+ }
+ return gl::Error(GL_NO_ERROR);
+ }
+ else
+ {
+ UNREACHABLE();
+ return gl::Error(GL_INVALID_OPERATION);
+ }
+}
+
+// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
+unsigned int GetAttachmentSerial(const gl::FramebufferAttachment *attachment)
+{
+ if (attachment->type() == GL_TEXTURE)
+ {
+ gl::Texture *texture = attachment->getTexture();
+ ASSERT(texture);
+ TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
+ const gl::ImageIndex *index = attachment->getTextureImageIndex();
+ ASSERT(index);
+ return textureD3D->getRenderTargetSerial(*index);
+ }
+ else if (attachment->type() == GL_RENDERBUFFER)
+ {
+ gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
+ ASSERT(renderbuffer);
+ RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
+ return renderbufferD3D->getRenderTargetSerial();
+ }
+ else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
+ {
+ const gl::DefaultAttachment *defaultAttachment = static_cast<const gl::DefaultAttachment *>(attachment);
+ const egl::Surface *surface = defaultAttachment->getSurface();
+ ASSERT(surface);
+ const SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+ ASSERT(surfaceD3D);
+
+ if (defaultAttachment->getBinding() == GL_BACK)
+ {
+ return surfaceD3D->getSwapChain()->getColorRenderTarget()->getSerial();
+ }
+ else
+ {
+ return surfaceD3D->getSwapChain()->getDepthStencilRenderTarget()->getSerial();
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h
new file mode 100644
index 0000000000..d5d2dae8bd
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h
@@ -0,0 +1,111 @@
+//
+// 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 <vector>
+#include <cstdint>
+
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/FramebufferImpl.h"
+
+namespace gl
+{
+class FramebufferAttachment;
+struct PixelPackState;
+}
+
+namespace rx
+{
+class RenderTargetD3D;
+class RendererD3D;
+
+struct ClearParameters
+{
+ bool clearColor[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
+ gl::ColorF colorFClearValue;
+ gl::ColorI colorIClearValue;
+ gl::ColorUI colorUIClearValue;
+ GLenum colorClearType;
+ bool colorMaskRed;
+ bool colorMaskGreen;
+ bool colorMaskBlue;
+ bool colorMaskAlpha;
+
+ bool clearDepth;
+ float depthClearValue;
+
+ bool clearStencil;
+ GLint stencilClearValue;
+ GLuint stencilWriteMask;
+
+ bool scissorEnabled;
+ gl::Rectangle scissor;
+};
+
+class FramebufferD3D : public FramebufferImpl
+{
+ public:
+ FramebufferD3D(const gl::Framebuffer::Data &data, RendererD3D *renderer);
+ virtual ~FramebufferD3D();
+
+ void setColorAttachment(size_t index, const gl::FramebufferAttachment *attachment) override;
+ void setDepthAttachment(const gl::FramebufferAttachment *attachment) override;
+ void setStencilAttachment(const gl::FramebufferAttachment *attachment) override;
+ void setDepthStencilAttachment(const gl::FramebufferAttachment *attachment) override;
+
+ void setDrawBuffers(size_t count, const GLenum *buffers) override;
+ void setReadBuffer(GLenum buffer) override;
+
+ gl::Error invalidate(size_t count, const GLenum *attachments) override;
+ gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override;
+
+ gl::Error clear(const gl::Data &data, GLbitfield mask) override;
+ gl::Error clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) override;
+ gl::Error clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) override;
+ gl::Error clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) override;
+ gl::Error clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override;
+
+ GLenum getImplementationColorReadFormat() const override;
+ GLenum getImplementationColorReadType() const override;
+ gl::Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const override;
+
+ gl::Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
+ GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) override;
+
+ GLenum checkStatus() const override;
+
+ const gl::AttachmentList &getColorAttachmentsForRender(const Workarounds &workarounds) const;
+
+ protected:
+ // Cache variable
+ mutable gl::AttachmentList mColorAttachmentsForRender;
+ mutable bool mInvalidateColorAttachmentCache;
+
+ private:
+ RendererD3D *const mRenderer;
+
+ virtual gl::Error clear(const gl::State &state, const ClearParameters &clearParams) = 0;
+
+ virtual gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch,
+ const gl::PixelPackState &pack, uint8_t *pixels) const = 0;
+
+ virtual gl::Error blit(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;
+
+ virtual GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const = 0;
+};
+
+gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTargetD3D **outRT);
+unsigned int GetAttachmentSerial(const gl::FramebufferAttachment *attachment);
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
index 776d92b202..8961a36ec5 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
@@ -4,22 +4,17 @@
// found in the LICENSE file.
//
-#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
-#include "libGLESv2/Program.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/HLSLCompiler.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/features.h"
-#include "common/features.h"
#include "common/utilities.h"
+#include "third_party/trace_event/trace_event.h"
+
#ifndef QT_D3DCOMPILER_DLL
#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
#endif
-#ifndef D3DCOMPILE_RESERVED16
-#define D3DCOMPILE_RESERVED16 (1 << 16)
-#endif
-#ifndef D3DCOMPILE_RESERVED17
-#define D3DCOMPILE_RESERVED17 (1 << 17)
-#endif
// Definitions local to the translation unit
namespace
@@ -31,6 +26,15 @@ namespace
#define CREATE_COMPILER_FLAG_INFO(flag) { flag, #flag }
+#if defined(ANGLE_MINGW32_COMPAT)
+#ifndef D3DCOMPILE_RESERVED16
+#define D3DCOMPILE_RESERVED16 0x10000
+#endif
+#ifndef D3DCOMPILE_RESERVED17
+#define D3DCOMPILE_RESERVED17 0x20000
+#endif
+#endif
+
struct CompilerFlagInfo
{
UINT mFlag;
@@ -128,6 +132,7 @@ HLSLCompiler::~HLSLCompiler()
bool HLSLCompiler::initialize()
{
+ TRACE_EVENT0("gpu", "initializeCompiler");
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
// Find a D3DCompiler module that had already been loaded based on a predefined list of versions.
@@ -151,8 +156,6 @@ bool HLSLCompiler::initialize()
defaultCompiler,
L"d3dcompiler_47.dll",
L"d3dcompiler_46.dll",
- L"d3dcompiler_45.dll",
- L"d3dcompiler_44.dll",
L"d3dcompiler_43.dll",
0
};
@@ -215,7 +218,7 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
ASSERT(mD3DCompileFunc);
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- if (gl::perfActive())
+ if (gl::DebugAnnotationsActive())
{
std::string sourcePath = getTempPath();
std::string sourceText = FormatString("#line 2 \"%s\"\n\n%s", sourcePath.c_str(), hlsl.c_str());
@@ -242,7 +245,11 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string
TRACE("\n%s", hlsl.c_str());
TRACE("\n%s", message.c_str());
- if (message.find("error X3531:") != std::string::npos) // "can't unroll loops marked with loop attribute"
+ if (message.find("error X3531:") != std::string::npos || // "can't unroll loops marked with loop attribute"
+ message.find("error X4014:") != std::string::npos) // "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.
{
macros = NULL; // Disable [loop] and [flatten]
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.h
index ff56f8035a..a824952553 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.h
@@ -1,7 +1,7 @@
-#ifndef LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
-#define LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
+#ifndef LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_
+#define LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
#include "common/angleutils.h"
#include "common/platform.h"
@@ -26,7 +26,7 @@ struct CompileConfig
CompileConfig(UINT flags, const std::string &name);
};
-class HLSLCompiler
+class HLSLCompiler : angle::NonCopyable
{
public:
HLSLCompiler();
@@ -44,8 +44,6 @@ class HLSLCompiler
std::string disassembleBinary(ID3DBlob* shaderBinary) const;
private:
- DISALLOW_COPY_AND_ASSIGN(HLSLCompiler);
-
HMODULE mD3DCompilerModule;
pD3DCompile mD3DCompileFunc;
pD3DDisassemble mD3DDisassembleFunc;
@@ -53,4 +51,4 @@ class HLSLCompiler
}
-#endif // LIBGLESV2_RENDERER_HLSL_D3DCOMPILER_H_
+#endif // LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp
new file mode 100644
index 0000000000..4e6f61150a
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp
@@ -0,0 +1,47 @@
+//
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// 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"
+
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+
+namespace rx
+{
+
+ImageD3D::ImageD3D()
+ : mWidth(0),
+ mHeight(0),
+ mDepth(0),
+ mInternalFormat(GL_NONE),
+ mTarget(GL_NONE),
+ mRenderable(false),
+ mDirty(false)
+{
+}
+
+gl::Error ImageD3D::copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source)
+{
+ gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer();
+ ASSERT(colorbuffer);
+
+ RenderTargetD3D *renderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ASSERT(renderTarget);
+ return copy(destOffset, sourceArea, renderTarget);
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.h
new file mode 100644
index 0000000000..0fe88a8f59
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.h
@@ -0,0 +1,84 @@
+//
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// 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 "libANGLE/Error.h"
+
+namespace gl
+{
+class Framebuffer;
+struct ImageIndex;
+struct Box;
+struct Extents;
+struct Offset;
+struct Rectangle;
+struct PixelUnpackState;
+}
+
+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; }
+ GLenum getTarget() const { return mTarget; }
+ bool isRenderableFormat() const { return mRenderable; }
+
+ void markDirty() { mDirty = true; }
+ void markClean() { mDirty = false; }
+ virtual bool isDirty() const = 0;
+
+ virtual bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) = 0;
+
+ virtual gl::Error loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input) = 0;
+ virtual gl::Error loadCompressedData(const gl::Box &area, const void *input) = 0;
+
+ virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error setManagedSurface3D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error setManagedSurface2DArray(TextureStorage *storage, int layer, int level) { return gl::Error(GL_NO_ERROR); };
+ virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0;
+
+ virtual gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea,
+ const gl::ImageIndex &sourceIndex, TextureStorage *source) = 0;
+
+ gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source);
+
+ protected:
+ GLsizei mWidth;
+ GLsizei mHeight;
+ GLsizei mDepth;
+ GLenum mInternalFormat;
+ bool mRenderable;
+ GLenum mTarget;
+
+ bool mDirty;
+
+ private:
+ virtual gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source) = 0;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_IMAGED3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.cpp
index aa614f6cc4..677b8bb240 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.cpp
@@ -7,8 +7,8 @@
// IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface
// class with derivations, classes that perform graphics API agnostic index buffer operations.
-#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
namespace rx
{
@@ -35,9 +35,9 @@ void IndexBuffer::updateSerial()
}
-IndexBufferInterface::IndexBufferInterface(RendererD3D *renderer, bool dynamic) : mRenderer(renderer)
+IndexBufferInterface::IndexBufferInterface(BufferFactoryD3D *factory, bool dynamic)
{
- mIndexBuffer = renderer->createIndexBuffer();
+ mIndexBuffer = factory->createIndexBuffer();
mDynamic = dynamic;
mWritePosition = 0;
@@ -66,7 +66,7 @@ unsigned int IndexBufferInterface::getSerial() const
return mIndexBuffer->getSerial();
}
-gl::Error IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset)
+gl::Error IndexBufferInterface::mapBuffer(unsigned int size, void **outMappedMemory, unsigned int *streamOffset)
{
// Protect against integer overflow
if (mWritePosition + size < mWritePosition)
@@ -130,7 +130,8 @@ gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum in
}
}
-StreamingIndexBufferInterface::StreamingIndexBufferInterface(RendererD3D *renderer) : IndexBufferInterface(renderer, true)
+StreamingIndexBufferInterface::StreamingIndexBufferInterface(BufferFactoryD3D *factory)
+ : IndexBufferInterface(factory, true)
{
}
@@ -165,7 +166,8 @@ gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, G
}
-StaticIndexBufferInterface::StaticIndexBufferInterface(RendererD3D *renderer) : IndexBufferInterface(renderer, false)
+StaticIndexBufferInterface::StaticIndexBufferInterface(BufferFactoryD3D *factory)
+ : IndexBufferInterface(factory, false)
{
}
@@ -191,9 +193,4 @@ gl::Error StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLen
}
}
-IndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache()
-{
- return &mIndexRangeCache;
-}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.h
index a34d30bbf3..36262f1d09 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.h
@@ -7,18 +7,18 @@
// IndexBuffer.h: Defines the abstract IndexBuffer class and IndexBufferInterface
// class with derivations, classes that perform graphics API agnostic index buffer operations.
-#ifndef LIBGLESV2_RENDERER_INDEXBUFFER_H_
-#define LIBGLESV2_RENDERER_INDEXBUFFER_H_
+#ifndef LIBANGLE_RENDERER_D3D_INDEXBUFFER_H_
+#define LIBANGLE_RENDERER_D3D_INDEXBUFFER_H_
#include "common/angleutils.h"
-#include "libGLESv2/Error.h"
-#include "libGLESv2/renderer/IndexRangeCache.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/IndexRangeCache.h"
namespace rx
{
-class RendererD3D;
+class BufferFactoryD3D;
-class IndexBuffer
+class IndexBuffer : angle::NonCopyable
{
public:
IndexBuffer();
@@ -41,16 +41,14 @@ class IndexBuffer
void updateSerial();
private:
- DISALLOW_COPY_AND_ASSIGN(IndexBuffer);
-
unsigned int mSerial;
static unsigned int mNextSerial;
};
-class IndexBufferInterface
+class IndexBufferInterface : angle::NonCopyable
{
public:
- IndexBufferInterface(RendererD3D *renderer, bool dynamic);
+ IndexBufferInterface(BufferFactoryD3D *factory, bool dynamic);
virtual ~IndexBufferInterface();
virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) = 0;
@@ -74,11 +72,7 @@ class IndexBufferInterface
gl::Error setBufferSize(unsigned int bufferSize, GLenum indexType);
private:
- DISALLOW_COPY_AND_ASSIGN(IndexBufferInterface);
-
- RendererD3D *const mRenderer;
-
- IndexBuffer* mIndexBuffer;
+ IndexBuffer *mIndexBuffer;
unsigned int mWritePosition;
bool mDynamic;
@@ -87,26 +81,21 @@ class IndexBufferInterface
class StreamingIndexBufferInterface : public IndexBufferInterface
{
public:
- StreamingIndexBufferInterface(RendererD3D *renderer);
+ explicit StreamingIndexBufferInterface(BufferFactoryD3D *factory);
~StreamingIndexBufferInterface();
- virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType);
+ gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) override;
};
class StaticIndexBufferInterface : public IndexBufferInterface
{
public:
- explicit StaticIndexBufferInterface(RendererD3D *renderer);
+ explicit StaticIndexBufferInterface(BufferFactoryD3D *factory);
~StaticIndexBufferInterface();
- virtual gl::Error reserveBufferSpace(unsigned int size, GLenum indexType);
-
- IndexRangeCache *getIndexRangeCache();
-
- private:
- IndexRangeCache mIndexRangeCache;
+ gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) override;
};
}
-#endif // LIBGLESV2_RENDERER_INDEXBUFFER_H_
+#endif // LIBANGLE_RENDERER_D3D_INDEXBUFFER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp
index eddd9de887..7dad269435 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp
@@ -7,13 +7,11 @@
// IndexDataManager.cpp: Defines the IndexDataManager, a class that
// runs the Buffer translation process for index buffers.
-#include "libGLESv2/renderer/d3d/IndexDataManager.h"
-#include "libGLESv2/renderer/d3d/BufferD3D.h"
-#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/formatutils.h"
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/formatutils.h"
namespace rx
{
@@ -57,10 +55,11 @@ static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void
else UNREACHABLE();
}
-IndexDataManager::IndexDataManager(RendererD3D *renderer)
- : mRenderer(renderer),
- mStreamingBufferShort(NULL),
- mStreamingBufferInt(NULL)
+IndexDataManager::IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass)
+ : mFactory(factory),
+ mRendererClass(rendererClass),
+ mStreamingBufferShort(nullptr),
+ mStreamingBufferInt(nullptr)
{
}
@@ -85,8 +84,10 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf
{
offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
- storage = BufferD3D::makeBufferD3D(buffer->getImplementation());
+ storage = GetImplAs<BufferD3D>(buffer);
+ // We'll trust that the compiler will optimize the % below:
+ // the operands are unsigned and the divisor is a constant.
switch (type)
{
case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break;
@@ -116,26 +117,18 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf
if (directStorage)
{
streamOffset = offset;
-
- if (!buffer->getIndexRangeCache()->findRange(type, offset, count, NULL, NULL))
- {
- buffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, offset);
- }
}
else if (staticBuffer && staticBuffer->getBufferSize() != 0 && staticBuffer->getIndexType() == type && alignedOffset)
{
indexBuffer = staticBuffer;
- if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, NULL, &streamOffset))
- {
- streamOffset = (offset / typeInfo.bytes) * gl::GetTypeInfo(destinationIndexType).bytes;
- staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
- }
+ // Using bit-shift here is faster than using division.
+ streamOffset = (offset >> typeInfo.bytesShift) << gl::GetTypeInfo(destinationIndexType).bytesShift;
}
// Avoid D3D11's primitive restart index value
// see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
- if (translated->indexRange.end == 0xFFFF && type == GL_UNSIGNED_SHORT && mRenderer->getMajorShaderModel() > 3)
+ if (translated->indexRange.end == 0xFFFF && type == GL_UNSIGNED_SHORT && mRendererClass == RENDERER_D3D11)
{
destinationIndexType = GL_UNSIGNED_INT;
directStorage = false;
@@ -159,7 +152,8 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf
if (staticBuffer->getBufferSize() == 0 && alignedOffset)
{
indexBuffer = staticBuffer;
- convertCount = storage->getSize() / typeInfo.bytes;
+ // Using bit-shift here is faster than using division.
+ convertCount = storage->getSize() >> typeInfo.bytesShift;
}
else
{
@@ -170,13 +164,14 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf
ASSERT(indexBuffer);
- if (convertCount > std::numeric_limits<unsigned int>::max() / destTypeInfo.bytes)
+ // Using bit-shift here is faster than using division.
+ if (convertCount > (std::numeric_limits<unsigned int>::max() >> destTypeInfo.bytesShift))
{
return gl::Error(GL_OUT_OF_MEMORY, "Reserving %u indices of %u bytes each exceeds the maximum buffer size.",
convertCount, destTypeInfo.bytes);
}
- unsigned int bufferSizeRequired = convertCount * destTypeInfo.bytes;
+ unsigned int bufferSizeRequired = convertCount << destTypeInfo.bytesShift;
error = indexBuffer->reserveBufferSpace(bufferSizeRequired, type);
if (error.isError())
{
@@ -209,21 +204,22 @@ gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buf
if (staticBuffer)
{
- streamOffset = (offset / typeInfo.bytes) * destTypeInfo.bytes;
- staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
+ // Using bit-shift here is faster than using division.
+ streamOffset = (offset >> typeInfo.bytesShift) << destTypeInfo.bytesShift;
}
}
translated->storage = directStorage ? storage : NULL;
translated->indexBuffer = indexBuffer ? indexBuffer->getIndexBuffer() : NULL;
translated->serial = directStorage ? storage->getSerial() : indexBuffer->getSerial();
- translated->startIndex = streamOffset / destTypeInfo.bytes;
+ // Using bit-shift here is faster than using division.
+ translated->startIndex = (streamOffset >> destTypeInfo.bytesShift);
translated->startOffset = streamOffset;
translated->indexType = destinationIndexType;
if (storage)
{
- storage->promoteStaticUsage(count * typeInfo.bytes);
+ storage->promoteStaticUsage(count << typeInfo.bytesShift);
}
return gl::Error(GL_NO_ERROR);
@@ -236,7 +232,7 @@ gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType,
{
if (!mStreamingBufferInt)
{
- mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
+ mStreamingBufferInt = new StreamingIndexBufferInterface(mFactory);
gl::Error error = mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
if (error.isError())
{
@@ -254,7 +250,7 @@ gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType,
if (!mStreamingBufferShort)
{
- mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
+ mStreamingBufferShort = new StreamingIndexBufferInterface(mFactory);
gl::Error error = mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT);
if (error.isError())
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.h
index a1aee1588b..275b3720c5 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.h
@@ -7,14 +7,15 @@
// IndexDataManager.h: Defines the IndexDataManager, a class that
// runs the Buffer translation process for index buffers.
-#ifndef LIBGLESV2_INDEXDATAMANAGER_H_
-#define LIBGLESV2_INDEXDATAMANAGER_H_
+#ifndef LIBANGLE_INDEXDATAMANAGER_H_
+#define LIBANGLE_INDEXDATAMANAGER_H_
+
+#include <GLES2/gl2.h>
#include "common/angleutils.h"
#include "common/mathutil.h"
-#include "libGLESv2/Error.h"
-
-#include <GLES2/gl2.h>
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
namespace
{
@@ -47,25 +48,23 @@ struct TranslatedIndexData
unsigned int serial;
};
-class IndexDataManager
+class IndexDataManager : angle::NonCopyable
{
public:
- explicit IndexDataManager(RendererD3D *renderer);
+ explicit IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass);
virtual ~IndexDataManager();
gl::Error prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated);
private:
- gl::Error getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer);
-
- DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
-
- RendererD3D *const mRenderer;
+ gl::Error getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer);
+ BufferFactoryD3D *const mFactory;
+ RendererClass mRendererClass;
StreamingIndexBufferInterface *mStreamingBufferShort;
StreamingIndexBufferInterface *mStreamingBufferInt;
};
}
-#endif // LIBGLESV2_INDEXDATAMANAGER_H_
+#endif // LIBANGLE_INDEXDATAMANAGER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 75da78110e..9ce9a27cd3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -6,19 +6,19 @@
// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
-#include "libGLESv2/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
-#include "common/features.h"
#include "common/utilities.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/Program.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/renderer/ShaderExecutable.h"
-#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
-#include "libGLESv2/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/features.h"
+#include "libANGLE/renderer/d3d/DynamicHLSL.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
namespace rx
{
@@ -84,10 +84,12 @@ void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAtt
std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<PixelShaderOutputVariable> &shaderOutputVars)
{
- std::vector<GLenum> defaultPixelOutput(1);
+ std::vector<GLenum> defaultPixelOutput;
- ASSERT(!shaderOutputVars.empty());
- defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex;
+ if (!shaderOutputVars.empty())
+ {
+ defaultPixelOutput.push_back(GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex);
+ }
return defaultPixelOutput;
}
@@ -102,11 +104,31 @@ bool IsRowMajorLayout(const sh::ShaderVariable &var)
return false;
}
+struct AttributeSorter
+{
+ AttributeSorter(const ProgramImpl::SemanticIndexArray &semanticIndices)
+ : originalIndices(&semanticIndices)
+ {
+ }
+
+ bool operator()(int a, int b)
+ {
+ int indexA = (*originalIndices)[a];
+ int indexB = (*originalIndices)[b];
+
+ if (indexA == -1) return false;
+ if (indexB == -1) return true;
+ return (indexA < indexB);
+ }
+
+ const ProgramImpl::SemanticIndexArray *originalIndices;
+};
+
}
ProgramD3D::VertexExecutable::VertexExecutable(const gl::VertexFormat inputLayout[],
const GLenum signature[],
- ShaderExecutable *shaderExecutable)
+ ShaderExecutableD3D *shaderExecutable)
: mShaderExecutable(shaderExecutable)
{
for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
@@ -134,7 +156,7 @@ bool ProgramD3D::VertexExecutable::matchesSignature(const GLenum signature[]) co
return true;
}
-ProgramD3D::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutable *shaderExecutable)
+ProgramD3D::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutableD3D *shaderExecutable)
: mOutputSignature(outputSignature),
mShaderExecutable(shaderExecutable)
{
@@ -149,20 +171,22 @@ ProgramD3D::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureTy
{
}
+unsigned int ProgramD3D::mCurrentSerial = 1;
+
ProgramD3D::ProgramD3D(RendererD3D *renderer)
: ProgramImpl(),
mRenderer(renderer),
mDynamicHLSL(NULL),
mGeometryExecutable(NULL),
- mVertexWorkarounds(ANGLE_D3D_WORKAROUND_NONE),
- mPixelWorkarounds(ANGLE_D3D_WORKAROUND_NONE),
mUsesPointSize(false),
mVertexUniformStorage(NULL),
mFragmentUniformStorage(NULL),
mUsedVertexSamplerRange(0),
mUsedPixelSamplerRange(0),
mDirtySamplerMapping(true),
- mShaderVersion(100)
+ mTextureUnitTypesCache(renderer->getRendererCaps().maxCombinedTextureImageUnits),
+ mShaderVersion(100),
+ mSerial(issueSerial())
{
mDynamicHLSL = new DynamicHLSL(renderer);
}
@@ -173,18 +197,6 @@ ProgramD3D::~ProgramD3D()
SafeDelete(mDynamicHLSL);
}
-ProgramD3D *ProgramD3D::makeProgramD3D(ProgramImpl *impl)
-{
- ASSERT(HAS_DYNAMIC_TYPE(ProgramD3D*, impl));
- return static_cast<ProgramD3D*>(impl);
-}
-
-const ProgramD3D *ProgramD3D::makeProgramD3D(const ProgramImpl *impl)
-{
- ASSERT(HAS_DYNAMIC_TYPE(const ProgramD3D*, impl));
- return static_cast<const ProgramD3D*>(impl);
-}
-
bool ProgramD3D::usesPointSpriteEmulation() const
{
return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
@@ -192,7 +204,12 @@ bool ProgramD3D::usesPointSpriteEmulation() const
bool ProgramD3D::usesGeometryShader() const
{
- return usesPointSpriteEmulation();
+ return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation();
+}
+
+bool ProgramD3D::usesInstancedPointSpriteEmulation() const
+{
+ return mRenderer->getWorkarounds().useInstancedPointSpriteEmulation;
}
GLint ProgramD3D::getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const
@@ -276,7 +293,7 @@ void ProgramD3D::updateSamplerMapping()
if (targetUniform->dirty)
{
- if (gl::IsSampler(targetUniform->type))
+ if (gl::IsSamplerType(targetUniform->type))
{
int count = targetUniform->elementCount();
GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data);
@@ -324,7 +341,7 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
// DrawArrays and DrawElements will issue the INVALID_OPERATION error.
updateSamplerMapping();
- std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE);
+ std::fill(mTextureUnitTypesCache.begin(), mTextureUnitTypesCache.end(), GL_NONE);
for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
{
@@ -332,19 +349,19 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
{
unsigned int unit = mSamplersPS[i].logicalTextureUnit;
- if (unit >= textureUnitTypes.size())
+ if (unit >= caps.maxCombinedTextureImageUnits)
{
if (infoLog)
{
- infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
+ infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, caps.maxCombinedTextureImageUnits);
}
return false;
}
- if (textureUnitTypes[unit] != GL_NONE)
+ if (mTextureUnitTypesCache[unit] != GL_NONE)
{
- if (mSamplersPS[i].textureType != textureUnitTypes[unit])
+ if (mSamplersPS[i].textureType != mTextureUnitTypesCache[unit])
{
if (infoLog)
{
@@ -356,7 +373,7 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
}
else
{
- textureUnitTypes[unit] = mSamplersPS[i].textureType;
+ mTextureUnitTypesCache[unit] = mSamplersPS[i].textureType;
}
}
}
@@ -367,19 +384,19 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
{
unsigned int unit = mSamplersVS[i].logicalTextureUnit;
- if (unit >= textureUnitTypes.size())
+ if (unit >= caps.maxCombinedTextureImageUnits)
{
if (infoLog)
{
- infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
+ infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, caps.maxCombinedTextureImageUnits);
}
return false;
}
- if (textureUnitTypes[unit] != GL_NONE)
+ if (mTextureUnitTypesCache[unit] != GL_NONE)
{
- if (mSamplersVS[i].textureType != textureUnitTypes[unit])
+ if (mSamplersVS[i].textureType != mTextureUnitTypesCache[unit])
{
if (infoLog)
{
@@ -391,7 +408,7 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
}
else
{
- textureUnitTypes[unit] = mSamplersVS[i].textureType;
+ mTextureUnitTypesCache[unit] = mSamplersVS[i].textureType;
}
}
}
@@ -399,8 +416,15 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
return true;
}
-gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
+LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
{
+ int compileFlags = stream->readInt<int>();
+ if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+ {
+ infoLog.append("Mismatched compilation flags.");
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
+ }
+
stream->readInt(&mShaderVersion);
const unsigned int psSamplerCount = stream->readInt<unsigned int>();
@@ -429,7 +453,7 @@ gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *str
if (stream->error())
{
infoLog.append("Invalid program binary.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
mUniforms.resize(uniformCount);
@@ -462,7 +486,7 @@ gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *str
if (stream->error())
{
infoLog.append("Invalid program binary.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
mUniformIndex.resize(uniformIndexCount);
@@ -477,7 +501,7 @@ gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *str
if (stream->error())
{
infoLog.append("Invalid program binary.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
mUniformBlocks.resize(uniformBlockCount);
@@ -518,9 +542,9 @@ gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *str
}
stream->readString(&mVertexHLSL);
- stream->readInt(&mVertexWorkarounds);
+ stream->readBytes(reinterpret_cast<unsigned char*>(&mVertexWorkarounds), sizeof(D3DCompilerWorkarounds));
stream->readString(&mPixelHLSL);
- stream->readInt(&mPixelWorkarounds);
+ stream->readBytes(reinterpret_cast<unsigned char*>(&mPixelWorkarounds), sizeof(D3DCompilerWorkarounds));
stream->readBool(&mUsesFragDepth);
stream->readBool(&mUsesPointSize);
@@ -553,7 +577,7 @@ gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *str
unsigned int vertexShaderSize = stream->readInt<unsigned int>();
const unsigned char *vertexShaderFunction = binary + stream->offset();
- ShaderExecutable *shaderExecutable = NULL;
+ ShaderExecutableD3D *shaderExecutable = NULL;
gl::Error error = mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize,
SHADER_VERTEX,
mTransformFeedbackLinkedVaryings,
@@ -561,13 +585,13 @@ gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *str
&shaderExecutable);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
if (!shaderExecutable)
{
infoLog.append("Could not create vertex shader.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
// generated converted input layout
@@ -592,20 +616,20 @@ gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *str
const size_t pixelShaderSize = stream->readInt<unsigned int>();
const unsigned char *pixelShaderFunction = binary + stream->offset();
- ShaderExecutable *shaderExecutable = NULL;
+ ShaderExecutableD3D *shaderExecutable = NULL;
gl::Error error = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize, SHADER_PIXEL,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
&shaderExecutable);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
if (!shaderExecutable)
{
infoLog.append("Could not create pixel shader.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
// add new binary
@@ -625,13 +649,13 @@ gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *str
&mGeometryExecutable);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
if (!mGeometryExecutable)
{
infoLog.append("Could not create geometry shader.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
stream->skip(geometryShaderSize);
}
@@ -643,16 +667,19 @@ gl::LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *str
if (memcmp(&identifier, &binaryIdentifier, sizeof(GUID)) != 0)
{
infoLog.append("Invalid program binary.");
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
initializeUniformStorage();
+ initAttributesByLayout();
- return gl::LinkResult(true, gl::Error(GL_NO_ERROR));
+ return LinkResult(true, gl::Error(GL_NO_ERROR));
}
gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
{
+ stream->writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
+
stream->writeInt(mShaderVersion);
stream->writeInt(mSamplersPS.size());
@@ -738,9 +765,9 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
}
stream->writeString(mVertexHLSL);
- stream->writeInt(mVertexWorkarounds);
+ stream->writeBytes(reinterpret_cast<unsigned char*>(&mVertexWorkarounds), sizeof(D3DCompilerWorkarounds));
stream->writeString(mPixelHLSL);
- stream->writeInt(mPixelWorkarounds);
+ stream->writeBytes(reinterpret_cast<unsigned char*>(&mPixelWorkarounds), sizeof(D3DCompilerWorkarounds));
stream->writeInt(mUsesFragDepth);
stream->writeInt(mUsesPointSize);
@@ -810,11 +837,12 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
return gl::Error(GL_NO_ERROR);
}
-gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExecutable)
+gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutableD3D **outExecutable)
{
- std::vector<GLenum> outputs;
+ mPixelShaderOutputFormatCache.clear();
- const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender(mRenderer->getWorkarounds());
+ const FramebufferD3D *fboD3D = GetImplAs<FramebufferD3D>(fbo);
+ const gl::AttachmentList &colorbuffers = fboD3D->getColorAttachmentsForRender(mRenderer->getWorkarounds());
for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
{
@@ -822,18 +850,20 @@ gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fb
if (colorbuffer)
{
- outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
+ mPixelShaderOutputFormatCache.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
}
else
{
- outputs.push_back(GL_NONE);
+ mPixelShaderOutputFormatCache.push_back(GL_NONE);
}
}
- return getPixelExecutableForOutputLayout(outputs, outExecutable);
+ return getPixelExecutableForOutputLayout(mPixelShaderOutputFormatCache, outExecutable, nullptr);
}
-gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature, ShaderExecutable **outExectuable)
+gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature,
+ ShaderExecutableD3D **outExectuable,
+ gl::InfoLog *infoLog)
{
for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
{
@@ -848,9 +878,12 @@ gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vector<GLenum
outputSignature);
// Generate new pixel executable
+ ShaderExecutableD3D *pixelExecutable = NULL;
+
gl::InfoLog tempInfoLog;
- ShaderExecutable *pixelExecutable = NULL;
- gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalPixelHLSL, SHADER_PIXEL,
+ gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
+
+ gl::Error error = mRenderer->compileToExecutable(*currentInfoLog, finalPixelHLSL, SHADER_PIXEL,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
mPixelWorkarounds, &pixelExecutable);
@@ -859,22 +892,24 @@ gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vector<GLenum
return error;
}
- if (!pixelExecutable)
+ if (pixelExecutable)
+ {
+ mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable));
+ }
+ else if (!infoLog)
{
std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]);
}
- else
- {
- mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable));
- }
*outExectuable = pixelExecutable;
return gl::Error(GL_NO_ERROR);
}
-gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable)
+gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
+ ShaderExecutableD3D **outExectuable,
+ gl::InfoLog *infoLog)
{
GLenum signature[gl::MAX_VERTEX_ATTRIBS];
getInputLayoutSignature(inputLayout, signature);
@@ -892,9 +927,12 @@ gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat i
std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, mShaderAttributes);
// Generate new vertex executable
+ ShaderExecutableD3D *vertexExecutable = NULL;
+
gl::InfoLog tempInfoLog;
- ShaderExecutable *vertexExecutable = NULL;
- gl::Error error = mRenderer->compileToExecutable(tempInfoLog, finalVertexHLSL, SHADER_VERTEX,
+ gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
+
+ gl::Error error = mRenderer->compileToExecutable(*currentInfoLog, finalVertexHLSL, SHADER_VERTEX,
mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
mVertexWorkarounds, &vertexExecutable);
@@ -903,42 +941,42 @@ gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat i
return error;
}
- if (!vertexExecutable)
+ if (vertexExecutable)
{
- std::vector<char> tempCharBuffer(tempInfoLog.getLength()+3);
- tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
- ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]);
+ mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable));
}
- else
+ else if (!infoLog)
{
- mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable));
+ std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
+ tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]);
+ ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]);
}
*outExectuable = vertexExecutable;
return gl::Error(GL_NO_ERROR);
}
-gl::LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- int registers)
+LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers)
{
ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
gl::VertexFormat defaultInputLayout[gl::MAX_VERTEX_ATTRIBS];
GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
- ShaderExecutable *defaultVertexExecutable = NULL;
- gl::Error error = getVertexExecutableForInputLayout(defaultInputLayout, &defaultVertexExecutable);
+ ShaderExecutableD3D *defaultVertexExecutable = NULL;
+ gl::Error error = getVertexExecutableForInputLayout(defaultInputLayout, &defaultVertexExecutable, &infoLog);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey());
- ShaderExecutable *defaultPixelExecutable = NULL;
- error = getPixelExecutableForOutputLayout(defaultPixelOutput, &defaultPixelExecutable);
+ ShaderExecutableD3D *defaultPixelExecutable = NULL;
+ error = getPixelExecutableForOutputLayout(defaultPixelOutput, &defaultPixelExecutable, &infoLog);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
if (usesGeometryShader())
@@ -948,10 +986,10 @@ gl::LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::S
error = mRenderer->compileToExecutable(infoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
(mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
- ANGLE_D3D_WORKAROUND_NONE, &mGeometryExecutable);
+ D3DCompilerWorkarounds(), &mGeometryExecutable);
if (error.isError())
{
- return gl::LinkResult(false, error);
+ return LinkResult(false, error);
}
}
@@ -977,15 +1015,15 @@ gl::LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::S
#endif
bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable));
- return gl::LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
+ return LinkResult(linkSuccess, gl::Error(GL_NO_ERROR));
}
-gl::LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
- gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings,
- GLenum transformFeedbackBufferMode,
- int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
- std::map<int, gl::VariableLocation> *outputVariables)
+LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
+ gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables)
{
ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
@@ -996,10 +1034,10 @@ gl::LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
mTransformFeedbackBufferMode = transformFeedbackBufferMode;
mPixelHLSL = fragmentShaderD3D->getTranslatedSource();
- mPixelWorkarounds = fragmentShaderD3D->getD3DWorkarounds();
+ fragmentShaderD3D->generateWorkarounds(&mPixelWorkarounds);
mVertexHLSL = vertexShaderD3D->getTranslatedSource();
- mVertexWorkarounds = vertexShaderD3D->getD3DWorkarounds();
+ vertexShaderD3D->generateWorkarounds(&mVertexWorkarounds);
mShaderVersion = vertexShaderD3D->getShaderVersion();
// Map the varyings to the register file
@@ -1008,24 +1046,26 @@ gl::LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
if (*registers < 0)
{
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
- if (!gl::ProgramBinary::linkVaryings(infoLog, fragmentShader, vertexShader))
+ if (!gl::Program::linkVaryings(infoLog, fragmentShader, vertexShader))
{
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
if (!mDynamicHLSL->generateShaderLinkHLSL(data, infoLog, *registers, packing, mPixelHLSL, mVertexHLSL,
fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings,
linkedVaryings, outputVariables, &mPixelShaderKey, &mUsesFragDepth))
{
- return gl::LinkResult(false, gl::Error(GL_NO_ERROR));
+ return LinkResult(false, gl::Error(GL_NO_ERROR));
}
mUsesPointSize = vertexShaderD3D->usesPointSize();
- return gl::LinkResult(true, gl::Error(GL_NO_ERROR));
+ initAttributesByLayout();
+
+ return LinkResult(true, gl::Error(GL_NO_ERROR));
}
void ProgramD3D::getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const
@@ -1042,7 +1082,7 @@ void ProgramD3D::initializeUniformStorage()
{
const gl::LinkedUniform &uniform = *mUniforms[uniformIndex];
- if (!gl::IsSampler(uniform.type))
+ if (!gl::IsSamplerType(uniform.type))
{
if (uniform.isReferencedByVertexShader())
{
@@ -1077,12 +1117,20 @@ gl::Error ProgramD3D::applyUniforms()
return gl::Error(GL_NO_ERROR);
}
-gl::Error ProgramD3D::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps)
+gl::Error ProgramD3D::applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[])
{
- ASSERT(boundBuffers.size() == mUniformBlocks.size());
+ GLint vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
+ GLint fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS];
- const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
- const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
+ for (unsigned int registerIndex = 0; registerIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; ++registerIndex)
+ {
+ vertexUniformBuffers[registerIndex] = -1;
+ }
+
+ for (unsigned int registerIndex = 0; registerIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS; ++registerIndex)
+ {
+ fragmentUniformBuffers[registerIndex] = -1;
+ }
const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers();
const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers();
@@ -1090,15 +1138,9 @@ gl::Error ProgramD3D::applyUniformBuffers(const std::vector<gl::Buffer*> boundBu
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++)
{
gl::UniformBlock *uniformBlock = mUniformBlocks[uniformBlockIndex];
- gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex];
+ GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];
- ASSERT(uniformBlock && uniformBuffer);
-
- if (uniformBuffer->getSize() < uniformBlock->dataSize)
- {
- // undefined behaviour
- return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small.");
- }
+ ASSERT(uniformBlock);
// Unnecessary to apply an unreferenced standard or shared UBO
if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader())
@@ -1109,21 +1151,21 @@ gl::Error ProgramD3D::applyUniformBuffers(const std::vector<gl::Buffer*> boundBu
if (uniformBlock->isReferencedByVertexShader())
{
unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
- ASSERT(vertexUniformBuffers[registerIndex] == NULL);
- ASSERT(registerIndex < caps.maxVertexUniformBlocks);
- vertexUniformBuffers[registerIndex] = uniformBuffer;
+ ASSERT(vertexUniformBuffers[registerIndex] == -1);
+ ASSERT(registerIndex < data.caps->maxVertexUniformBlocks);
+ vertexUniformBuffers[registerIndex] = blockBinding;
}
if (uniformBlock->isReferencedByFragmentShader())
{
unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
- ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
- ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
- fragmentUniformBuffers[registerIndex] = uniformBuffer;
+ ASSERT(fragmentUniformBuffers[registerIndex] == -1);
+ ASSERT(registerIndex < data.caps->maxFragmentUniformBlocks);
+ fragmentUniformBuffers[registerIndex] = blockBinding;
}
}
- return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
+ return mRenderer->setUniformBuffers(data, vertexUniformBuffers, fragmentUniformBuffers);
}
bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
@@ -1308,7 +1350,7 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
{
const sh::Uniform &vertexUniform = *entry->second;
const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
- if (!gl::ProgramBinary::linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
+ if (!gl::Program::linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
{
return false;
}
@@ -1321,7 +1363,7 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
if (uniform.staticUse)
{
- defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
+ defineUniformBase(vertexShaderD3D, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
}
}
@@ -1331,7 +1373,7 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
if (uniform.staticUse)
{
- defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
+ defineUniformBase(fragmentShaderD3D, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
}
}
@@ -1355,17 +1397,17 @@ bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShad
return true;
}
-void ProgramD3D::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
+void ProgramD3D::defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister)
{
- ShShaderOutput outputType = ShaderD3D::getCompilerOutputType(shader);
+ ShShaderOutput outputType = shader->getCompilerOutputType();
sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
encoder.skipRegisters(uniformRegister);
defineUniform(shader, uniform, uniform.name, &encoder);
}
-void ProgramD3D::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
- const std::string &fullName, sh::HLSLBlockEncoder *encoder)
+void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform,
+ const std::string &fullName, sh::HLSLBlockEncoder *encoder)
{
if (uniform.isStruct())
{
@@ -1396,30 +1438,28 @@ void ProgramD3D::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
gl::LinkedUniform *linkedUniform = getUniformByName(fullName);
+ // Advance the uniform offset, to track registers allocation for structs
+ sh::BlockMemberInfo blockInfo = encoder->encodeType(uniform.type, uniform.arraySize, false);
+
if (!linkedUniform)
{
linkedUniform = new gl::LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
- -1, sh::BlockMemberInfo::getDefaultBlockInfo());
+ -1, sh::BlockMemberInfo::getDefaultBlockInfo());
ASSERT(linkedUniform);
- linkedUniform->registerElement = encoder->getCurrentElement();
+ linkedUniform->registerElement = sh::HLSLBlockEncoder::getBlockRegisterElement(blockInfo);
mUniforms.push_back(linkedUniform);
}
- ASSERT(linkedUniform->registerElement == encoder->getCurrentElement());
-
- if (shader == GL_FRAGMENT_SHADER)
+ if (shader->getShaderType() == GL_FRAGMENT_SHADER)
{
- linkedUniform->psRegisterIndex = encoder->getCurrentRegister();
+ linkedUniform->psRegisterIndex = sh::HLSLBlockEncoder::getBlockRegister(blockInfo);
}
- else if (shader == GL_VERTEX_SHADER)
+ else if (shader->getShaderType() == GL_VERTEX_SHADER)
{
- linkedUniform->vsRegisterIndex = encoder->getCurrentRegister();
+ linkedUniform->vsRegisterIndex = sh::HLSLBlockEncoder::getBlockRegister(blockInfo);
}
else UNREACHABLE();
- // Advance the uniform offset, to track registers allocation for structs
- encoder->encodeType(uniform.type, uniform.arraySize, false);
-
// Arrays are treated as aggregate types
if (uniform.isArray())
{
@@ -1488,7 +1528,7 @@ void ProgramD3D::setUniform(GLint location, GLsizei count, const T* v, GLenum ta
}
}
}
- else if (gl::IsSampler(targetUniform->type))
+ else if (gl::IsSamplerType(targetUniform->type))
{
ASSERT(targetUniformType == GL_INT);
@@ -1824,7 +1864,7 @@ bool ProgramD3D::assignSamplers(unsigned int startSamplerIndex,
bool ProgramD3D::indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps)
{
- ASSERT(gl::IsSampler(uniform.type));
+ ASSERT(gl::IsSamplerType(uniform.type));
ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX);
if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
@@ -1874,7 +1914,7 @@ bool ProgramD3D::indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps)
{
const gl::LinkedUniform &uniform = *mUniforms[uniformIndex];
- if (gl::IsSampler(uniform.type))
+ if (gl::IsSamplerType(uniform.type))
{
if (!indexSamplerUniform(uniform, infoLog, caps))
{
@@ -1902,11 +1942,11 @@ void ProgramD3D::reset()
mTransformFeedbackBufferMode = GL_NONE;
mVertexHLSL.clear();
- mVertexWorkarounds = ANGLE_D3D_WORKAROUND_NONE;
+ mVertexWorkarounds.reset();
mShaderVersion = 100;
mPixelHLSL.clear();
- mPixelWorkarounds = ANGLE_D3D_WORKAROUND_NONE;
+ mPixelWorkarounds.reset();
mUsesFragDepth = false;
mPixelShaderKey.clear();
mUsesPointSize = false;
@@ -1920,6 +1960,46 @@ void ProgramD3D::reset()
mUsedVertexSamplerRange = 0;
mUsedPixelSamplerRange = 0;
mDirtySamplerMapping = true;
+
+ std::fill(mAttributesByLayout, mAttributesByLayout + ArraySize(mAttributesByLayout), -1);
+}
+
+unsigned int ProgramD3D::getSerial() const
+{
+ return mSerial;
+}
+
+unsigned int ProgramD3D::issueSerial()
+{
+ return mCurrentSerial++;
+}
+
+void ProgramD3D::initAttributesByLayout()
+{
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mAttributesByLayout[i] = i;
+ }
+
+ std::sort(&mAttributesByLayout[0], &mAttributesByLayout[gl::MAX_VERTEX_ATTRIBS], AttributeSorter(mSemanticIndex));
+}
+
+void ProgramD3D::sortAttributesByLayout(rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
+ int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]) const
+{
+ rx::TranslatedAttribute oldTranslatedAttributes[gl::MAX_VERTEX_ATTRIBS];
+
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ oldTranslatedAttributes[i] = attributes[i];
+ }
+
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ int oldIndex = mAttributesByLayout[i];
+ sortedSemanticIndices[i] = mSemanticIndex[oldIndex];
+ attributes[i] = oldTranslatedAttributes[oldIndex];
+ }
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.h
index 4baab9aa19..6f3eade81d 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -6,11 +6,14 @@
// ProgramD3D.h: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
-#ifndef LIBGLESV2_RENDERER_PROGRAMD3D_H_
-#define LIBGLESV2_RENDERER_PROGRAMD3D_H_
+#ifndef LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
+#define LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
-#include "libGLESv2/renderer/ProgramImpl.h"
-#include "libGLESv2/renderer/Workarounds.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/renderer/ProgramImpl.h"
+#include "libANGLE/renderer/Workarounds.h"
+#include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include <string>
#include <vector>
@@ -25,7 +28,14 @@ struct VertexFormat;
namespace rx
{
class RendererD3D;
-class UniformStorage;
+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
class ProgramD3D : public ProgramImpl
{
@@ -33,9 +43,6 @@ class ProgramD3D : public ProgramImpl
ProgramD3D(RendererD3D *renderer);
virtual ~ProgramD3D();
- static ProgramD3D *makeProgramD3D(ProgramImpl *impl);
- static const ProgramD3D *makeProgramD3D(const ProgramImpl *impl);
-
const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
int getShaderVersion() const { return mShaderVersion; }
GLenum getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
@@ -49,31 +56,32 @@ class ProgramD3D : public ProgramImpl
bool usesPointSize() const { return mUsesPointSize; }
bool usesPointSpriteEmulation() const;
bool usesGeometryShader() const;
+ bool usesInstancedPointSpriteEmulation() const;
GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
- gl::LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
+ LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
gl::Error save(gl::BinaryOutputStream *stream);
- gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExectuable);
- gl::Error getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout, ShaderExecutable **outExectuable);
- gl::Error getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable);
- ShaderExecutable *getGeometryExecutable() const { return mGeometryExecutable; }
+ gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutableD3D **outExectuable);
+ gl::Error getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout, ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog);
+ gl::Error getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog);
+ ShaderExecutableD3D *getGeometryExecutable() const { return mGeometryExecutable; }
- gl::LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
- int registers);
+ LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ int registers);
- gl::LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
- gl::Shader *fragmentShader, gl::Shader *vertexShader,
- const std::vector<std::string> &transformFeedbackVaryings,
- GLenum transformFeedbackBufferMode,
- int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
- std::map<int, gl::VariableLocation> *outputVariables);
+ LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
+ gl::Shader *fragmentShader, gl::Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode,
+ int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
+ std::map<int, gl::VariableLocation> *outputVariables);
void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
void initializeUniformStorage();
gl::Error applyUniforms();
- gl::Error applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps);
+ gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) override;
bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
unsigned int registerIndex, const gl::Caps &caps);
void dirtyAllUniforms();
@@ -104,8 +112,8 @@ class ProgramD3D : public ProgramImpl
void getUniformiv(GLint location, GLint *params);
void getUniformuiv(GLint location, GLuint *params);
- const UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; }
- const UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
+ const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; }
+ const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
const gl::Caps &caps);
@@ -113,43 +121,47 @@ class ProgramD3D : public ProgramImpl
void reset();
- private:
- DISALLOW_COPY_AND_ASSIGN(ProgramD3D);
+ unsigned int getSerial() const;
+ void initAttributesByLayout();
+ void sortAttributesByLayout(rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
+ int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]) const;
+
+ private:
class VertexExecutable
{
public:
VertexExecutable(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
const GLenum signature[gl::MAX_VERTEX_ATTRIBS],
- ShaderExecutable *shaderExecutable);
+ ShaderExecutableD3D *shaderExecutable);
~VertexExecutable();
bool matchesSignature(const GLenum convertedLayout[gl::MAX_VERTEX_ATTRIBS]) const;
const gl::VertexFormat *inputs() const { return mInputs; }
const GLenum *signature() const { return mSignature; }
- ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
+ ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
private:
gl::VertexFormat mInputs[gl::MAX_VERTEX_ATTRIBS];
GLenum mSignature[gl::MAX_VERTEX_ATTRIBS];
- ShaderExecutable *mShaderExecutable;
+ ShaderExecutableD3D *mShaderExecutable;
};
class PixelExecutable
{
public:
- PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutable *shaderExecutable);
+ 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; }
- ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
+ ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
private:
std::vector<GLenum> mOutputSignature;
- ShaderExecutable *mShaderExecutable;
+ ShaderExecutableD3D *mShaderExecutable;
};
struct Sampler
@@ -161,8 +173,8 @@ class ProgramD3D : public ProgramImpl
GLenum textureType;
};
- void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister);
- void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName,
+ void defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister);
+ void defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform, const std::string &fullName,
sh::HLSLBlockEncoder *encoder);
bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps);
bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
@@ -188,20 +200,20 @@ class ProgramD3D : public ProgramImpl
std::vector<VertexExecutable *> mVertexExecutables;
std::vector<PixelExecutable *> mPixelExecutables;
- ShaderExecutable *mGeometryExecutable;
+ ShaderExecutableD3D *mGeometryExecutable;
std::string mVertexHLSL;
- D3DWorkaroundType mVertexWorkarounds;
+ D3DCompilerWorkarounds mVertexWorkarounds;
std::string mPixelHLSL;
- D3DWorkaroundType mPixelWorkarounds;
+ D3DCompilerWorkarounds mPixelWorkarounds;
bool mUsesFragDepth;
std::vector<PixelShaderOutputVariable> mPixelShaderKey;
bool mUsesPointSize;
- UniformStorage *mVertexUniformStorage;
- UniformStorage *mFragmentUniformStorage;
+ UniformStorageD3D *mVertexUniformStorage;
+ UniformStorageD3D *mFragmentUniformStorage;
GLenum mTransformFeedbackBufferMode;
@@ -211,9 +223,22 @@ class ProgramD3D : public ProgramImpl
GLuint mUsedPixelSamplerRange;
bool mDirtySamplerMapping;
+ // Cache for validateSamplers
+ std::vector<GLenum> mTextureUnitTypesCache;
+
+ // Cache for getPixelExecutableForFramebuffer
+ std::vector<GLenum> mPixelShaderOutputFormatCache;
+
int mShaderVersion;
+
+ int mAttributesByLayout[gl::MAX_VERTEX_ATTRIBS];
+
+ unsigned int mSerial;
+
+ static unsigned int issueSerial();
+ static unsigned int mCurrentSerial;
};
}
-#endif // LIBGLESV2_RENDERER_PROGRAMD3D_H_
+#endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp
new file mode 100644
index 0000000000..84b30aa106
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp
@@ -0,0 +1,36 @@
+//
+// Copyright (c) 2012-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.
+//
+
+// 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;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h
new file mode 100644
index 0000000000..fe6afcecae
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h
@@ -0,0 +1,42 @@
+//
+// Copyright (c) 2012-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.
+//
+
+// 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/angletypes.h"
+
+namespace rx
+{
+
+class RenderTargetD3D : angle::NonCopyable
+{
+ public:
+ RenderTargetD3D();
+ virtual ~RenderTargetD3D();
+
+ 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()); }
+
+ virtual unsigned int getSerial() const;
+ static unsigned int issueSerials(unsigned int count);
+
+ private:
+ const unsigned int mSerial;
+ static unsigned int mCurrentSerial;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_RENDERTARGETD3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
index cb4af367a2..c91fedff06 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
@@ -7,10 +7,10 @@
// RenderbufferD3d.cpp: Implements the RenderbufferD3D class, a specialization of RenderbufferImpl
-#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
-#include "libGLESv2/renderer/RenderTarget.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
namespace rx
{
@@ -30,7 +30,12 @@ RenderbufferD3D *RenderbufferD3D::makeRenderbufferD3D(RenderbufferImpl *renderbu
return static_cast<RenderbufferD3D*>(renderbuffer);
}
-gl::Error RenderbufferD3D::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
+gl::Error RenderbufferD3D::setStorage(GLenum internalformat, size_t width, size_t height)
+{
+ return setStorageMultisample(0, internalformat, width, height);
+}
+
+gl::Error RenderbufferD3D::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height)
{
// If the renderbuffer parameters are queried, the calling function
// will expect one of the valid renderbuffer formats for use in
@@ -42,7 +47,7 @@ gl::Error RenderbufferD3D::setStorage(GLsizei width, GLsizei height, GLenum inte
creationFormat = GL_DEPTH24_STENCIL8_OES;
}
- RenderTarget *newRT = NULL;
+ RenderTargetD3D *newRT = NULL;
gl::Error error = mRenderer->createRenderTarget(width, height, creationFormat, samples, &newRT);
if (error.isError())
{
@@ -55,47 +60,7 @@ gl::Error RenderbufferD3D::setStorage(GLsizei width, GLsizei height, GLenum inte
return gl::Error(GL_NO_ERROR);
}
-gl::Error RenderbufferD3D::setStorage(SwapChain *swapChain, bool depth)
-{
- RenderTarget *newRT = NULL;
- gl::Error error = mRenderer->createRenderTarget(swapChain, depth, &newRT);
- if (error.isError())
- {
- return error;
- }
-
- SafeDelete(mRenderTarget);
- mRenderTarget = newRT;
-
- return gl::Error(GL_NO_ERROR);
-}
-
-GLsizei RenderbufferD3D::getWidth() const
-{
- return (mRenderTarget ? mRenderTarget->getWidth() : 0);
-}
-
-GLsizei RenderbufferD3D::getHeight() const
-{
- return (mRenderTarget ? mRenderTarget->getHeight() : 0);
-}
-
-GLenum RenderbufferD3D::getInternalFormat() const
-{
- return (mRenderTarget ? mRenderTarget->getInternalFormat() : GL_RGBA4);
-}
-
-GLenum RenderbufferD3D::getActualFormat() const
-{
- return (mRenderTarget ? mRenderTarget->getActualFormat() : GL_RGBA4);
-}
-
-GLsizei RenderbufferD3D::getSamples() const
-{
- return (mRenderTarget ? mRenderTarget->getSamples() : 0);
-}
-
-RenderTarget *RenderbufferD3D::getRenderTarget()
+RenderTargetD3D *RenderbufferD3D::getRenderTarget()
{
return mRenderTarget;
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h
new file mode 100644
index 0000000000..4c4b998683
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h
@@ -0,0 +1,43 @@
+//
+// Copyright (c) 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 RendererD3D;
+class RenderTargetD3D;
+class SwapChainD3D;
+
+class RenderbufferD3D : public RenderbufferImpl
+{
+ public:
+ RenderbufferD3D(RendererD3D *renderer);
+ virtual ~RenderbufferD3D();
+
+ static RenderbufferD3D *makeRenderbufferD3D(RenderbufferImpl *renderbuffer);
+
+ virtual gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override;
+ virtual gl::Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) override;
+
+ RenderTargetD3D *getRenderTarget();
+ unsigned int getRenderTargetSerial() const;
+
+ private:
+ RendererD3D *mRenderer;
+ RenderTargetD3D *mRenderTarget;
+};
+}
+
+#endif // LIBANGLE_RENDERER_D3D_RENDERBUFFERD3D_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp
new file mode 100644
index 0000000000..2ce0ce5a1b
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp
@@ -0,0 +1,628 @@
+//
+// Copyright (c) 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/utilities.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/ResourceManager.h"
+#include "libANGLE/State.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/DisplayD3D.h"
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+
+namespace rx
+{
+
+namespace
+{
+// 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.
+const int ScratchMemoryBufferLifetime = 1000;
+}
+
+RendererD3D::RendererD3D(egl::Display *display)
+ : mDisplay(display),
+ mDeviceLost(false),
+ mScratchMemoryBufferResetCounter(0)
+{
+}
+
+RendererD3D::~RendererD3D()
+{
+ cleanup();
+}
+
+void RendererD3D::cleanup()
+{
+ mScratchMemoryBuffer.resize(0);
+ for (auto it = mIncompleteTextures.begin(); it != mIncompleteTextures.end(); ++it)
+ {
+ it->second.set(NULL);
+ }
+ mIncompleteTextures.clear();
+}
+
+// static
+RendererD3D *RendererD3D::makeRendererD3D(Renderer *renderer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(RendererD3D*, renderer));
+ return static_cast<RendererD3D*>(renderer);
+}
+
+gl::Error RendererD3D::drawElements(const gl::Data &data,
+ GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLsizei instances,
+ const RangeUI &indexRange)
+{
+ if (data.state->isPrimitiveRestartEnabled())
+ {
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION, "Primitive restart not implemented");
+ }
+
+ gl::Program *program = data.state->getProgram();
+ ASSERT(program != NULL);
+
+ program->updateSamplerMapping();
+
+ gl::Error error = generateSwizzles(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!applyPrimitiveType(mode, count, program->usesPointSize()))
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ error = applyRenderTarget(data, mode, false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyState(data, mode);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ gl::VertexArray *vao = data.state->getVertexArray();
+ TranslatedIndexData indexInfo;
+ indexInfo.indexRange = indexRange;
+ error = applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ applyTransformFeedbackBuffers(*data.state);
+ // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
+ // layer.
+ ASSERT(!data.state->isTransformFeedbackActiveUnpaused());
+
+ GLsizei vertexCount = indexInfo.indexRange.length() + 1;
+ error = applyVertexBuffer(*data.state, mode, indexInfo.indexRange.start, vertexCount, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyShaders(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = program->applyUniformBuffers(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!skipDraw(data, mode))
+ {
+ error = drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::drawArrays(const gl::Data &data,
+ GLenum mode, GLint first,
+ GLsizei count, GLsizei instances)
+{
+ gl::Program *program = data.state->getProgram();
+ ASSERT(program != NULL);
+
+ program->updateSamplerMapping();
+
+ gl::Error error = generateSwizzles(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!applyPrimitiveType(mode, count, program->usesPointSize()))
+ {
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ error = applyRenderTarget(data, mode, false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyState(data, mode);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ applyTransformFeedbackBuffers(*data.state);
+
+ error = applyVertexBuffer(*data.state, mode, first, count, instances);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyShaders(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = program->applyUniformBuffers(data);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!skipDraw(data, mode))
+ {
+ error = drawArrays(data, mode, count, instances, program->usesPointSize());
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (data.state->isTransformFeedbackActiveUnpaused())
+ {
+ markTransformFeedbackUsage(data);
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::generateSwizzles(const gl::Data &data, gl::SamplerType type)
+{
+ gl::Program *program = data.state->getProgram();
+
+ size_t samplerRange = program->getUsedSamplerRange(type);
+
+ for (size_t i = 0; i < samplerRange; i++)
+ {
+ GLenum textureType = program->getSamplerTextureType(type, i);
+ GLint textureUnit = program->getSamplerMapping(type, i, *data.caps);
+ if (textureUnit != -1)
+ {
+ gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
+ ASSERT(texture);
+ if (texture->getSamplerState().swizzleRequired())
+ {
+ gl::Error error = generateSwizzle(texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::generateSwizzles(const gl::Data &data)
+{
+ gl::Error error = generateSwizzles(data, gl::SAMPLER_VERTEX);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = generateSwizzles(data, gl::SAMPLER_PIXEL);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+// Applies the render target surface, depth stencil surface, viewport rectangle and
+// scissor rectangle to the renderer
+gl::Error RendererD3D::applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport)
+{
+ const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
+ ASSERT(framebufferObject && framebufferObject->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE);
+
+ gl::Error error = applyRenderTarget(framebufferObject);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ float nearZ, farZ;
+ data.state->getDepthRange(&nearZ, &farZ);
+ setViewport(data.state->getViewport(), nearZ, farZ, drawMode,
+ data.state->getRasterizerState().frontFace, ignoreViewport);
+
+ setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled());
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D device
+gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode)
+{
+ const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
+ int samples = framebufferObject->getSamples(data);
+
+ gl::RasterizerState rasterizer = data.state->getRasterizerState();
+ rasterizer.pointDrawMode = (drawMode == GL_POINTS);
+ rasterizer.multiSample = (samples != 0);
+
+ gl::Error error = setRasterizerState(rasterizer);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ unsigned int mask = 0;
+ if (data.state->isSampleCoverageEnabled())
+ {
+ GLclampf coverageValue;
+ bool coverageInvert = false;
+ data.state->getSampleCoverageParams(&coverageValue, &coverageInvert);
+ 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;
+ }
+ }
+ }
+
+ if (coverageInvert)
+ {
+ mask = ~mask;
+ }
+ }
+ else
+ {
+ mask = 0xFFFFFFFF;
+ }
+ error = setBlendState(framebufferObject, data.state->getBlendState(), data.state->getBlendColor(), mask);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setDepthStencilState(data.state->getDepthStencilState(), data.state->getStencilRef(),
+ data.state->getStencilBackRef(), rasterizer.frontFace == GL_CCW);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+// Applies the shaders and shader constants to the Direct3D device
+gl::Error RendererD3D::applyShaders(const gl::Data &data)
+{
+ gl::Program *program = data.state->getProgram();
+
+ gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
+ gl::VertexFormat::GetInputLayout(inputLayout, program, *data.state);
+
+ const gl::Framebuffer *fbo = data.state->getDrawFramebuffer();
+
+ gl::Error error = applyShaders(program, inputLayout, fbo, data.state->getRasterizerState().rasterizerDiscard, data.state->isTransformFeedbackActiveUnpaused());
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return program->applyUniforms();
+}
+
+// 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).
+gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType,
+ const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
+{
+ gl::Program *program = data.state->getProgram();
+
+ size_t samplerRange = program->getUsedSamplerRange(shaderType);
+ for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
+ {
+ GLenum textureType = program->getSamplerTextureType(shaderType, samplerIndex);
+ GLint textureUnit = program->getSamplerMapping(shaderType, samplerIndex, *data.caps);
+ if (textureUnit != -1)
+ {
+ gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
+ ASSERT(texture);
+ gl::SamplerState sampler = texture->getSamplerState();
+
+ gl::Sampler *samplerObject = data.state->getSampler(textureUnit);
+ if (samplerObject)
+ {
+ samplerObject->getState(&sampler);
+ }
+
+ // TODO: std::binary_search may become unavailable using older versions of GCC
+ if (texture->isSamplerComplete(sampler, data) &&
+ !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
+ {
+ gl::Error error = setSamplerState(shaderType, samplerIndex, texture, sampler);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = setTexture(shaderType, samplerIndex, texture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ else
+ {
+ // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture.
+ gl::Texture *incompleteTexture = getIncompleteTexture(textureType);
+ gl::Error error = setTexture(shaderType, samplerIndex, incompleteTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ else
+ {
+ // No texture bound to this slot even though it is used by the shader, bind a NULL texture
+ gl::Error error = setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+
+ // Set all the remaining textures to NULL
+ size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits
+ : data.caps->maxVertexTextureImageUnits;
+ for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
+ {
+ gl::Error error = setTexture(shaderType, samplerIndex, NULL);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error RendererD3D::applyTextures(const gl::Data &data)
+{
+ FramebufferTextureSerialArray framebufferSerials;
+ size_t framebufferSerialCount = getBoundFramebufferTextureSerials(data, &framebufferSerials);
+
+ gl::Error error = applyTextures(data, gl::SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = applyTextures(data, gl::SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode)
+{
+ if (drawMode == GL_POINTS)
+ {
+ // 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 (!data.state->getProgram()->usesPointSize() && !data.state->isTransformFeedbackActiveUnpaused())
+ {
+ // This is stictly speaking not an error, but developers should be
+ // notified of risking undefined behavior.
+ ERR("Point rendering without writing to gl_PointSize.");
+
+ return true;
+ }
+ }
+ else if (gl::IsTriangleMode(drawMode))
+ {
+ if (data.state->getRasterizerState().cullFace && data.state->getRasterizerState().cullMode == GL_FRONT_AND_BACK)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void RendererD3D::markTransformFeedbackUsage(const gl::Data &data)
+{
+ for (size_t i = 0; i < data.caps->maxTransformFeedbackSeparateAttributes; i++)
+ {
+ gl::Buffer *buffer = data.state->getIndexedTransformFeedbackBuffer(i);
+ if (buffer)
+ {
+ BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
+ bufferD3D->markTransformFeedbackUsage();
+ }
+ }
+}
+
+size_t RendererD3D::getBoundFramebufferTextureSerials(const gl::Data &data,
+ FramebufferTextureSerialArray *outSerialArray)
+{
+ size_t serialCount = 0;
+
+ const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer();
+ for (unsigned int i = 0; i < data.caps->maxColorAttachments; i++)
+ {
+ gl::FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
+ if (attachment && attachment->type() == GL_TEXTURE)
+ {
+ gl::Texture *texture = attachment->getTexture();
+ (*outSerialArray)[serialCount++] = texture->getTextureSerial();
+ }
+ }
+
+ gl::FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
+ if (depthStencilAttachment && depthStencilAttachment->type() == GL_TEXTURE)
+ {
+ gl::Texture *depthStencilTexture = depthStencilAttachment->getTexture();
+ (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
+ }
+
+ std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
+
+ return serialCount;
+}
+
+gl::Texture *RendererD3D::getIncompleteTexture(GLenum type)
+{
+ if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
+ {
+ const GLubyte color[] = { 0, 0, 0, 255 };
+ const gl::Extents colorSize(1, 1, 1);
+ const gl::PixelUnpackState incompleteUnpackState(1, 0);
+
+ gl::Texture* t = new gl::Texture(createTexture(type), gl::Texture::INCOMPLETE_TEXTURE_ID, type);
+
+ if (type == GL_TEXTURE_CUBE_MAP)
+ {
+ for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++)
+ {
+ t->setImage(face, 0, GL_RGBA, colorSize, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ }
+ }
+ else
+ {
+ t->setImage(type, 0, GL_RGBA, colorSize, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ }
+
+ mIncompleteTextures[type].set(t);
+ }
+
+ return mIncompleteTextures[type].get();
+}
+
+bool RendererD3D::isDeviceLost() const
+{
+ return mDeviceLost;
+}
+
+void RendererD3D::notifyDeviceLost()
+{
+ mDeviceLost = true;
+ mDisplay->notifyDeviceLost();
+}
+
+std::string RendererD3D::getVendorString() const
+{
+ LUID adapterLuid = { 0 };
+
+ if (getLUID(&adapterLuid))
+ {
+ char adapterLuidString[64];
+ sprintf_s(adapterLuidString, sizeof(adapterLuidString), "(adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
+ return std::string(adapterLuidString);
+ }
+
+ return std::string("");
+}
+
+gl::Error RendererD3D::getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer **bufferOut)
+{
+ if (mScratchMemoryBuffer.size() == requestedSize)
+ {
+ mScratchMemoryBufferResetCounter = ScratchMemoryBufferLifetime;
+ *bufferOut = &mScratchMemoryBuffer;
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ if (mScratchMemoryBuffer.size() > requestedSize)
+ {
+ mScratchMemoryBufferResetCounter--;
+ }
+
+ if (mScratchMemoryBufferResetCounter <= 0 || mScratchMemoryBuffer.size() < requestedSize)
+ {
+ mScratchMemoryBuffer.resize(0);
+ if (!mScratchMemoryBuffer.resize(requestedSize))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer.");
+ }
+ mScratchMemoryBufferResetCounter = ScratchMemoryBufferLifetime;
+ }
+
+ ASSERT(mScratchMemoryBuffer.size() >= requestedSize);
+
+ *bufferOut = &mScratchMemoryBuffer;
+ return gl::Error(GL_NO_ERROR);
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.h
index a2f778763c..3de6c20886 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.h
@@ -6,15 +6,23 @@
// RendererD3D.h: Defines a back-end specific class for the DirectX renderer.
-#ifndef LIBGLESV2_RENDERER_RENDERERD3D_H_
-#define LIBGLESV2_RENDERER_RENDERERD3D_H_
+#ifndef LIBANGLE_RENDERER_D3D_RENDERERD3D_H_
+#define LIBANGLE_RENDERER_D3D_RENDERERD3D_H_
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/Data.h"
+#include "common/MemoryBuffer.h"
+#include "libANGLE/Data.h"
+#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/renderer/d3d/formatutilsD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h"
//FIXME(jmadill): std::array is currently prohibited by Chromium style guide
#include <array>
+namespace egl
+{
+class ConfigSet;
+}
+
namespace gl
{
class InfoLog;
@@ -24,24 +32,55 @@ class Texture;
namespace rx
{
-class TextureStorage;
-class VertexBuffer;
+class ImageD3D;
class IndexBuffer;
-class ShaderExecutable;
-class SwapChain;
-class RenderTarget;
-class Image;
+class RenderTargetD3D;
+class ShaderExecutableD3D;
+class SwapChainD3D;
class TextureStorage;
-class UniformStorage;
+class UniformStorageD3D;
+class VertexBuffer;
+
+enum ShaderType
+{
+ SHADER_VERTEX,
+ SHADER_PIXEL,
+ SHADER_GEOMETRY
+};
+
+enum RendererClass
+{
+ RENDERER_D3D11,
+ RENDERER_D3D9,
+};
+
+// Useful for unit testing
+class BufferFactoryD3D
+{
+ public:
+ BufferFactoryD3D() {}
+ virtual ~BufferFactoryD3D() {}
+
+ virtual VertexBuffer *createVertexBuffer() = 0;
+ virtual IndexBuffer *createIndexBuffer() = 0;
+
+ // TODO(jmadill): add VertexFormatCaps
+ virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const = 0;
+ virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0;
+};
-class RendererD3D : public Renderer
+class RendererD3D : public Renderer, public BufferFactoryD3D
{
public:
explicit RendererD3D(egl::Display *display);
virtual ~RendererD3D();
+ virtual egl::Error initialize() = 0;
+
static RendererD3D *makeRendererD3D(Renderer *renderer);
+ virtual egl::ConfigSet generateConfigs() const = 0;
+
gl::Error drawArrays(const gl::Data &data,
GLenum mode, GLint first,
GLsizei count, GLsizei instances) override;
@@ -51,28 +90,24 @@ class RendererD3D : public Renderer
const GLvoid *indices, GLsizei instances,
const RangeUI &indexRange) override;
- gl::Error clear(const gl::Data &data, GLbitfield mask) override;
- gl::Error clearBufferfv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLfloat *values) override;
- gl::Error clearBufferuiv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLuint *values) override;
- gl::Error clearBufferiv(const gl::Data &data, GLenum buffer, int drawbuffer, const GLint *values) override;
- gl::Error clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override;
-
- gl::Error readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLsizei *bufSize, void* pixels) override;
+ bool isDeviceLost() const override;
+ std::string getVendorString() const override;
- gl::Error blitFramebuffer(const gl::Data &data,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter) override;
+ virtual int getMinorShaderModel() const = 0;
+ virtual std::string getShaderModelSuffix() const = 0;
// Direct3D Specific methods
- virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
+ virtual GUID getAdapterIdentifier() const = 0;
+
+ virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
virtual gl::Error generateSwizzle(gl::Texture *texture) = 0;
virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0;
virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
- virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) = 0;
+ virtual gl::Error setUniformBuffers(const gl::Data &data,
+ const GLint vertexUniformBuffers[],
+ const GLint fragmentUniformBuffers[]) = 0;
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState) = 0;
virtual gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
@@ -85,11 +120,11 @@ class RendererD3D : public Renderer
bool ignoreViewport) = 0;
virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0;
- virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+ virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive) = 0;
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray) = 0;
- virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
- virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances) = 0;
+ virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize) = 0;
+ virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances) = 0;
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0;
@@ -102,71 +137,66 @@ class RendererD3D : public Renderer
virtual bool getShareHandleSupport() const = 0;
virtual bool getPostSubBufferSupport() const = 0;
+ virtual int getMajorShaderModel() const = 0;
+
// Pixel operations
- virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) = 0;
- virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) = 0;
- virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0;
- virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) = 0;
-
- virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
- GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) = 0;
+ virtual gl::Error copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level) = 0;
+ virtual gl::Error copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level) = 0;
+ virtual gl::Error copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level) = 0;
+ virtual gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level) = 0;
// RenderTarget creation
- virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT) = 0;
- virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT) = 0;
+ virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) = 0;
// Shader operations
- virtual void releaseShaderCompiler() = 0;
virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, ShaderExecutable **outExecutable) = 0;
+ bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) = 0;
virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround,
- ShaderExecutable **outExectuable) = 0;
- virtual UniformStorage *createUniformStorage(size_t storageSize) = 0;
+ bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds,
+ ShaderExecutableD3D **outExectuable) = 0;
+ virtual UniformStorageD3D *createUniformStorage(size_t storageSize) = 0;
// Image operations
- virtual Image *createImage() = 0;
- virtual gl::Error generateMipmap(Image *dest, Image *source) = 0;
- virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain) = 0;
- virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) = 0;
- virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) = 0;
+ virtual ImageD3D *createImage() = 0;
+ virtual gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) = 0;
+ virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) = 0;
+ virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) = 0;
+ virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) = 0;
virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0;
// Buffer-to-texture and Texture-to-buffer copies
virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0;
- virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0;
- virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const = 0;
- virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0;
+ // Device lost
+ void notifyDeviceLost() override;
+ virtual bool resetDevice() = 0;
- virtual VertexBuffer *createVertexBuffer() = 0;
- virtual IndexBuffer *createIndexBuffer() = 0;
+ virtual RendererClass getRendererClass() const = 0;
+
+ gl::Error getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer **bufferOut);
protected:
- virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) = 0;
+ virtual gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) = 0;
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
- virtual gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) = 0;
- virtual gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
- const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget,
- bool blitDepth, bool blitStencil, GLenum filter) = 0;
+
+ virtual bool getLUID(LUID *adapterLuid) const = 0;
void cleanup();
egl::Display *mDisplay;
+ bool mDeviceLost;
private:
- DISALLOW_COPY_AND_ASSIGN(RendererD3D);
-
//FIXME(jmadill): std::array is currently prohibited by Chromium style guide
typedef std::array<unsigned int, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray;
@@ -175,12 +205,10 @@ class RendererD3D : public Renderer
gl::Error applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport);
gl::Error applyState(const gl::Data &data, GLenum drawMode);
- bool applyTransformFeedbackBuffers(const gl::Data &data);
- gl::Error applyShaders(const gl::Data &data, bool transformFeedbackActive);
+ gl::Error applyShaders(const gl::Data &data);
gl::Error applyTextures(const gl::Data &data, gl::SamplerType shaderType,
const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount);
gl::Error applyTextures(const gl::Data &data);
- gl::Error applyUniformBuffers(const gl::Data &data);
bool skipDraw(const gl::Data &data, GLenum drawMode);
void markTransformFeedbackUsage(const gl::Data &data);
@@ -190,8 +218,24 @@ class RendererD3D : public Renderer
gl::Texture *getIncompleteTexture(GLenum type);
gl::TextureMap mIncompleteTextures;
+ MemoryBuffer mScratchMemoryBuffer;
+ unsigned int mScratchMemoryBufferResetCounter;
+};
+
+struct dx_VertexConstants
+{
+ float depthRange[4];
+ float viewAdjust[4];
+ float viewCoords[4];
+};
+
+struct dx_PixelConstants
+{
+ float depthRange[4];
+ float viewCoords[4];
+ float depthFront[4];
};
}
-#endif // LIBGLESV2_RENDERER_RENDERERD3D_H_
+#endif // LIBANGLE_RENDERER_D3D_RENDERERD3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp
index 8a97579e16..7d522a95d4 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp
@@ -6,12 +6,13 @@
// ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl.
-#include "libGLESv2/Shader.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
-#include "libGLESv2/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/Compiler.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/CompilerD3D.h"
+#include "libANGLE/features.h"
-#include "common/features.h"
#include "common/utilities.h"
// Definitions local to the translation unit
@@ -57,9 +58,6 @@ void FilterInactiveVariables(std::vector<VarT> *variableList)
}
}
-void *ShaderD3D::mFragmentCompiler = NULL;
-void *ShaderD3D::mVertexCompiler = NULL;
-
template <typename VarT>
const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableList)
{
@@ -67,13 +65,11 @@ const std::vector<VarT> *GetShaderVariables(const std::vector<VarT> *variableLis
return variableList;
}
-ShaderD3D::ShaderD3D(const gl::Data &data, GLenum type, RendererD3D *renderer)
- : mType(type),
- mRenderer(renderer),
+ShaderD3D::ShaderD3D(GLenum type)
+ : mShaderType(type),
mShaderVersion(100)
{
uncompile();
- initializeCompiler(data);
}
ShaderD3D::~ShaderD3D()
@@ -94,67 +90,13 @@ const ShaderD3D *ShaderD3D::makeShaderD3D(const ShaderImpl *impl)
std::string ShaderD3D::getDebugInfo() const
{
- return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mType) + " SHADER END\n";
+ return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mShaderType) + " SHADER END\n";
}
-// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
-void ShaderD3D::initializeCompiler(const gl::Data &data)
-{
- if (!mFragmentCompiler)
- {
- bool result = ShInitialize();
- if (result)
- {
- ShShaderSpec specVersion = (data.clientVersion >= 3) ? SH_GLES3_SPEC : SH_GLES2_SPEC;
- ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
-
- ShBuiltInResources resources;
- ShInitBuiltInResources(&resources);
-
- const gl::Caps &caps = *data.caps;
- const gl::Extensions &extensions = *data.extensions;
-
- resources.MaxVertexAttribs = caps.maxVertexAttributes;
- resources.MaxVertexUniformVectors = caps.maxVertexUniformVectors;
- resources.MaxVaryingVectors = caps.maxVaryingVectors;
- resources.MaxVertexTextureImageUnits = caps.maxVertexTextureImageUnits;
- resources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
- resources.MaxTextureImageUnits = caps.maxTextureImageUnits;
- resources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors;
- resources.MaxDrawBuffers = caps.maxDrawBuffers;
- resources.OES_standard_derivatives = extensions.standardDerivatives;
- resources.EXT_draw_buffers = extensions.drawBuffers;
- resources.EXT_shader_texture_lod = 1;
- // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
- resources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
- resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
- // GLSL ES 3.0 constants
- resources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4;
- resources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
- resources.MinProgramTexelOffset = caps.minProgramTexelOffset;
- resources.MaxProgramTexelOffset = caps.maxProgramTexelOffset;
-
- mFragmentCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, specVersion, hlslVersion, &resources);
- mVertexCompiler = ShConstructCompiler(GL_VERTEX_SHADER, specVersion, hlslVersion, &resources);
- }
- }
-}
-
-void ShaderD3D::releaseCompiler()
+void ShaderD3D::parseVaryings(ShHandle compiler)
{
- ShDestruct(mFragmentCompiler);
- ShDestruct(mVertexCompiler);
-
- mFragmentCompiler = NULL;
- mVertexCompiler = NULL;
-
- ShFinalize();
-}
-
-void ShaderD3D::parseVaryings(void *compiler)
-{
- if (!mHlsl.empty())
+ if (!mTranslatedSource.empty())
{
const std::vector<sh::Varying> *varyings = ShGetVaryings(compiler);
ASSERT(varyings);
@@ -164,17 +106,19 @@ void ShaderD3D::parseVaryings(void *compiler)
mVaryings.push_back(gl::PackedVarying((*varyings)[varyingIndex]));
}
- mUsesMultipleRenderTargets = mHlsl.find("GL_USES_MRT") != std::string::npos;
- mUsesFragColor = mHlsl.find("GL_USES_FRAG_COLOR") != std::string::npos;
- mUsesFragData = mHlsl.find("GL_USES_FRAG_DATA") != std::string::npos;
- mUsesFragCoord = mHlsl.find("GL_USES_FRAG_COORD") != std::string::npos;
- mUsesFrontFacing = mHlsl.find("GL_USES_FRONT_FACING") != std::string::npos;
- mUsesPointSize = mHlsl.find("GL_USES_POINT_SIZE") != std::string::npos;
- mUsesPointCoord = mHlsl.find("GL_USES_POINT_COORD") != std::string::npos;
- mUsesDepthRange = mHlsl.find("GL_USES_DEPTH_RANGE") != std::string::npos;
- mUsesFragDepth = mHlsl.find("GL_USES_FRAG_DEPTH") != std::string::npos;
- mUsesDiscardRewriting = mHlsl.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos;
- mUsesNestedBreak = mHlsl.find("ANGLE_USES_NESTED_BREAK") != std::string::npos;
+ mUsesMultipleRenderTargets = mTranslatedSource.find("GL_USES_MRT") != std::string::npos;
+ mUsesFragColor = mTranslatedSource.find("GL_USES_FRAG_COLOR") != std::string::npos;
+ mUsesFragData = mTranslatedSource.find("GL_USES_FRAG_DATA") != std::string::npos;
+ mUsesFragCoord = mTranslatedSource.find("GL_USES_FRAG_COORD") != std::string::npos;
+ mUsesFrontFacing = mTranslatedSource.find("GL_USES_FRONT_FACING") != std::string::npos;
+ mUsesPointSize = mTranslatedSource.find("GL_USES_POINT_SIZE") != std::string::npos;
+ mUsesPointCoord = mTranslatedSource.find("GL_USES_POINT_COORD") != std::string::npos;
+ mUsesDepthRange = mTranslatedSource.find("GL_USES_DEPTH_RANGE") != std::string::npos;
+ mUsesFragDepth = mTranslatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos;
+ mUsesDiscardRewriting = mTranslatedSource.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos;
+ mUsesNestedBreak = mTranslatedSource.find("ANGLE_USES_NESTED_BREAK") != std::string::npos;
+ mUsesDeferredInit = mTranslatedSource.find("ANGLE_USES_DEFERRED_INIT") != std::string::npos;
+ mRequiresIEEEStrictCompiling = mTranslatedSource.find("ANGLE_REQUIRES_IEEE_STRICT_COMPILING") != std::string::npos;
}
}
@@ -190,7 +134,8 @@ void ShaderD3D::resetVaryingsRegisterAssignment()
void ShaderD3D::uncompile()
{
// set by compileToHLSL
- mHlsl.clear();
+ mCompilerOutputType = SH_ESSL_OUTPUT;
+ mTranslatedSource.clear();
mInfoLog.clear();
mUsesMultipleRenderTargets = false;
@@ -205,6 +150,8 @@ void ShaderD3D::uncompile()
mShaderVersion = 100;
mUsesDiscardRewriting = false;
mUsesNestedBreak = false;
+ mUsesDeferredInit = false;
+ mRequiresIEEEStrictCompiling = false;
mVaryings.clear();
mUniforms.clear();
@@ -214,16 +161,13 @@ void ShaderD3D::uncompile()
mDebugInfo.clear();
}
-void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::string &source)
+void ShaderD3D::compileToHLSL(ShHandle compiler, const std::string &source)
{
- // ensure the compiler is loaded
- initializeCompiler(data);
-
int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES);
std::string sourcePath;
#if !defined (ANGLE_ENABLE_WINDOWS_STORE)
- if (gl::perfActive())
+ if (gl::DebugAnnotationsActive())
{
sourcePath = getTempPath();
writeFile(sourcePath.c_str(), source.c_str(), source.length());
@@ -254,14 +198,9 @@ void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::s
mShaderVersion = ShGetShaderVersion(compiler);
- if (mShaderVersion == 300 && data.clientVersion < 3)
- {
- mInfoLog = "GLSL ES 3.00 is not supported by OpenGL ES 2.0 contexts";
- TRACE("\n%s", mInfoLog.c_str());
- }
- else if (result)
+ if (result)
{
- mHlsl = ShGetObjectCode(compiler);
+ mTranslatedSource = ShGetObjectCode(compiler);
#ifdef _DEBUG
// Prefix hlsl shader with commented out glsl shader
@@ -281,8 +220,8 @@ void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::s
curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1);
}
hlslStream << "\n\n";
- hlslStream << mHlsl;
- mHlsl = hlslStream.str();
+ hlslStream << mTranslatedSource;
+ mTranslatedSource = hlslStream.str();
#endif
mUniforms = *GetShaderVariables(ShGetUniforms(compiler));
@@ -293,10 +232,10 @@ void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::s
if (uniform.staticUse)
{
- unsigned int index = -1;
- bool result = ShGetUniformRegister(compiler, uniform.name, &index);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(result);
+ unsigned int index = static_cast<unsigned int>(-1);
+ bool getUniformRegisterResult = ShGetUniformRegister(compiler, uniform.name, &index);
+ UNUSED_ASSERTION_VARIABLE(getUniformRegisterResult);
+ ASSERT(getUniformRegisterResult);
mUniformRegisterMap[uniform.name] = index;
}
@@ -310,10 +249,10 @@ void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::s
if (interfaceBlock.staticUse)
{
- unsigned int index = -1;
- bool result = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index);
- UNUSED_ASSERTION_VARIABLE(result);
- ASSERT(result);
+ unsigned int index = static_cast<unsigned int>(-1);
+ bool blockRegisterResult = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index);
+ UNUSED_ASSERTION_VARIABLE(blockRegisterResult);
+ ASSERT(blockRegisterResult);
mInterfaceBlockRegisterMap[interfaceBlock.name] = index;
}
@@ -327,24 +266,27 @@ void ShaderD3D::compileToHLSL(const gl::Data &data, void *compiler, const std::s
}
}
-D3DWorkaroundType ShaderD3D::getD3DWorkarounds() const
+void ShaderD3D::generateWorkarounds(D3DCompilerWorkarounds *workarounds) const
{
if (mUsesDiscardRewriting)
{
// ANGLE issue 486:
// Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization
- return ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION;
+ workarounds->skipOptimization = true;
}
-
- if (mUsesNestedBreak)
+ 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
- return ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION;
+ workarounds->useMaxOptimization = true;
}
- return ANGLE_D3D_WORKAROUND_NONE;
+ if (mRequiresIEEEStrictCompiling)
+ {
+ // IEEE Strictness for D3D compiler needs to be enabled for NaNs to work.
+ workarounds->enableIEEEStrictness = true;
+ }
}
// true if varying x has a higher priority in packing than y
@@ -381,62 +323,48 @@ unsigned int ShaderD3D::getInterfaceBlockRegister(const std::string &blockName)
return mInterfaceBlockRegisterMap.find(blockName)->second;
}
-void *ShaderD3D::getCompiler()
+GLenum ShaderD3D::getShaderType() const
{
- if (mType == GL_VERTEX_SHADER)
- {
- return mVertexCompiler;
- }
- else
- {
- ASSERT(mType == GL_FRAGMENT_SHADER);
- return mFragmentCompiler;
- }
+ return mShaderType;
}
-ShShaderOutput ShaderD3D::getCompilerOutputType(GLenum shader)
+ShShaderOutput ShaderD3D::getCompilerOutputType() const
{
- void *compiler = NULL;
-
- switch (shader)
- {
- case GL_VERTEX_SHADER: compiler = mVertexCompiler; break;
- case GL_FRAGMENT_SHADER: compiler = mFragmentCompiler; break;
- default: UNREACHABLE(); return SH_HLSL9_OUTPUT;
- }
-
- return ShGetShaderOutputType(compiler);
+ return mCompilerOutputType;
}
-bool ShaderD3D::compile(const gl::Data &data, const std::string &source)
+bool ShaderD3D::compile(gl::Compiler *compiler, const std::string &source)
{
uncompile();
- void *compiler = getCompiler();
+ CompilerD3D *compilerD3D = CompilerD3D::makeCompilerD3D(compiler->getImplementation());
+ ShHandle compilerHandle = compilerD3D->getCompilerHandle(mShaderType);
+
+ mCompilerOutputType = ShGetShaderOutputType(compilerHandle);
- compileToHLSL(data, compiler, source);
+ compileToHLSL(compilerHandle, source);
- if (mType == GL_VERTEX_SHADER)
+ if (mShaderType == GL_VERTEX_SHADER)
{
- parseAttributes(compiler);
+ parseAttributes(compilerHandle);
}
- parseVaryings(compiler);
+ parseVaryings(compilerHandle);
- if (mType == GL_FRAGMENT_SHADER)
+ if (mShaderType == GL_FRAGMENT_SHADER)
{
std::sort(mVaryings.begin(), mVaryings.end(), compareVarying);
const std::string &hlsl = getTranslatedSource();
if (!hlsl.empty())
{
- mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(compiler));
+ mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(compilerHandle));
FilterInactiveVariables(&mActiveOutputVariables);
}
}
#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED
- mDebugInfo += std::string("// ") + GetShaderTypeString(mType) + " SHADER BEGIN\n";
+ mDebugInfo += std::string("// ") + GetShaderTypeString(mShaderType) + " SHADER BEGIN\n";
mDebugInfo += "\n// GLSL BEGIN\n\n" + source + "\n\n// GLSL END\n\n\n";
mDebugInfo += "// INITIAL HLSL BEGIN\n\n" + getTranslatedSource() + "\n// INITIAL HLSL END\n\n\n";
// Successive steps will append more info
@@ -447,7 +375,7 @@ bool ShaderD3D::compile(const gl::Data &data, const std::string &source)
return !getTranslatedSource().empty();
}
-void ShaderD3D::parseAttributes(void *compiler)
+void ShaderD3D::parseAttributes(ShHandle compiler)
{
const std::string &hlsl = getTranslatedSource();
if (!hlsl.empty())
@@ -457,25 +385,4 @@ void ShaderD3D::parseAttributes(void *compiler)
}
}
-int ShaderD3D::getSemanticIndex(const std::string &attributeName) const
-{
- if (!attributeName.empty())
- {
- int semanticIndex = 0;
- for (size_t attributeIndex = 0; attributeIndex < mActiveAttributes.size(); attributeIndex++)
- {
- const sh::ShaderVariable &attribute = mActiveAttributes[attributeIndex];
-
- if (attribute.name == attributeName)
- {
- return semanticIndex;
- }
-
- semanticIndex += gl::VariableRegisterCount(attribute.type);
- }
- }
-
- return -1;
-}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.h
index 3c9aac2c12..d0237b5985 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.h
@@ -6,12 +6,12 @@
// ShaderD3D.h: Defines the rx::ShaderD3D class which implements rx::ShaderImpl.
-#ifndef LIBGLESV2_RENDERER_SHADERD3D_H_
-#define LIBGLESV2_RENDERER_SHADERD3D_H_
+#ifndef LIBANGLE_RENDERER_D3D_SHADERD3D_H_
+#define LIBANGLE_RENDERER_D3D_SHADERD3D_H_
-#include "libGLESv2/renderer/ShaderImpl.h"
-#include "libGLESv2/renderer/Workarounds.h"
-#include "libGLESv2/Shader.h"
+#include "libANGLE/renderer/ShaderImpl.h"
+#include "libANGLE/renderer/Workarounds.h"
+#include "libANGLE/Shader.h"
#include <map>
@@ -25,15 +25,13 @@ class ShaderD3D : public ShaderImpl
friend class DynamicHLSL;
public:
- ShaderD3D(const gl::Data &data, GLenum type, RendererD3D *renderer);
+ ShaderD3D(GLenum type);
virtual ~ShaderD3D();
static ShaderD3D *makeShaderD3D(ShaderImpl *impl);
static const ShaderD3D *makeShaderD3D(const ShaderImpl *impl);
// ShaderImpl implementation
- virtual const std::string &getInfoLog() const { return mInfoLog; }
- virtual const std::string &getTranslatedSource() const { return mHlsl; }
virtual std::string getDebugInfo() const;
// D3D-specific methods
@@ -41,36 +39,28 @@ class ShaderD3D : public ShaderImpl
void resetVaryingsRegisterAssignment();
unsigned int getUniformRegister(const std::string &uniformName) const;
unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
- int getSemanticIndex(const std::string &attributeName) const;
void appendDebugInfo(const std::string &info) { mDebugInfo += info; }
- D3DWorkaroundType getD3DWorkarounds() const;
+ void generateWorkarounds(D3DCompilerWorkarounds *workarounds) const;
int getShaderVersion() const { return mShaderVersion; }
bool usesDepthRange() const { return mUsesDepthRange; }
bool usesPointSize() const { return mUsesPointSize; }
+ bool usesDeferredInit() const { return mUsesDeferredInit; }
- static void releaseCompiler();
- static ShShaderOutput getCompilerOutputType(GLenum shader);
+ GLenum getShaderType() const;
+ ShShaderOutput getCompilerOutputType() const;
- virtual bool compile(const gl::Data &data, const std::string &source);
+ virtual bool compile(gl::Compiler *compiler, const std::string &source);
private:
- DISALLOW_COPY_AND_ASSIGN(ShaderD3D);
+ void compileToHLSL(ShHandle compiler, const std::string &source);
+ void parseVaryings(ShHandle compiler);
- void compileToHLSL(const gl::Data &data, void *compiler, const std::string &source);
- void parseVaryings(void *compiler);
-
- void initializeCompiler(const gl::Data &data);
- void parseAttributes(void *compiler);
- void *getCompiler();
+ void parseAttributes(ShHandle compiler);
static bool compareVarying(const gl::PackedVarying &x, const gl::PackedVarying &y);
- static void *mFragmentCompiler;
- static void *mVertexCompiler;
-
- GLenum mType;
- RendererD3D *mRenderer;
+ GLenum mShaderType;
int mShaderVersion;
@@ -85,9 +75,10 @@ class ShaderD3D : public ShaderImpl
bool mUsesFragDepth;
bool mUsesDiscardRewriting;
bool mUsesNestedBreak;
+ bool mUsesDeferredInit;
+ bool mRequiresIEEEStrictCompiling;
- std::string mHlsl;
- std::string mInfoLog;
+ ShShaderOutput mCompilerOutputType;
std::string mDebugInfo;
std::map<std::string, unsigned int> mUniformRegisterMap;
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
@@ -95,4 +86,4 @@ class ShaderD3D : public ShaderImpl
}
-#endif // LIBGLESV2_RENDERER_SHADERD3D_H_
+#endif // LIBANGLE_RENDERER_D3D_SHADERD3D_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp
new file mode 100644
index 0000000000..97ffdf5094
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 2012-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.
+//
+
+// 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) : mSize(initialSize)
+{
+}
+
+UniformStorageD3D::~UniformStorageD3D()
+{
+}
+
+size_t UniformStorageD3D::size() const
+{
+ return mSize;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h
new file mode 100644
index 0000000000..71b83b7954
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h
@@ -0,0 +1,54 @@
+//
+// Copyright (c) 2012-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.
+//
+
+// 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/debug.h"
+
+#include <vector>
+#include <cstdint>
+
+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;
+
+ private:
+ size_t mSize;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_SHADEREXECUTABLED3D_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
new file mode 100644
index 0000000000..4fde295443
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
@@ -0,0 +1,396 @@
+//
+// Copyright (c) 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/Display.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+
+#include <tchar.h>
+#include <EGL/eglext.h>
+#include <algorithm>
+
+namespace rx
+{
+
+SurfaceD3D *SurfaceD3D::createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLClientBuffer shareHandle,
+ EGLint width, EGLint height)
+{
+ return new SurfaceD3D(renderer, display, config, width, height, EGL_TRUE, shareHandle, NULL);
+}
+
+SurfaceD3D *SurfaceD3D::createFromWindow(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLNativeWindowType window,
+ EGLint fixedSize, EGLint width, EGLint height)
+{
+ return new SurfaceD3D(renderer, display, config, width, height, fixedSize, static_cast<EGLClientBuffer>(0), window);
+}
+
+SurfaceD3D::SurfaceD3D(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLint width, EGLint height, EGLint fixedSize,
+ EGLClientBuffer shareHandle, EGLNativeWindowType window)
+ : SurfaceImpl(),
+ mRenderer(renderer),
+ mDisplay(display),
+ mFixedSize(fixedSize == EGL_TRUE),
+ mRenderTargetFormat(config->renderTargetFormat),
+ mDepthStencilFormat(config->depthStencilFormat),
+ mSwapChain(nullptr),
+ mSwapIntervalDirty(true),
+ mWindowSubclassed(false),
+ mNativeWindow(window),
+ mWidth(width),
+ mHeight(height),
+ mSwapInterval(1),
+ mShareHandle(reinterpret_cast<HANDLE*>(shareHandle))
+{
+ subclassWindow();
+}
+
+SurfaceD3D::~SurfaceD3D()
+{
+ unsubclassWindow();
+ releaseSwapChain();
+}
+
+void SurfaceD3D::releaseSwapChain()
+{
+ SafeDelete(mSwapChain);
+}
+
+egl::Error SurfaceD3D::initialize()
+{
+ if (mNativeWindow.getNativeWindow())
+ {
+ if (!mNativeWindow.initialize())
+ {
+ return egl::Error(EGL_BAD_SURFACE);
+ }
+ }
+
+ egl::Error error = resetSwapChain();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceD3D::bindTexImage(EGLint)
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceD3D::releaseTexImage(EGLint)
+{
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceD3D::resetSwapChain()
+{
+ ASSERT(!mSwapChain);
+
+ int width;
+ int height;
+
+ if (!mFixedSize)
+ {
+ RECT windowRect;
+ if (!mNativeWindow.getClientRect(&windowRect))
+ {
+ ASSERT(false);
+
+ return egl::Error(EGL_BAD_SURFACE, "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 = mWidth;
+ height = mHeight;
+ }
+
+ mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mRenderTargetFormat, mDepthStencilFormat);
+ if (!mSwapChain)
+ {
+ return egl::Error(EGL_BAD_ALLOC);
+ }
+
+ egl::Error error = resetSwapChain(width, height);
+ if (error.isError())
+ {
+ SafeDelete(mSwapChain);
+ return error;
+ }
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceD3D::resizeSwapChain(int backbufferWidth, int backbufferHeight)
+{
+ ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
+ ASSERT(mSwapChain);
+
+ EGLint status = mSwapChain->resize(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::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceD3D::resetSwapChain(int backbufferWidth, int backbufferHeight)
+{
+ ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
+ ASSERT(mSwapChain);
+
+ EGLint status = mSwapChain->reset(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::Error(EGL_SUCCESS);
+}
+
+egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ if (!mSwapChain)
+ {
+ return egl::Error(EGL_SUCCESS);
+ }
+
+ if (x + width > mWidth)
+ {
+ width = mWidth - x;
+ }
+
+ if (y + height > mHeight)
+ {
+ height = mHeight - y;
+ }
+
+ if (width == 0 || height == 0)
+ {
+ return egl::Error(EGL_SUCCESS);
+ }
+
+ EGLint status = mSwapChain->swapRect(x, y, width, height);
+
+ if (status == EGL_CONTEXT_LOST)
+ {
+ mRenderer->notifyDeviceLost();
+ return egl::Error(status);
+ }
+ else if (status != EGL_SUCCESS)
+ {
+ return egl::Error(status);
+ }
+
+ checkForOutOfDateSwapChain();
+
+ return egl::Error(EGL_SUCCESS);
+}
+
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
+#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
+
+static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
+{
+ if (message == WM_SIZE)
+ {
+ SurfaceD3D* surf = reinterpret_cast<SurfaceD3D*>(GetProp(hwnd, kSurfaceProperty));
+ if(surf)
+ {
+ surf->checkForOutOfDateSwapChain();
+ }
+ }
+ WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
+ return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
+}
+#endif
+
+void SurfaceD3D::subclassWindow()
+{
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ HWND window = mNativeWindow.getNativeWindow();
+ if (!window)
+ {
+ return;
+ }
+
+ DWORD processId;
+ DWORD threadId = GetWindowThreadProcessId(window, &processId);
+ if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
+ {
+ return;
+ }
+
+ SetLastError(0);
+ LONG_PTR oldWndProc = SetWindowLongPtr(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
+ if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
+ {
+ mWindowSubclassed = false;
+ return;
+ }
+
+ SetProp(window, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
+ SetProp(window, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
+ mWindowSubclassed = true;
+#endif
+}
+
+void SurfaceD3D::unsubclassWindow()
+{
+ if (!mWindowSubclassed)
+ {
+ return;
+ }
+
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ HWND window = mNativeWindow.getNativeWindow();
+ if (!window)
+ {
+ return;
+ }
+
+ // un-subclass
+ LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(window, kParentWndProc));
+
+ // Check the windowproc is still SurfaceWindowProc.
+ // If this assert fails, then it is likely the application has subclassed the
+ // hwnd as well and did not unsubclass before destroying its EGL context. The
+ // application should be modified to either subclass before initializing the
+ // EGL context, or to unsubclass before destroying the EGL context.
+ if(parentWndFunc)
+ {
+ LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc);
+ UNUSED_ASSERTION_VARIABLE(prevWndFunc);
+ ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
+ }
+
+ RemoveProp(window, kSurfaceProperty);
+ RemoveProp(window, kParentWndProc);
+#endif
+ mWindowSubclassed = false;
+}
+
+bool SurfaceD3D::checkForOutOfDateSwapChain()
+{
+ 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))
+ {
+ ASSERT(false);
+ return false;
+ }
+
+ // 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();
+ }
+
+ bool wasDirty = (mSwapIntervalDirty || sizeDirty);
+
+ if (mSwapIntervalDirty)
+ {
+ resetSwapChain(clientWidth, clientHeight);
+ }
+ else if (sizeDirty)
+ {
+ resizeSwapChain(clientWidth, clientHeight);
+ }
+
+ return wasDirty;
+}
+
+egl::Error SurfaceD3D::swap()
+{
+ return swapRect(0, 0, mWidth, mHeight);
+}
+
+egl::Error SurfaceD3D::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ return swapRect(x, y, width, height);
+}
+
+rx::SwapChainD3D *SurfaceD3D::getSwapChain() const
+{
+ return mSwapChain;
+}
+
+void SurfaceD3D::setSwapInterval(EGLint interval)
+{
+ if (mSwapInterval == interval)
+ {
+ return;
+ }
+
+ mSwapInterval = interval;
+ mSwapIntervalDirty = true;
+}
+
+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;
+}
+
+egl::Error SurfaceD3D::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ ASSERT(attribute == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || attribute == EGL_DEVICE_EXT);
+ if (attribute == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE)
+ *value = mSwapChain->getShareHandle();
+ else if (attribute == EGL_DEVICE_EXT)
+ *value = mSwapChain->getDevice();
+ return egl::Error(EGL_SUCCESS);
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h
new file mode 100644
index 0000000000..070b7cdbc4
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h
@@ -0,0 +1,92 @@
+//
+// Copyright (c) 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/d3d11/NativeWindow.h"
+
+namespace egl
+{
+class Surface;
+}
+
+namespace rx
+{
+class SwapChainD3D;
+class RendererD3D;
+
+class SurfaceD3D : public SurfaceImpl
+{
+ public:
+ static SurfaceD3D *createFromWindow(RendererD3D *renderer, egl::Display *display, const egl::Config *config,
+ EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height);
+ static SurfaceD3D *createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config,
+ EGLClientBuffer shareHandle, EGLint width, EGLint height);
+ ~SurfaceD3D() override;
+ void releaseSwapChain();
+
+ egl::Error initialize() override;
+
+ egl::Error swap() override;
+ egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(EGLint buffer) override;
+ egl::Error releaseTexImage(EGLint buffer) override;
+ void setSwapInterval(EGLint interval) override;
+
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+
+ EGLint isPostSubBufferSupported() const override;
+
+ // D3D implementations
+ SwapChainD3D *getSwapChain() const;
+
+ egl::Error resetSwapChain();
+
+ // Returns true if swapchain changed due to resize or interval update
+ bool checkForOutOfDateSwapChain();
+
+ private:
+ SurfaceD3D(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLint width, EGLint height,
+ EGLint fixedSize, EGLClientBuffer shareHandle, EGLNativeWindowType window);
+
+ egl::Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
+ egl::Error resetSwapChain(int backbufferWidth, int backbufferHeight);
+ egl::Error resizeSwapChain(int backbufferWidth, int backbufferHeight);
+
+ void subclassWindow();
+ void unsubclassWindow();
+
+ RendererD3D *mRenderer;
+ egl::Display *mDisplay;
+
+ bool mFixedSize;
+
+ GLenum mRenderTargetFormat;
+ GLenum mDepthStencilFormat;
+
+ SwapChainD3D *mSwapChain;
+ bool mSwapIntervalDirty;
+ bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
+
+ NativeWindow mNativeWindow; // Handler for the Window that the surface is created for.
+ EGLint mWidth;
+ EGLint mHeight;
+
+ EGLint mSwapInterval;
+
+ HANDLE mShareHandle;
+};
+
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_SURFACED3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h
index 1417e0bdf6..da36e52ea7 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h
@@ -4,18 +4,20 @@
// found in the LICENSE file.
//
-// SwapChain.h: Defines a back-end specific class that hides the details of the
+// SwapChainD3D.h: Defines a back-end specific class that hides the details of the
// implementation-specific swapchain.
-#ifndef LIBGLESV2_RENDERER_SWAPCHAIN_H_
-#define LIBGLESV2_RENDERER_SWAPCHAIN_H_
+#ifndef LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_
+#define LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_
+
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
#include "common/angleutils.h"
-#include "common/NativeWindow.h"
#include "common/platform.h"
-#include <GLES2/gl2.h>
-#include <EGL/egl.h>
+// TODO: move out of D3D11
+#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h"
#if !defined(ANGLE_FORCE_VSYNC_OFF)
#define ANGLE_FORCE_VSYNC_OFF 0
@@ -23,26 +25,31 @@
namespace rx
{
+class RenderTargetD3D;
-class SwapChain
+class SwapChainD3D : angle::NonCopyable
{
public:
- SwapChain(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+ SwapChainD3D(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
: mNativeWindow(nativeWindow), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat)
{
}
- virtual ~SwapChain() {};
+ virtual ~SwapChainD3D() {};
virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0;
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0;
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0;
virtual void recreate() = 0;
+ virtual void *getDevice() { return NULL; }
+
+ virtual RenderTargetD3D *getColorRenderTarget() = 0;
+ virtual RenderTargetD3D *getDepthStencilRenderTarget() = 0;
GLenum GetBackBufferInternalFormat() const { return mBackBufferFormat; }
GLenum GetDepthBufferInternalFormat() const { return mDepthBufferFormat; }
- virtual HANDLE getShareHandle() {return mShareHandle;};
+ HANDLE getShareHandle() { return mShareHandle; }
protected:
rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for.
@@ -53,4 +60,4 @@ class SwapChain
};
}
-#endif // LIBGLESV2_RENDERER_SWAPCHAIN_H_
+#endif // LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp
index 4a67701fdf..78b03f2283 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp
@@ -6,23 +6,23 @@
// TextureD3D.cpp: Implementations of the Texture interfaces shared betweeen the D3D backends.
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/renderer/BufferImpl.h"
-#include "libGLESv2/renderer/RenderTarget.h"
-#include "libGLESv2/renderer/d3d/BufferD3D.h"
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
-#include "libGLESv2/renderer/d3d/TextureStorage.h"
-#include "libGLESv2/renderer/d3d/ImageD3D.h"
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
-
-#include "libEGL/Surface.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
#include "common/mathutil.h"
#include "common/utilities.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Framebuffer.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/ImageD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+#include "libANGLE/renderer/d3d/TextureStorage.h"
namespace rx
{
@@ -30,7 +30,8 @@ namespace rx
namespace
{
-gl::Error GetUnpackPointer(const gl::PixelUnpackState &unpack, const void *pixels, const uint8_t **pointerOut)
+gl::Error GetUnpackPointer(const gl::PixelUnpackState &unpack, const uint8_t *pixels,
+ ptrdiff_t layerOffset, const uint8_t **pointerOut)
{
if (unpack.pixelBuffer.id() != 0)
{
@@ -40,7 +41,7 @@ gl::Error GetUnpackPointer(const gl::PixelUnpackState &unpack, const void *pixel
// 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 = BufferD3D::makeBufferD3D(pixelBuffer->getImplementation());
+ BufferD3D *bufferD3D = GetImplAs<BufferD3D>(pixelBuffer);
ASSERT(bufferD3D);
const uint8_t *bufferData = NULL;
gl::Error error = bufferD3D->getData(&bufferData);
@@ -53,7 +54,13 @@ gl::Error GetUnpackPointer(const gl::PixelUnpackState &unpack, const void *pixel
}
else
{
- *pointerOut = static_cast<const uint8_t *>(pixels);
+ *pointerOut = pixels;
+ }
+
+ // Offset the pointer for 2D array layer (if it's valid)
+ if (*pointerOut != nullptr)
+ {
+ *pointerOut += layerOffset;
}
return gl::Error(GL_NO_ERROR);
@@ -79,40 +86,45 @@ TextureD3D::~TextureD3D()
{
}
-TextureD3D *TextureD3D::makeTextureD3D(TextureImpl *texture)
-{
- ASSERT(HAS_DYNAMIC_TYPE(TextureD3D*, texture));
- return static_cast<TextureD3D*>(texture);
-}
-
-TextureStorage *TextureD3D::getNativeTexture()
+gl::Error TextureD3D::getNativeTexture(TextureStorage **outStorage)
{
// ensure the underlying texture is created
- initializeStorage(false);
+ gl::Error error = initializeStorage(false);
+ if (error.isError())
+ {
+ return error;
+ }
if (mTexStorage)
{
- updateStorage();
+ error = updateStorage();
+ if (error.isError())
+ {
+ return error;
+ }
}
- return mTexStorage;
+ ASSERT(outStorage);
+
+ *outStorage = mTexStorage;
+ return gl::Error(GL_NO_ERROR);
}
GLint TextureD3D::getBaseLevelWidth() const
{
- const Image *baseImage = getBaseLevelImage();
+ const ImageD3D *baseImage = getBaseLevelImage();
return (baseImage ? baseImage->getWidth() : 0);
}
GLint TextureD3D::getBaseLevelHeight() const
{
- const Image *baseImage = getBaseLevelImage();
+ const ImageD3D *baseImage = getBaseLevelImage();
return (baseImage ? baseImage->getHeight() : 0);
}
GLint TextureD3D::getBaseLevelDepth() const
{
- const Image *baseImage = getBaseLevelImage();
+ const ImageD3D *baseImage = getBaseLevelImage();
return (baseImage ? baseImage->getDepth() : 0);
}
@@ -121,11 +133,11 @@ GLint TextureD3D::getBaseLevelDepth() const
// the base level image for anything except querying texture format and size.
GLenum TextureD3D::getBaseLevelInternalFormat() const
{
- const Image *baseImage = getBaseLevelImage();
+ const ImageD3D *baseImage = getBaseLevelImage();
return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
}
-bool TextureD3D::shouldUseSetData(const Image *image) const
+bool TextureD3D::shouldUseSetData(const ImageD3D *image) const
{
if (!mRenderer->getWorkarounds().setDataFasterThanImageUpload)
{
@@ -145,9 +157,17 @@ bool TextureD3D::shouldUseSetData(const Image *image) const
return (mTexStorage && !internalFormat.compressed);
}
-gl::Error TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, const gl::ImageIndex &index)
+gl::Error TextureD3D::setImage(const gl::ImageIndex &index, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels,
+ ptrdiff_t layerOffset)
{
- Image *image = getImage(index);
+ if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0)
+ {
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION, "unimplemented pixel store state");
+ }
+
+ ImageD3D *image = getImage(index);
ASSERT(image);
// No-op
@@ -159,7 +179,7 @@ gl::Error TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type,
// 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 = NULL;
- gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ gl::Error error = GetUnpackPointer(unpack, pixels, layerOffset, &pixelData);
if (error.isError())
{
return error;
@@ -167,15 +187,14 @@ gl::Error TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type,
if (pixelData != NULL)
{
- gl::Error error(GL_NO_ERROR);
-
if (shouldUseSetData(image))
{
error = mTexStorage->setData(index, image, NULL, type, unpack, pixelData);
}
else
{
- error = image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData);
+ gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth());
+ error = image->loadData(fullImageArea, unpack, type, pixelData);
}
if (error.isError())
@@ -189,12 +208,12 @@ gl::Error TextureD3D::setImage(const gl::PixelUnpackState &unpack, GLenum type,
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index)
+gl::Error TextureD3D::subImage(const gl::ImageIndex &index, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels, ptrdiff_t layerOffset)
{
// CPU readback & copy where direct GPU copy is not supported
const uint8_t *pixelData = NULL;
- gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ gl::Error error = GetUnpackPointer(unpack, pixels, layerOffset, &pixelData);
if (error.isError())
{
return error;
@@ -202,23 +221,21 @@ gl::Error TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsi
if (pixelData != NULL)
{
- Image *image = getImage(index);
+ ImageD3D *image = getImage(index);
ASSERT(image);
- gl::Box region(xoffset, yoffset, zoffset, width, height, depth);
if (shouldUseSetData(image))
{
- return mTexStorage->setData(index, image, &region, type, unpack, pixelData);
+ return mTexStorage->setData(index, image, &area, type, unpack, pixelData);
}
- gl::Error error = image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment,
- type, pixelData);
+ error = image->loadData(area, unpack, type, pixelData);
if (error.isError())
{
return error;
}
- error = commitRegion(index, region);
+ error = commitRegion(index, area);
if (error.isError())
{
return error;
@@ -230,12 +247,19 @@ gl::Error TextureD3D::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsi
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D::setCompressedImage(const gl::PixelUnpackState &unpack, GLsizei imageSize, const void *pixels, Image *image)
+gl::Error TextureD3D::setCompressedImage(const gl::ImageIndex &index, const gl::PixelUnpackState &unpack,
+ const uint8_t *pixels, ptrdiff_t layerOffset)
{
+ if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0)
+ {
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION, "unimplemented pixel store state");
+ }
+
// 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 = NULL;
- gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ gl::Error error = GetUnpackPointer(unpack, pixels, layerOffset, &pixelData);
if (error.isError())
{
return error;
@@ -243,7 +267,11 @@ gl::Error TextureD3D::setCompressedImage(const gl::PixelUnpackState &unpack, GLs
if (pixelData != NULL)
{
- gl::Error error = image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixelData);
+ ImageD3D *image = getImage(index);
+ ASSERT(image);
+
+ gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth());
+ error = image->loadCompressedData(fullImageArea, pixelData);
if (error.isError())
{
return error;
@@ -255,11 +283,18 @@ gl::Error TextureD3D::setCompressedImage(const gl::PixelUnpackState &unpack, GLs
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels, Image *image)
+gl::Error TextureD3D::subImageCompressed(const gl::ImageIndex &index, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels,
+ ptrdiff_t layerOffset)
{
+ if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0)
+ {
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION, "unimplemented pixel store state");
+ }
+
const uint8_t *pixelData = NULL;
- gl::Error error = GetUnpackPointer(unpack, pixels, &pixelData);
+ gl::Error error = GetUnpackPointer(unpack, pixels, layerOffset, &pixelData);
if (error.isError())
{
return error;
@@ -267,7 +302,10 @@ gl::Error TextureD3D::subImageCompressed(GLint xoffset, GLint yoffset, GLint zof
if (pixelData != NULL)
{
- gl::Error error = image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixelData);
+ ImageD3D *image = getImage(index);
+ ASSERT(image);
+
+ error = image->loadCompressedData(area, pixelData);
if (error.isError())
{
return error;
@@ -284,8 +322,8 @@ bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum siz
return unpack.pixelBuffer.id() != 0 && mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
}
-gl::Error TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
- GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget)
+gl::Error TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const uint8_t *pixels, const gl::Box &destArea,
+ GLenum sizedInternalFormat, GLenum type, RenderTargetD3D *destRenderTarget)
{
// No-op
if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0)
@@ -333,7 +371,7 @@ TextureStorage *TextureD3D::getStorage()
return mTexStorage;
}
-Image *TextureD3D::getBaseLevelImage() const
+ImageD3D *TextureD3D::getBaseLevelImage() const
{
return getImage(getImageIndex(0, 0));
}
@@ -347,6 +385,23 @@ gl::Error TextureD3D::generateMipmaps()
return gl::Error(GL_NO_ERROR); // no-op
}
+ if (mTexStorage && mRenderer->getWorkarounds().zeroMaxLodWorkaround)
+ {
+ // Switch to using the mipmapped texture.
+ TextureStorage *textureStorage = NULL;
+ gl::Error error = getNativeTexture(&textureStorage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = textureStorage->useLevelZeroWorkaroundTexture(false);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
// Set up proper mipmap chain in our Image array.
initMipmapsImages();
@@ -365,9 +420,10 @@ gl::Error TextureD3D::generateMipmaps()
{
gl::ImageIndex srcIndex = getImageIndex(0, layer);
- Image *image = getImage(srcIndex);
- gl::Rectangle area(0, 0, image->getWidth(), image->getHeight());
- gl::Error error = image->copy(0, 0, 0, area, srcIndex, mTexStorage);
+ ImageD3D *image = getImage(srcIndex);
+ gl::Box area(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth());
+ gl::Offset offset(0, 0, 0);
+ gl::Error error = image->copy(offset, area, srcIndex, mTexStorage);
if (error.isError())
{
return error;
@@ -384,7 +440,12 @@ gl::Error TextureD3D::generateMipmaps()
}
}
- bool renderableStorage = (mTexStorage && mTexStorage->isRenderTarget());
+ // 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->getWorkarounds().zeroMaxLodWorkaround));
for (GLint layer = 0; layer < layerCount; ++layer)
{
@@ -416,19 +477,24 @@ gl::Error TextureD3D::generateMipmaps()
}
}
+ if (mTexStorage)
+ {
+ updateStorage();
+ }
+
return gl::Error(GL_NO_ERROR);
}
bool TextureD3D::isBaseImageZeroSize() const
{
- Image *baseImage = getBaseLevelImage();
+ ImageD3D *baseImage = getBaseLevelImage();
if (!baseImage || baseImage->getWidth() <= 0)
{
return true;
}
- if (!gl::IsCubemapTextureTarget(baseImage->getTarget()) && baseImage->getHeight() <= 0)
+ if (!gl::IsCubeMapTextureTarget(baseImage->getTarget()) && baseImage->getHeight() <= 0)
{
return true;
}
@@ -487,7 +553,7 @@ gl::Error TextureD3D::ensureRenderTarget()
bool TextureD3D::canCreateRenderTargetForImage(const gl::ImageIndex &index) const
{
- Image *image = getImage(index);
+ ImageD3D *image = getImage(index);
bool levelsComplete = (isImageComplete(index) && isImageComplete(getImageIndex(0, 0)));
return (image->isRenderableFormat() && levelsComplete);
}
@@ -497,9 +563,8 @@ gl::Error TextureD3D::commitRegion(const gl::ImageIndex &index, const gl::Box &r
if (mTexStorage)
{
ASSERT(isValidIndex(index));
- Image *image = getImage(index);
- ImageD3D *imageD3D = ImageD3D::makeImageD3D(image);
- gl::Error error = imageD3D->copyToStorage(mTexStorage, index, region);
+ ImageD3D *image = getImage(index);
+ gl::Error error = image->copyToStorage(mTexStorage, index, region);
if (error.isError())
{
return error;
@@ -516,7 +581,7 @@ TextureD3D_2D::TextureD3D_2D(RendererD3D *renderer)
{
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
{
- mImageArray[i] = ImageD3D::makeImageD3D(renderer->createImage());
+ mImageArray[i] = renderer->createImage();
}
}
@@ -533,14 +598,14 @@ TextureD3D_2D::~TextureD3D_2D()
SafeDelete(mTexStorage);
}
-Image *TextureD3D_2D::getImage(int level, int layer) const
+ImageD3D *TextureD3D_2D::getImage(int level, int layer) const
{
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
ASSERT(layer == 0);
return mImageArray[level];
}
-Image *TextureD3D_2D::getImage(const gl::ImageIndex &index) const
+ImageD3D *TextureD3D_2D::getImage(const gl::ImageIndex &index) const
{
ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
ASSERT(!index.hasLayer());
@@ -578,30 +643,21 @@ GLenum TextureD3D_2D::getInternalFormat(GLint level) const
return GL_NONE;
}
-GLenum TextureD3D_2D::getActualFormat(GLint level) const
-{
- if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mImageArray[level]->getActualFormat();
- else
- return GL_NONE;
-}
-
bool TextureD3D_2D::isDepth(GLint level) const
{
return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-gl::Error TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
- GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
- const void *pixels)
+gl::Error TextureD3D_2D::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
- ASSERT(target == GL_TEXTURE_2D && depth == 1);
+ ASSERT(target == GL_TEXTURE_2D && size.depth == 1);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
bool fastUnpacked = false;
- redefineImage(level, sizedInternalFormat, width, height);
+ redefineImage(level, sizedInternalFormat, size);
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
@@ -609,7 +665,7 @@ gl::Error TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLs
if (isFastUnpackable(unpack, sizedInternalFormat) && isLevelComplete(level))
{
// Will try to create RT storage if it does not exist
- RenderTarget *destRenderTarget = NULL;
+ RenderTargetD3D *destRenderTarget = NULL;
gl::Error error = getRenderTarget(index, &destRenderTarget);
if (error.isError())
{
@@ -632,7 +688,7 @@ gl::Error TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLs
if (!fastUnpacked)
{
- gl::Error error = TextureD3D::setImage(unpack, type, pixels, index);
+ gl::Error error = TextureD3D::setImage(index, type, unpack, pixels, 0);
if (error.isError())
{
return error;
@@ -642,89 +698,80 @@ gl::Error TextureD3D_2D::setImage(GLenum target, GLint level, GLsizei width, GLs
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_2D::setCompressedImage(GLenum target, GLint level, GLenum format,
- GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2D::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
- ASSERT(target == GL_TEXTURE_2D && depth == 1);
+ ASSERT(target == GL_TEXTURE_2D && area.depth == 1 && area.z == 0);
- // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
- redefineImage(level, format, width, height);
-
- return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[level]);
-}
-
-gl::Error TextureD3D_2D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
- const gl::PixelUnpackState &unpack, const void *pixels)
-{
- ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0);
-
- bool fastUnpacked = false;
+ if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0)
+ {
+ UNIMPLEMENTED();
+ return gl::Error(GL_INVALID_OPERATION, "unimplemented pixel store state");
+ }
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
- gl::Box destArea(xoffset, yoffset, 0, width, height, 1);
if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
{
- RenderTarget *renderTarget = NULL;
+ RenderTargetD3D *renderTarget = NULL;
gl::Error error = getRenderTarget(index, &renderTarget);
if (error.isError())
{
return error;
}
- error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget);
- if (error.isError())
- {
- return error;
- }
-
- // Ensure we don't overwrite our newly initialized data
- mImageArray[level]->markClean();
+ ASSERT(!mImageArray[level]->isDirty());
- fastUnpacked = true;
+ return fastUnpackPixels(unpack, pixels, area, getInternalFormat(level), type, renderTarget);
}
-
- if (!fastUnpacked)
+ else
{
- return TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type,
- unpack, pixels, index);
+ return TextureD3D::subImage(index, area, format, type, unpack, pixels, 0);
}
+}
- return gl::Error(GL_NO_ERROR);
+
+gl::Error TextureD3D_2D::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
+{
+ ASSERT(target == GL_TEXTURE_2D && size.depth == 1);
+
+ // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
+ redefineImage(level, internalFormat, size);
+
+ return TextureD3D::setCompressedImage(gl::ImageIndex::Make2D(level), unpack, pixels, 0);
}
-gl::Error TextureD3D_2D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2D::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
- ASSERT(target == GL_TEXTURE_2D && depth == 1 && zoffset == 0);
+ ASSERT(target == GL_TEXTURE_2D && area.depth == 1 && area.z == 0);
- gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels, mImageArray[level]);
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+ gl::Error error = TextureD3D::subImageCompressed(index, area, format, unpack, pixels, 0);
if (error.isError())
{
return error;
}
- gl::ImageIndex index = gl::ImageIndex::Make2D(level);
- gl::Box region(xoffset, yoffset, 0, width, height, 1);
- return commitRegion(index, region);
+ return commitRegion(index, area);
}
-gl::Error TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
- gl::Framebuffer *source)
+gl::Error TextureD3D_2D::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
+ const gl::Framebuffer *source)
{
ASSERT(target == GL_TEXTURE_2D);
- GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
- redefineImage(level, sizedInternalFormat, width, height);
+ GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE);
+ redefineImage(level, sizedInternalFormat, gl::Extents(sourceArea.width, sourceArea.height, 1));
- gl::Rectangle sourceRect(x, y, width, height);
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+ gl::Offset destOffset(0, 0, 0);
- if (!canCreateRenderTargetForImage(index))
+ // 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->getWorkarounds().zeroMaxLodWorkaround)
{
- gl::Error error = mImageArray[level]->copy(0, 0, 0, sourceRect, source);
+ gl::Error error = mImageArray[level]->copy(destOffset, sourceArea, source);
if (error.isError())
{
return error;
@@ -742,9 +789,9 @@ gl::Error TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GL
mImageArray[level]->markClean();
- if (width != 0 && height != 0 && isValidLevel(level))
+ if (sourceArea.width != 0 && sourceArea.height != 0 && isValidLevel(level))
{
- gl::Error error = mRenderer->copyImage2D(source, sourceRect, format, 0, 0, mTexStorage, level);
+ error = mRenderer->copyImage2D(source, sourceArea, internalFormat, destOffset, mTexStorage, level);
if (error.isError())
{
return error;
@@ -755,20 +802,21 @@ gl::Error TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GL
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_2D::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source)
{
- ASSERT(target == GL_TEXTURE_2D && zoffset == 0);
+ ASSERT(target == GL_TEXTURE_2D && destOffset.z == 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)
- gl::Rectangle sourceRect(x, y, width, height);
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
- if (!canCreateRenderTargetForImage(index))
+ // 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->getWorkarounds().zeroMaxLodWorkaround)
{
- gl::Error error = mImageArray[level]->copy(xoffset, yoffset, 0, sourceRect, source);
+ gl::Error error = mImageArray[level]->copy(destOffset, sourceArea, source);
if (error.isError())
{
return error;
@@ -792,9 +840,9 @@ gl::Error TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset,
return error;
}
- error = mRenderer->copyImage2D(source, sourceRect,
+ error = mRenderer->copyImage2D(source, sourceArea,
gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
- xoffset, yoffset, mTexStorage, level);
+ destOffset, mTexStorage, level);
if (error.isError())
{
return error;
@@ -805,25 +853,26 @@ gl::Error TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset,
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_2D::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size)
{
- ASSERT(target == GL_TEXTURE_2D && depth == 1);
+ ASSERT(GL_TEXTURE_2D && size.depth == 1);
- for (int level = 0; level < levels; level++)
+ for (size_t level = 0; level < levels; level++)
{
- GLsizei levelWidth = std::max(1, width >> level);
- GLsizei levelHeight = std::max(1, height >> level);
- mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, levelWidth, levelHeight, 1, true);
+ gl::Extents levelSize(std::max(1, size.width >> level),
+ std::max(1, size.height >> level),
+ 1);
+ mImageArray[level]->redefine(GL_TEXTURE_2D, internalFormat, levelSize, true);
}
for (int level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
- mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true);
+ mImageArray[level]->redefine(GL_TEXTURE_2D, GL_NONE, gl::Extents(0, 0, 0), true);
}
// TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
- TextureStorage *storage = mRenderer->createTextureStorage2D(internalformat, renderTarget, width, height, levels);
+ TextureStorage *storage = mRenderer->createTextureStorage2D(internalFormat, renderTarget, size.width, size.height, levels, false);
gl::Error error = setCompleteTexStorage(storage);
if (error.isError())
@@ -832,6 +881,13 @@ gl::Error TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalf
return error;
}
+ error = updateStorage();
+
+ if (error.isError())
+ {
+ return error;
+ }
+
mImmutable = true;
return gl::Error(GL_NO_ERROR);
@@ -839,16 +895,20 @@ gl::Error TextureD3D_2D::storage(GLenum target, GLsizei levels, GLenum internalf
void TextureD3D_2D::bindTexImage(egl::Surface *surface)
{
- GLenum internalformat = surface->getFormat();
+ GLenum internalformat = surface->getConfig()->renderTargetFormat;
- mImageArray[0]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, surface->getWidth(), surface->getHeight(), 1, true);
+ gl::Extents size(surface->getWidth(), surface->getHeight(), 1);
+ mImageArray[0]->redefine(GL_TEXTURE_2D, internalformat, size, true);
if (mTexStorage)
{
SafeDelete(mTexStorage);
}
- mTexStorage = mRenderer->createTextureStorage2D(surface->getSwapChain());
+ SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+ ASSERT(surfaceD3D);
+
+ mTexStorage = mRenderer->createTextureStorage2D(surfaceD3D->getSwapChain());
mDirtyImages = true;
}
@@ -862,7 +922,7 @@ void TextureD3D_2D::releaseTexImage()
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
- mImageArray[i]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true);
+ mImageArray[i]->redefine(GL_TEXTURE_2D, GL_NONE, gl::Extents(0, 0, 0), true);
}
}
@@ -872,9 +932,11 @@ void TextureD3D_2D::initMipmapsImages()
int levelCount = mipLevels();
for (int level = 1; level < levelCount; level++)
{
- redefineImage(level, getBaseLevelInternalFormat(),
- std::max(getBaseLevelWidth() >> level, 1),
- std::max(getBaseLevelHeight() >> level, 1));
+ gl::Extents levelSize(std::max(getBaseLevelWidth() >> level, 1),
+ std::max(getBaseLevelHeight() >> level, 1),
+ 1);
+
+ redefineImage(level, getBaseLevelInternalFormat(), levelSize);
}
}
@@ -884,7 +946,7 @@ unsigned int TextureD3D_2D::getRenderTargetSerial(const gl::ImageIndex &index)
return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-gl::Error TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+gl::Error TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT)
{
ASSERT(!index.hasLayer());
@@ -916,7 +978,7 @@ bool TextureD3D_2D::isLevelComplete(int level) const
return true;
}
- const Image *baseImage = getBaseLevelImage();
+ const ImageD3D *baseImage = getBaseLevelImage();
GLsizei width = baseImage->getWidth();
GLsizei height = baseImage->getHeight();
@@ -1012,8 +1074,20 @@ gl::Error TextureD3D_2D::createCompleteStorage(bool renderTarget, TextureStorage
// 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->getWorkarounds().zeroMaxLodWorkaround)
+ {
+ // 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
- *outTexStorage = mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels);
+ *outTexStorage = mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels, hintLevelZeroOnly);
return gl::Error(GL_NO_ERROR);
}
@@ -1078,22 +1152,24 @@ gl::Error TextureD3D_2D::updateStorageLevel(int level)
return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height)
+void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, const gl::Extents &size)
{
+ ASSERT(size.depth == 1);
+
// If there currently is a corresponding storage texture image, it has these parameters
const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
const GLenum storageFormat = getBaseLevelInternalFormat();
- mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, width, height, 1, false);
+ mImageArray[level]->redefine(GL_TEXTURE_2D, internalformat, size, false);
if (mTexStorage)
{
const int storageLevels = mTexStorage->getLevelCount();
if ((level >= storageLevels && storageLevels != 0) ||
- width != storageWidth ||
- height != storageHeight ||
+ size.width != storageWidth ||
+ size.height != storageHeight ||
internalformat != storageFormat) // Discard mismatched storage
{
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
@@ -1131,7 +1207,7 @@ TextureD3D_Cube::TextureD3D_Cube(RendererD3D *renderer)
{
for (int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j)
{
- mImageArray[i][j] = ImageD3D::makeImageD3D(renderer->createImage());
+ mImageArray[i][j] = renderer->createImage();
}
}
}
@@ -1152,17 +1228,17 @@ TextureD3D_Cube::~TextureD3D_Cube()
SafeDelete(mTexStorage);
}
-Image *TextureD3D_Cube::getImage(int level, int layer) const
+ImageD3D *TextureD3D_Cube::getImage(int level, int layer) const
{
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(layer < 6);
+ ASSERT(layer >= 0 && layer < 6);
return mImageArray[layer][level];
}
-Image *TextureD3D_Cube::getImage(const gl::ImageIndex &index) const
+ImageD3D *TextureD3D_Cube::getImage(const gl::ImageIndex &index) const
{
ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(index.layerIndex < 6);
+ ASSERT(index.layerIndex >= 0 && index.layerIndex < 6);
return mImageArray[index.layerIndex][index.mipIndex];
}
@@ -1185,75 +1261,75 @@ bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const
return gl::GetInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0;
}
-gl::Error TextureD3D_Cube::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
- GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
- const void *pixels)
+gl::Error TextureD3D_Cube::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
- ASSERT(depth == 1);
+ ASSERT(size.depth == 1);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- redefineImage(index.layerIndex, level, sizedInternalFormat, width, height);
+ redefineImage(index.layerIndex, level, sizedInternalFormat, size);
- return TextureD3D::setImage(unpack, type, pixels, index);
+ return TextureD3D::setImage(index, type, unpack, pixels, 0);
}
-gl::Error TextureD3D_Cube::setCompressedImage(GLenum target, GLint level, GLenum format,
- GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_Cube::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
- ASSERT(depth == 1);
-
- // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
- int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
+ ASSERT(area.depth == 1 && area.z == 0);
- redefineImage(faceIndex, level, format, width, height);
-
- return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[faceIndex][level]);
+ gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
+ return TextureD3D::subImage(index, area, format, type, unpack, pixels, 0);
}
-gl::Error TextureD3D_Cube::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
- const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_Cube::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
- ASSERT(depth == 1 && zoffset == 0);
+ ASSERT(size.depth == 1);
+
+ // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
+ size_t faceIndex = gl::CubeMapTextureTargetToLayerIndex(target);
+
+ redefineImage(faceIndex, level, internalFormat, size);
+
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- return TextureD3D::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, index);
+ return TextureD3D::setCompressedImage(index, unpack, pixels, 0);
}
-gl::Error TextureD3D_Cube::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_Cube::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
- ASSERT(depth == 1 && zoffset == 0);
+ ASSERT(area.depth == 1 && area.z == 0);
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels, mImageArray[index.layerIndex][level]);
+ gl::Error error = TextureD3D::subImageCompressed(index, area, format, unpack, pixels, 0);
if (error.isError())
{
return error;
}
- gl::Box region(xoffset, yoffset, 0, width, height, 1);
- return commitRegion(index, region);
+ return commitRegion(index, area);
}
-gl::Error TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
- GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_Cube::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
+ const gl::Framebuffer *source)
{
- int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
- GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);
+ size_t faceIndex = gl::CubeMapTextureTargetToLayerIndex(target);
+ GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE);
- redefineImage(faceIndex, level, sizedInternalFormat, width, height);
+ gl::Extents size(sourceArea.width, sourceArea.height, 1);
+ redefineImage(faceIndex, level, sizedInternalFormat, size);
- gl::Rectangle sourceRect(x, y, width, height);
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
+ gl::Offset destOffset(0, 0, 0);
- if (!canCreateRenderTargetForImage(index))
+ // 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->getWorkarounds().zeroMaxLodWorkaround)
{
- gl::Error error = mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source);
+ gl::Error error = mImageArray[faceIndex][level]->copy(destOffset, sourceArea, source);
if (error.isError())
{
return error;
@@ -1271,11 +1347,11 @@ gl::Error TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format,
mImageArray[faceIndex][level]->markClean();
- ASSERT(width == height);
+ ASSERT(size.width == size.height);
- if (width > 0 && isValidFaceLevel(faceIndex, level))
+ if (size.width > 0 && isValidFaceLevel(faceIndex, level))
{
- error = mRenderer->copyImageCube(source, sourceRect, format, 0, 0, mTexStorage, target, level);
+ error = mRenderer->copyImageCube(source, sourceArea, internalFormat, destOffset, mTexStorage, target, level);
if (error.isError())
{
return error;
@@ -1286,17 +1362,18 @@ gl::Error TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format,
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_Cube::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source)
{
- int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
+ size_t faceIndex = gl::CubeMapTextureTargetToLayerIndex(target);
- gl::Rectangle sourceRect(x, y, width, height);
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- if (!canCreateRenderTargetForImage(index))
+ // 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->getWorkarounds().zeroMaxLodWorkaround)
{
- gl::Error error =mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source);
+ gl::Error error = mImageArray[faceIndex][level]->copy(destOffset, sourceArea, source);
if (error.isError())
{
return error;
@@ -1320,8 +1397,8 @@ gl::Error TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffse
return error;
}
- error = mRenderer->copyImageCube(source, sourceRect, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
- xoffset, yoffset, mTexStorage, target, level);
+ error = mRenderer->copyImageCube(source, sourceArea, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
+ destOffset, mTexStorage, target, level);
if (error.isError())
{
return error;
@@ -1332,17 +1409,17 @@ gl::Error TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffse
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_Cube::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size)
{
- ASSERT(width == height);
- ASSERT(depth == 1);
+ ASSERT(size.width == size.height);
+ ASSERT(size.depth == 1);
- for (int level = 0; level < levels; level++)
+ for (size_t level = 0; level < levels; level++)
{
- GLsizei mipSize = std::max(1, width >> level);
+ GLsizei mipSize = std::max(1, size.width >> level);
for (int faceIndex = 0; faceIndex < 6; faceIndex++)
{
- mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, internalformat, mipSize, mipSize, 1, true);
+ mImageArray[faceIndex][level]->redefine(GL_TEXTURE_CUBE_MAP, internalFormat, gl::Extents(mipSize, mipSize, 1), true);
}
}
@@ -1350,13 +1427,14 @@ gl::Error TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum interna
{
for (int faceIndex = 0; faceIndex < 6; faceIndex++)
{
- mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, GL_NONE, 0, 0, 0, true);
+ mImageArray[faceIndex][level]->redefine(GL_TEXTURE_CUBE_MAP, GL_NONE, gl::Extents(0, 0, 0), true);
}
}
// TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
- TextureStorage *storage = mRenderer->createTextureStorageCube(internalformat, renderTarget, width, levels);
+
+ TextureStorage *storage = mRenderer->createTextureStorageCube(internalFormat, renderTarget, size.width, levels, false);
gl::Error error = setCompleteTexStorage(storage);
if (error.isError())
@@ -1365,6 +1443,13 @@ gl::Error TextureD3D_Cube::storage(GLenum target, GLsizei levels, GLenum interna
return error;
}
+ error = updateStorage();
+
+ if (error.isError())
+ {
+ return error;
+ }
+
mImmutable = true;
return gl::Error(GL_NO_ERROR);
@@ -1417,19 +1502,20 @@ void TextureD3D_Cube::initMipmapsImages()
for (int level = 1; level < levelCount; level++)
{
int faceLevelSize = (std::max(mImageArray[faceIndex][0]->getWidth() >> level, 1));
- redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), faceLevelSize, faceLevelSize);
+ redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(),
+ gl::Extents(faceLevelSize, faceLevelSize, 1));
}
}
}
unsigned int TextureD3D_Cube::getRenderTargetSerial(const gl::ImageIndex &index)
{
- return (ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
+ return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-gl::Error TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+gl::Error TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT)
{
- ASSERT(gl::IsCubemapTextureTarget(index.type));
+ ASSERT(gl::IsCubeMapTextureTarget(index.type));
// ensure the underlying texture is created
gl::Error error = ensureRenderTarget();
@@ -1498,8 +1584,23 @@ gl::Error TextureD3D_Cube::createCompleteStorage(bool renderTarget, TextureStora
// 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->getWorkarounds().zeroMaxLodWorkaround)
+ {
+ // If any of the CPU images (levels >= 1) are dirty, then the textureStorage should use the mipped texture to begin with.
+ // Otherwise, it should use the level-zero-only texture.
+ hintLevelZeroOnly = true;
+ for (int faceIndex = 0; faceIndex < 6 && 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
- *outTexStorage = mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels);
+ *outTexStorage = mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels, hintLevelZeroOnly);
return gl::Error(GL_NO_ERROR);
}
@@ -1607,7 +1708,7 @@ gl::Error TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level)
if (image->isDirty())
{
- GLenum faceTarget = gl::TextureCubeMap::layerIndexToTarget(faceIndex);
+ GLenum faceTarget = gl::LayerIndexToCubeMapTextureTarget(faceIndex);
gl::ImageIndex index = gl::ImageIndex::MakeCube(faceTarget, level);
gl::Box region(0, 0, 0, image->getWidth(), image->getHeight(), 1);
gl::Error error = commitRegion(index, region);
@@ -1620,29 +1721,29 @@ gl::Error TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level)
return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height)
+void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalformat, const gl::Extents &size)
{
// If there currently is a corresponding storage texture image, it has these parameters
const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
const GLenum storageFormat = getBaseLevelInternalFormat();
- mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, internalformat, width, height, 1, false);
+ mImageArray[faceIndex][level]->redefine(GL_TEXTURE_CUBE_MAP, internalformat, size, false);
if (mTexStorage)
{
const int storageLevels = mTexStorage->getLevelCount();
if ((level >= storageLevels && storageLevels != 0) ||
- width != storageWidth ||
- height != storageHeight ||
+ size.width != storageWidth ||
+ size.height != storageHeight ||
internalformat != storageFormat) // Discard mismatched storage
{
- for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+ for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++)
{
- for (int faceIndex = 0; faceIndex < 6; faceIndex++)
+ for (int dirtyFace = 0; dirtyFace < 6; dirtyFace++)
{
- mImageArray[faceIndex][level]->markDirty();
+ mImageArray[dirtyFace][dirtyLevel]->markDirty();
}
}
@@ -1661,12 +1762,12 @@ gl::ImageIndexIterator TextureD3D_Cube::imageIterator() const
gl::ImageIndex TextureD3D_Cube::getImageIndex(GLint mip, GLint layer) const
{
// The "layer" of the image index corresponds to the cube face
- return gl::ImageIndex::MakeCube(gl::TextureCubeMap::layerIndexToTarget(layer), mip);
+ return gl::ImageIndex::MakeCube(gl::LayerIndexToCubeMapTextureTarget(layer), mip);
}
bool TextureD3D_Cube::isValidIndex(const gl::ImageIndex &index) const
{
- return (mTexStorage && gl::IsCubemapTextureTarget(index.type) &&
+ return (mTexStorage && gl::IsCubeMapTextureTarget(index.type) &&
index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount());
}
@@ -1675,7 +1776,7 @@ TextureD3D_3D::TextureD3D_3D(RendererD3D *renderer)
{
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
{
- mImageArray[i] = ImageD3D::makeImageD3D(renderer->createImage());
+ mImageArray[i] = renderer->createImage();
}
}
@@ -1692,14 +1793,14 @@ TextureD3D_3D::~TextureD3D_3D()
SafeDelete(mTexStorage);
}
-Image *TextureD3D_3D::getImage(int level, int layer) const
+ImageD3D *TextureD3D_3D::getImage(int level, int layer) const
{
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
ASSERT(layer == 0);
return mImageArray[level];
}
-Image *TextureD3D_3D::getImage(const gl::ImageIndex &index) const
+ImageD3D *TextureD3D_3D::getImage(const gl::ImageIndex &index) const
{
ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
ASSERT(!index.hasLayer());
@@ -1750,24 +1851,23 @@ bool TextureD3D_3D::isDepth(GLint level) const
return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-gl::Error TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
- GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
- const void *pixels)
+gl::Error TextureD3D_3D::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
- redefineImage(level, sizedInternalFormat, width, height, depth);
+ redefineImage(level, sizedInternalFormat, size);
bool fastUnpacked = false;
gl::ImageIndex index = gl::ImageIndex::Make3D(level);
// Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
- if (isFastUnpackable(unpack, sizedInternalFormat))
+ if (isFastUnpackable(unpack, sizedInternalFormat) && !size.empty())
{
// Will try to create RT storage if it does not exist
- RenderTarget *destRenderTarget = NULL;
+ RenderTargetD3D *destRenderTarget = NULL;
gl::Error error = getRenderTarget(index, &destRenderTarget);
if (error.isError())
{
@@ -1790,7 +1890,7 @@ gl::Error TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLs
if (!fastUnpacked)
{
- gl::Error error = TextureD3D::setImage(unpack, type, pixels, index);
+ gl::Error error = TextureD3D::setImage(index, type, unpack, pixels, 0);
if (error.isError())
{
return error;
@@ -1800,96 +1900,77 @@ gl::Error TextureD3D_3D::setImage(GLenum target, GLint level, GLsizei width, GLs
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_3D::setCompressedImage(GLenum target, GLint level, GLenum format,
- GLsizei width, GLsizei height,GLsizei depth,
- GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_3D::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
- // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
- redefineImage(level, format, width, height, depth);
-
- return TextureD3D::setCompressedImage(unpack, imageSize, pixels, mImageArray[level]);
-}
-
-gl::Error TextureD3D_3D::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
- const gl::PixelUnpackState &unpack, const void *pixels)
-{
- ASSERT(target == GL_TEXTURE_3D);
-
- bool fastUnpacked = false;
-
gl::ImageIndex index = gl::ImageIndex::Make3D(level);
// Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
if (isFastUnpackable(unpack, getInternalFormat(level)))
{
- RenderTarget *destRenderTarget = NULL;
+ RenderTargetD3D *destRenderTarget = NULL;
gl::Error error = getRenderTarget(index, &destRenderTarget);
if (error.isError())
{
return error;
}
- gl::Box destArea(xoffset, yoffset, zoffset, width, height, depth);
- error = fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget);
- if (error.isError())
- {
- return error;
- }
-
- // Ensure we don't overwrite our newly initialized data
- mImageArray[level]->markClean();
+ ASSERT(!mImageArray[level]->isDirty());
- fastUnpacked = true;
+ return fastUnpackPixels(unpack, pixels, area, getInternalFormat(level), type, destRenderTarget);
}
-
- if (!fastUnpacked)
+ else
{
- return TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type,
- unpack, pixels, index);
+ return TextureD3D::subImage(index, area, format, type, unpack, pixels, 0);
}
+}
- return gl::Error(GL_NO_ERROR);
+gl::Error TextureD3D_3D::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
+{
+ ASSERT(target == GL_TEXTURE_3D);
+
+ // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
+ redefineImage(level, internalFormat, size);
+
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+ return TextureD3D::setCompressedImage(index, unpack, pixels, 0);
}
-gl::Error TextureD3D_3D::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_3D::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
ASSERT(target == GL_TEXTURE_3D);
- gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth,
- format, imageSize, unpack, pixels, mImageArray[level]);
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+ gl::Error error = TextureD3D::subImageCompressed(index, area, format, unpack, pixels, 0);
if (error.isError())
{
return error;
}
- gl::ImageIndex index = gl::ImageIndex::Make3D(level);
- gl::Box region(xoffset, yoffset, zoffset, width, height, depth);
- return commitRegion(index, region);
+ return commitRegion(index, area);
}
-gl::Error TextureD3D_3D::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
- GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_3D::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
+ const gl::Framebuffer *source)
{
UNIMPLEMENTED();
return gl::Error(GL_INVALID_OPERATION, "Copying 3D textures is unimplemented.");
}
-gl::Error TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_3D::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source)
{
ASSERT(target == GL_TEXTURE_3D);
- gl::Rectangle sourceRect(x, y, width, height);
gl::ImageIndex index = gl::ImageIndex::Make3D(level);
if (canCreateRenderTargetForImage(index))
{
- gl::Error error = mImageArray[level]->copy(xoffset, yoffset, zoffset, sourceRect, source);
+ gl::Error error = mImageArray[level]->copy(destOffset, sourceArea, source);
if (error.isError())
{
return error;
@@ -1913,9 +1994,9 @@ gl::Error TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset,
return error;
}
- error = mRenderer->copyImage3D(source, sourceRect,
+ error = mRenderer->copyImage3D(source, sourceArea,
gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format,
- xoffset, yoffset, zoffset, mTexStorage, level);
+ destOffset, mTexStorage, level);
if (error.isError())
{
return error;
@@ -1926,26 +2007,26 @@ gl::Error TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset,
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_3D::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size)
{
ASSERT(target == GL_TEXTURE_3D);
- for (int level = 0; level < levels; level++)
+ for (size_t level = 0; level < levels; level++)
{
- GLsizei levelWidth = std::max(1, width >> level);
- GLsizei levelHeight = std::max(1, height >> level);
- GLsizei levelDepth = std::max(1, depth >> level);
- mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, internalformat, levelWidth, levelHeight, levelDepth, true);
+ 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_TEXTURE_3D, internalFormat, levelSize, true);
}
for (int level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
- mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, GL_NONE, 0, 0, 0, true);
+ mImageArray[level]->redefine(GL_TEXTURE_3D, GL_NONE, gl::Extents(0, 0, 0), true);
}
// TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
- TextureStorage *storage = mRenderer->createTextureStorage3D(internalformat, renderTarget, width, height, depth, levels);
+ TextureStorage *storage = mRenderer->createTextureStorage3D(internalFormat, renderTarget, size.width, size.height, size.depth, levels);
gl::Error error = setCompleteTexStorage(storage);
if (error.isError())
@@ -1954,6 +2035,13 @@ gl::Error TextureD3D_3D::storage(GLenum target, GLsizei levels, GLenum internalf
return error;
}
+ error = updateStorage();
+
+ if (error.isError())
+ {
+ return error;
+ }
+
mImmutable = true;
return gl::Error(GL_NO_ERROR);
@@ -1976,10 +2064,10 @@ void TextureD3D_3D::initMipmapsImages()
int levelCount = mipLevels();
for (int level = 1; level < levelCount; level++)
{
- redefineImage(level, getBaseLevelInternalFormat(),
- std::max(getBaseLevelWidth() >> level, 1),
- std::max(getBaseLevelHeight() >> level, 1),
- std::max(getBaseLevelDepth() >> level, 1));
+ gl::Extents levelSize(std::max(getBaseLevelWidth() >> level, 1),
+ std::max(getBaseLevelHeight() >> level, 1),
+ std::max(getBaseLevelDepth() >> level, 1));
+ redefineImage(level, getBaseLevelInternalFormat(), levelSize);
}
}
@@ -1988,7 +2076,7 @@ unsigned int TextureD3D_3D::getRenderTargetSerial(const gl::ImageIndex &index)
return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-gl::Error TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+gl::Error TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT)
{
// ensure the underlying texture is created
gl::Error error = ensureRenderTarget();
@@ -2031,7 +2119,7 @@ gl::Error TextureD3D_3D::initializeStorage(bool renderTarget)
return gl::Error(GL_NO_ERROR);
}
- bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
+ bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
TextureStorage *storage = NULL;
gl::Error error = createCompleteStorage(createRenderTarget, &storage);
@@ -2185,7 +2273,7 @@ gl::Error TextureD3D_3D::updateStorageLevel(int level)
return gl::Error(GL_NO_ERROR);
}
-void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, const gl::Extents &size)
{
// If there currently is a corresponding storage texture image, it has these parameters
const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
@@ -2193,16 +2281,16 @@ void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, GLsizei wi
const int storageDepth = std::max(1, getBaseLevelDepth() >> level);
const GLenum storageFormat = getBaseLevelInternalFormat();
- mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, internalformat, width, height, depth, false);
+ mImageArray[level]->redefine(GL_TEXTURE_3D, internalformat, size, false);
if (mTexStorage)
{
const int storageLevels = mTexStorage->getLevelCount();
if ((level >= storageLevels && storageLevels != 0) ||
- width != storageWidth ||
- height != storageHeight ||
- depth != storageDepth ||
+ size.width != storageWidth ||
+ size.height != storageHeight ||
+ size.depth != storageDepth ||
internalformat != storageFormat) // Discard mismatched storage
{
for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
@@ -2253,19 +2341,21 @@ TextureD3D_2DArray::~TextureD3D_2DArray()
SafeDelete(mTexStorage);
}
-Image *TextureD3D_2DArray::getImage(int level, int layer) const
+ImageD3D *TextureD3D_2DArray::getImage(int level, int layer) const
{
ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(layer < mLayerCounts[level]);
- return mImageArray[level][layer];
+ ASSERT((layer == 0 && mLayerCounts[level] == 0) ||
+ layer < mLayerCounts[level]);
+ return (mImageArray[level] ? mImageArray[level][layer] : NULL);
}
-Image *TextureD3D_2DArray::getImage(const gl::ImageIndex &index) const
+ImageD3D *TextureD3D_2DArray::getImage(const gl::ImageIndex &index) const
{
ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
- ASSERT(index.layerIndex < mLayerCounts[index.mipIndex]);
+ ASSERT((index.layerIndex == 0 && mLayerCounts[index.mipIndex] == 0) ||
+ index.layerIndex < mLayerCounts[index.mipIndex]);
ASSERT(index.type == GL_TEXTURE_2D_ARRAY);
- return mImageArray[index.mipIndex][index.layerIndex];
+ return (mImageArray[index.mipIndex] ? mImageArray[index.mipIndex][index.layerIndex] : NULL);
}
GLsizei TextureD3D_2DArray::getLayerCount(int level) const
@@ -2294,24 +2384,23 @@ bool TextureD3D_2DArray::isDepth(GLint level) const
return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-gl::Error TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth,
- GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack,
- const void *pixels)
+gl::Error TextureD3D_2DArray::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type);
- redefineImage(level, sizedInternalFormat, width, height, depth);
+ redefineImage(level, sizedInternalFormat, size);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedInternalFormat);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, width, height, unpack.alignment);
+ GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, size.width, size.height, unpack.alignment, unpack.rowLength);
- for (int i = 0; i < depth; i++)
+ for (int i = 0; i < size.depth; i++)
{
- const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
+ const ptrdiff_t layerOffset = (inputDepthPitch * i);
gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, i);
- gl::Error error = TextureD3D::setImage(unpack, type, layerPixels, index);
+ gl::Error error = TextureD3D::setImage(index, type, unpack, pixels, layerOffset);
if (error.isError())
{
return error;
@@ -2321,22 +2410,23 @@ gl::Error TextureD3D_2DArray::setImage(GLenum target, GLint level, GLsizei width
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLenum format,
- GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2DArray::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
- // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
- redefineImage(level, format, width, height, depth);
-
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(level));
+ GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, area.width, area.height, unpack.alignment, unpack.rowLength);
- for (int i = 0; i < depth; i++)
+ for (int i = 0; i < area.depth; i++)
{
- const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
- gl::Error error = TextureD3D::setCompressedImage(unpack, imageSize, layerPixels, mImageArray[level][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 index = gl::ImageIndex::Make2DArray(level, layer);
+ gl::Error error = TextureD3D::subImage(index, layerArea, format, type, unpack, pixels, layerOffset);
if (error.isError())
{
return error;
@@ -2346,23 +2436,23 @@ gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level, GLe
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
- const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(level));
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, width, height, unpack.alignment);
+ // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
+ redefineImage(level, internalFormat, size);
- for (int i = 0; i < depth; i++)
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
+ GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, 1, 0);
+
+ for (int i = 0; i < size.depth; i++)
{
- int layer = zoffset + i;
- const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
+ const ptrdiff_t layerOffset = (inputDepthPitch * i);
- gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
- gl::Error error = TextureD3D::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type,
- unpack, layerPixels, index);
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, i);
+ gl::Error error = TextureD3D::setCompressedImage(index, unpack, pixels, layerOffset);
if (error.isError())
{
return error;
@@ -2372,29 +2462,29 @@ gl::Error TextureD3D_2DArray::subImage(GLenum target, GLint level, GLint xoffset
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels)
+gl::Error TextureD3D_2DArray::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
+ GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0);
- for (int i = 0; i < depth; i++)
+ for (int i = 0; i < area.depth; i++)
{
- int layer = zoffset + i;
- const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
+ int layer = area.z + i;
+ const ptrdiff_t layerOffset = (inputDepthPitch * i);
- gl::Error error = TextureD3D::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, unpack, layerPixels, mImageArray[level][layer]);
+ gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1);
+
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
+ gl::Error error = TextureD3D::subImageCompressed(index, layerArea, format, unpack, pixels, layerOffset);
if (error.isError())
{
return error;
}
- gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
- gl::Box region(xoffset, yoffset, 0, width, height, 1);
- error = commitRegion(index, region);
+ error = commitRegion(index, layerArea);
if (error.isError())
{
return error;
@@ -2404,22 +2494,24 @@ gl::Error TextureD3D_2DArray::subImageCompressed(GLenum target, GLint level, GLi
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_2DArray::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_2DArray::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
+ const gl::Framebuffer *source)
{
UNIMPLEMENTED();
return gl::Error(GL_INVALID_OPERATION, "Copying 2D array textures is unimplemented.");
}
-gl::Error TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+gl::Error TextureD3D_2DArray::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
- gl::Rectangle sourceRect(x, y, width, height);
- gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zoffset);
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, destOffset.z);
if (canCreateRenderTargetForImage(index))
{
- gl::Error error = mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, sourceRect, source);
+ gl::Offset destLayerOffset(destOffset.x, destOffset.y, 0);
+ gl::Error error = mImageArray[level][destOffset.z]->copy(destLayerOffset, sourceArea, source);
if (error.isError())
{
return error;
@@ -2443,8 +2535,8 @@ gl::Error TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xof
return error;
}
- error = mRenderer->copyImage2DArray(source, sourceRect, gl::GetInternalFormatInfo(getInternalFormat(0)).format,
- xoffset, yoffset, zoffset, mTexStorage, level);
+ error = mRenderer->copyImage2DArray(source, sourceArea, gl::GetInternalFormatInfo(getInternalFormat(0)).format,
+ destOffset, mTexStorage, level);
if (error.isError())
{
return error;
@@ -2454,18 +2546,19 @@ gl::Error TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xof
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+gl::Error TextureD3D_2DArray::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size)
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
deleteImages();
- for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+ for (size_t level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
- GLsizei levelWidth = std::max(1, width >> level);
- GLsizei levelHeight = std::max(1, height >> level);
+ gl::Extents levelLayerSize(std::max(1, size.width >> level),
+ std::max(1, size.height >> level),
+ 1);
- mLayerCounts[level] = (level < levels ? depth : 0);
+ mLayerCounts[level] = (level < levels ? size.depth : 0);
if (mLayerCounts[level] > 0)
{
@@ -2474,16 +2567,15 @@ gl::Error TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum inte
for (int layer = 0; layer < mLayerCounts[level]; layer++)
{
- mImageArray[level][layer] = ImageD3D::makeImageD3D(mRenderer->createImage());
- mImageArray[level][layer]->redefine(mRenderer, GL_TEXTURE_2D_ARRAY, internalformat, levelWidth,
- levelHeight, 1, true);
+ mImageArray[level][layer] = mRenderer->createImage();
+ mImageArray[level][layer]->redefine(GL_TEXTURE_2D_ARRAY, internalFormat, levelLayerSize, true);
}
}
}
// TODO(geofflang): Verify storage creation had no errors
bool renderTarget = IsRenderTargetUsage(mUsage);
- TextureStorage *storage = mRenderer->createTextureStorage2DArray(internalformat, renderTarget, width, height, depth, levels);
+ TextureStorage *storage = mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, size.width, size.height, size.depth, levels);
gl::Error error = setCompleteTexStorage(storage);
if (error.isError())
@@ -2492,6 +2584,13 @@ gl::Error TextureD3D_2DArray::storage(GLenum target, GLsizei levels, GLenum inte
return error;
}
+ error = updateStorage();
+
+ if (error.isError())
+ {
+ return error;
+ }
+
mImmutable = true;
return gl::Error(GL_NO_ERROR);
@@ -2512,14 +2611,17 @@ void TextureD3D_2DArray::initMipmapsImages()
{
int baseWidth = getBaseLevelWidth();
int baseHeight = getBaseLevelHeight();
- int baseDepth = getBaseLevelDepth();
+ int baseDepth = getLayerCount(0);
GLenum baseFormat = getBaseLevelInternalFormat();
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
int levelCount = mipLevels();
for (int level = 1; level < levelCount; level++)
{
- redefineImage(level, baseFormat, std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth);
+ gl::Extents levelLayerSize(std::max(baseWidth >> level, 1),
+ std::max(baseHeight >> level, 1),
+ baseDepth);
+ redefineImage(level, baseFormat, levelLayerSize);
}
}
@@ -2528,7 +2630,7 @@ unsigned int TextureD3D_2DArray::getRenderTargetSerial(const gl::ImageIndex &ind
return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0);
}
-gl::Error TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+gl::Error TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT)
{
// ensure the underlying texture is created
gl::Error error = ensureRenderTarget();
@@ -2560,7 +2662,7 @@ gl::Error TextureD3D_2DArray::initializeStorage(bool renderTarget)
return gl::Error(GL_NO_ERROR);
}
- bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
+ bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
TextureStorage *storage = NULL;
gl::Error error = createCompleteStorage(createRenderTarget, &storage);
@@ -2730,7 +2832,7 @@ void TextureD3D_2DArray::deleteImages()
}
}
-void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, const gl::Extents &size)
{
// If there currently is a corresponding storage texture image, it has these parameters
const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
@@ -2744,16 +2846,17 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, GLsiz
}
delete[] mImageArray[level];
mImageArray[level] = NULL;
- mLayerCounts[level] = depth;
+ mLayerCounts[level] = size.depth;
- if (depth > 0)
+ if (size.depth > 0)
{
- mImageArray[level] = new ImageD3D*[depth]();
+ mImageArray[level] = new ImageD3D*[size.depth]();
for (int layer = 0; layer < mLayerCounts[level]; layer++)
{
- mImageArray[level][layer] = ImageD3D::makeImageD3D(mRenderer->createImage());
- mImageArray[level][layer]->redefine(mRenderer, GL_TEXTURE_2D_ARRAY, internalformat, width, height, 1, false);
+ mImageArray[level][layer] = mRenderer->createImage();
+ mImageArray[level][layer]->redefine(GL_TEXTURE_2D_ARRAY, internalformat,
+ gl::Extents(size.width, size.height, 1), false);
}
}
@@ -2762,16 +2865,16 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, GLsiz
const int storageLevels = mTexStorage->getLevelCount();
if ((level >= storageLevels && storageLevels != 0) ||
- width != storageWidth ||
- height != storageHeight ||
- depth != storageDepth ||
+ size.width != storageWidth ||
+ size.height != storageHeight ||
+ size.depth != storageDepth ||
internalformat != storageFormat) // Discard mismatched storage
{
- for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+ for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++)
{
- for (int layer = 0; layer < mLayerCounts[level]; layer++)
+ for (int dirtyLayer = 0; dirtyLayer < mLayerCounts[dirtyLevel]; dirtyLayer++)
{
- mImageArray[level][layer]->markDirty();
+ mImageArray[dirtyLevel][dirtyLayer]->markDirty();
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.h
index 083a6335b9..d94be49a08 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.h
@@ -6,12 +6,12 @@
// TextureD3D.h: Implementations of the Texture interfaces shared betweeen the D3D backends.
-#ifndef LIBGLESV2_RENDERER_TEXTURED3D_H_
-#define LIBGLESV2_RENDERER_TEXTURED3D_H_
+#ifndef LIBANGLE_RENDERER_D3D_TEXTURED3D_H_
+#define LIBANGLE_RENDERER_D3D_TEXTURED3D_H_
-#include "libGLESv2/renderer/TextureImpl.h"
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/Constants.h"
+#include "libANGLE/renderer/TextureImpl.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Constants.h"
namespace gl
{
@@ -21,10 +21,10 @@ class Framebuffer;
namespace rx
{
-class Image;
+class ImageD3D;
class ImageD3D;
class RendererD3D;
-class RenderTarget;
+class RenderTargetD3D;
class TextureStorage;
class TextureD3D : public TextureImpl
@@ -33,14 +33,15 @@ class TextureD3D : public TextureImpl
TextureD3D(RendererD3D *renderer);
virtual ~TextureD3D();
- static TextureD3D *makeTextureD3D(TextureImpl *texture);
-
- TextureStorage *getNativeTexture();
+ gl::Error getNativeTexture(TextureStorage **outStorage);
virtual void setUsage(GLenum usage) { mUsage = usage; }
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;
+
GLint getBaseLevelWidth() const;
GLint getBaseLevelHeight() const;
GLint getBaseLevelDepth() const;
@@ -48,7 +49,7 @@ class TextureD3D : public TextureImpl
bool isImmutable() const { return mImmutable; }
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0;
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index) = 0;
// Returns an iterator over all "Images" for this particular Texture.
@@ -61,18 +62,21 @@ class TextureD3D : public TextureImpl
virtual gl::Error generateMipmaps();
TextureStorage *getStorage();
- Image *getBaseLevelImage() const;
+ ImageD3D *getBaseLevelImage() const;
protected:
- gl::Error setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, const gl::ImageIndex &index);
- gl::Error subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels, const gl::ImageIndex &index);
- gl::Error setCompressedImage(const gl::PixelUnpackState &unpack, GLsizei imageSize, const void *pixels, Image *image);
- gl::Error subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels, Image *image);
+ gl::Error setImage(const gl::ImageIndex &index, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels,
+ ptrdiff_t layerOffset);
+ gl::Error subImage(const gl::ImageIndex &index, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels, ptrdiff_t layerOffset);
+ gl::Error setCompressedImage(const gl::ImageIndex &index, const gl::PixelUnpackState &unpack,
+ const uint8_t *pixels, ptrdiff_t layerOffset);
+ gl::Error subImageCompressed(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::PixelUnpackState &unpack, GLenum sizedInternalFormat);
- gl::Error fastUnpackPixels(const gl::PixelUnpackState &unpack, const void *pixels, const gl::Box &destArea,
- GLenum sizedInternalFormat, GLenum type, RenderTarget *destRenderTarget);
+ gl::Error fastUnpackPixels(const gl::PixelUnpackState &unpack, const uint8_t *pixels, const gl::Box &destArea,
+ GLenum sizedInternalFormat, GLenum type, RenderTargetD3D *destRenderTarget);
GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const;
int mipLevels() const;
@@ -97,13 +101,11 @@ class TextureD3D : public TextureImpl
TextureStorage *mTexStorage;
private:
- DISALLOW_COPY_AND_ASSIGN(TextureD3D);
-
virtual gl::Error initializeStorage(bool renderTarget) = 0;
virtual gl::Error updateStorage() = 0;
- bool shouldUseSetData(const Image *image) const;
+ bool shouldUseSetData(const ImageD3D *image) const;
};
class TextureD3D_2D : public TextureD3D
@@ -112,28 +114,36 @@ class TextureD3D_2D : public TextureD3D
TextureD3D_2D(RendererD3D *renderer);
virtual ~TextureD3D_2D();
- virtual Image *getImage(int level, int layer) const;
- virtual Image *getImage(const gl::ImageIndex &index) const;
+ virtual ImageD3D *getImage(int level, int layer) const;
+ virtual ImageD3D *getImage(const gl::ImageIndex &index) const;
virtual GLsizei getLayerCount(int level) const;
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
GLenum getInternalFormat(GLint level) const;
- GLenum getActualFormat(GLint level) const;
bool isDepth(GLint level) const;
- virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+ gl::Error setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+
+ gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+ gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+
+ gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
+ const gl::Framebuffer *source) override;
+ gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source) override;
+
+ gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
virtual gl::ImageIndexIterator imageIterator() const;
@@ -141,8 +151,6 @@ class TextureD3D_2D : public TextureD3D
virtual bool isValidIndex(const gl::ImageIndex &index) const;
private:
- DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D);
-
virtual gl::Error initializeStorage(bool renderTarget);
virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const;
virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
@@ -156,7 +164,7 @@ class TextureD3D_2D : public TextureD3D
gl::Error updateStorageLevel(int level);
- void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height);
+ void redefineImage(GLint level, GLenum internalformat, const gl::Extents &size);
ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
};
@@ -167,8 +175,8 @@ class TextureD3D_Cube : public TextureD3D
TextureD3D_Cube(RendererD3D *renderer);
virtual ~TextureD3D_Cube();
- virtual Image *getImage(int level, int layer) const;
- virtual Image *getImage(const gl::ImageIndex &index) const;
+ virtual ImageD3D *getImage(int level, int layer) const;
+ virtual ImageD3D *getImage(const gl::ImageIndex &index) const;
virtual GLsizei getLayerCount(int level) const;
virtual bool hasDirtyImages() const { return mDirtyImages; }
@@ -178,18 +186,27 @@ class TextureD3D_Cube : public TextureD3D
GLenum getInternalFormat(GLint level, GLint layer) const;
bool isDepth(GLint level, GLint layer) const;
- virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+ gl::Error setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+
+ gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+ gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+
+ gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
+ const gl::Framebuffer *source) override;
+ gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source) override;
+
+ gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
virtual gl::ImageIndexIterator imageIterator() const;
@@ -197,8 +214,6 @@ class TextureD3D_Cube : public TextureD3D
virtual bool isValidIndex(const gl::ImageIndex &index) const;
private:
- DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube);
-
virtual gl::Error initializeStorage(bool renderTarget);
virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const;
virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
@@ -212,7 +227,7 @@ class TextureD3D_Cube : public TextureD3D
virtual bool isImageComplete(const gl::ImageIndex &index) const;
gl::Error updateStorageFaceLevel(int faceIndex, int level);
- void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height);
+ void redefineImage(int faceIndex, GLint level, GLenum internalformat, const gl::Extents &size);
ImageD3D *mImageArray[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
};
@@ -223,8 +238,8 @@ class TextureD3D_3D : public TextureD3D
TextureD3D_3D(RendererD3D *renderer);
virtual ~TextureD3D_3D();
- virtual Image *getImage(int level, int layer) const;
- virtual Image *getImage(const gl::ImageIndex &index) const;
+ virtual ImageD3D *getImage(int level, int layer) const;
+ virtual ImageD3D *getImage(const gl::ImageIndex &index) const;
virtual GLsizei getLayerCount(int level) const;
GLsizei getWidth(GLint level) const;
@@ -233,18 +248,27 @@ class TextureD3D_3D : public TextureD3D
GLenum getInternalFormat(GLint level) const;
bool isDepth(GLint level) const;
- virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+ gl::Error setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+
+ gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+ gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+
+ gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
+ const gl::Framebuffer *source) override;
+ gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source) override;
+
+ gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
virtual gl::ImageIndexIterator imageIterator() const;
@@ -252,8 +276,6 @@ class TextureD3D_3D : public TextureD3D
virtual bool isValidIndex(const gl::ImageIndex &index) const;
private:
- DISALLOW_COPY_AND_ASSIGN(TextureD3D_3D);
-
virtual gl::Error initializeStorage(bool renderTarget);
virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const;
virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
@@ -266,7 +288,7 @@ class TextureD3D_3D : public TextureD3D
virtual bool isImageComplete(const gl::ImageIndex &index) const;
gl::Error updateStorageLevel(int level);
- void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ void redefineImage(GLint level, GLenum internalformat, const gl::Extents &size);
ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
};
@@ -277,8 +299,8 @@ class TextureD3D_2DArray : public TextureD3D
TextureD3D_2DArray(RendererD3D *renderer);
virtual ~TextureD3D_2DArray();
- virtual Image *getImage(int level, int layer) const;
- virtual Image *getImage(const gl::ImageIndex &index) const;
+ virtual ImageD3D *getImage(int level, int layer) const;
+ virtual ImageD3D *getImage(const gl::ImageIndex &index) const;
virtual GLsizei getLayerCount(int level) const;
GLsizei getWidth(GLint level) const;
@@ -286,18 +308,27 @@ class TextureD3D_2DArray : public TextureD3D
GLenum getInternalFormat(GLint level) const;
bool isDepth(GLint level) const;
- virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels);
- virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
- virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+ gl::Error setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+
+ gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+ gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format,
+ const gl::PixelUnpackState &unpack, const uint8_t *pixels) override;
+
+ gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat,
+ const gl::Framebuffer *source) override;
+ gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source) override;
+
+ gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override;
virtual void bindTexImage(egl::Surface *surface);
virtual void releaseTexImage();
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
virtual gl::ImageIndexIterator imageIterator() const;
@@ -305,8 +336,6 @@ class TextureD3D_2DArray : public TextureD3D
virtual bool isValidIndex(const gl::ImageIndex &index) const;
private:
- DISALLOW_COPY_AND_ASSIGN(TextureD3D_2DArray);
-
virtual gl::Error initializeStorage(bool renderTarget);
virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const;
virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage);
@@ -320,7 +349,7 @@ class TextureD3D_2DArray : public TextureD3D
gl::Error updateStorageLevel(int level);
void deleteImages();
- void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ void redefineImage(GLint level, GLenum internalformat, const gl::Extents &size);
// 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
@@ -332,4 +361,4 @@ class TextureD3D_2DArray : public TextureD3D
}
-#endif // LIBGLESV2_RENDERER_TEXTURED3D_H_
+#endif // LIBANGLE_RENDERER_D3D_TEXTURED3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.cpp
index 320b74b8ed..abb83a14d5 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.cpp
@@ -6,12 +6,12 @@
// TextureStorage.cpp: Shared members of abstract rx::TextureStorage class.
-#include "libGLESv2/renderer/d3d/TextureStorage.h"
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
-#include "libGLESv2/renderer/RenderTarget.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/Texture.h"
+#include "libANGLE/renderer/d3d/TextureStorage.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Texture.h"
#include "common/debug.h"
#include "common/mathutil.h"
@@ -26,7 +26,7 @@ TextureStorage::TextureStorage()
void TextureStorage::initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride)
{
- mFirstRenderTargetSerial = RenderTarget::issueSerials(rtSerialsToReserve);
+ mFirstRenderTargetSerial = RenderTargetD3D::issueSerials(rtSerialsToReserve);
mRenderTargetSerialsLayerStride = rtSerialsLayerStride;
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.h
index da92be3c74..ae2d42ca8a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.h
@@ -6,16 +6,16 @@
// TextureStorage.h: Defines the abstract rx::TextureStorage class.
-#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
-#define LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
+#ifndef LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_
+#define LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
#include "common/debug.h"
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
#include <GLES2/gl2.h>
-#include <cstdint>
+#include <stdint.h>
namespace gl
{
@@ -26,11 +26,11 @@ struct PixelUnpackState;
namespace rx
{
-class SwapChain;
-class RenderTarget;
-class Image;
+class SwapChainD3D;
+class RenderTargetD3D;
+class ImageD3D;
-class TextureStorage
+class TextureStorage : angle::NonCopyable
{
public:
TextureStorage();
@@ -41,26 +41,27 @@ class TextureStorage
virtual bool isManaged() const = 0;
virtual int getLevelCount() const = 0;
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0;
virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0;
virtual gl::Error copyToStorage(TextureStorage *destStorage) = 0;
- virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData) = 0;
unsigned int getRenderTargetSerial(const gl::ImageIndex &index) const;
unsigned int getTextureSerial() const;
+ // This is a no-op for most implementations of TextureStorage. Some (e.g. TextureStorage11_2D) might override it.
+ virtual gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) { return gl::Error(GL_NO_ERROR); }
+
protected:
void initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride);
private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage);
-
unsigned int mFirstRenderTargetSerial;
unsigned int mRenderTargetSerialsLayerStride;
};
}
-#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
+#endif // LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp
index 11596006d0..5c0bfdcd5b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp
@@ -6,7 +6,7 @@
// TransformFeedbackD3D.cpp is a no-op implementation for both the D3D9 and D3D11 renderers.
-#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
+#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h"
namespace rx
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h
index 7c367aba1d..6b255b4a2b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h
@@ -6,11 +6,11 @@
// TransformFeedbackD3D.h: Implements the abstract rx::TransformFeedbackImpl class.
-#ifndef LIBGLESV2_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_
-#define LIBGLESV2_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_
+#ifndef LIBANGLE_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_
+#define LIBANGLE_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_
-#include "libGLESv2/renderer/TransformFeedbackImpl.h"
-#include "libGLESv2/angletypes.h"
+#include "libANGLE/renderer/TransformFeedbackImpl.h"
+#include "libANGLE/angletypes.h"
namespace rx
{
@@ -29,4 +29,4 @@ class TransformFeedbackD3D : public TransformFeedbackImpl
}
-#endif // LIBGLESV2_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_
+#endif // LIBANGLE_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp
index 73f0c79e19..19bd548fce 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp
@@ -7,10 +7,10 @@
// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface
// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
-#include "libGLESv2/renderer/d3d/VertexBuffer.h"
-#include "libGLESv2/renderer/d3d/BufferD3D.h"
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
-#include "libGLESv2/VertexAttribute.h"
+#include "libANGLE/renderer/d3d/VertexBuffer.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/VertexAttribute.h"
#include "common/mathutil.h"
@@ -38,13 +38,14 @@ unsigned int VertexBuffer::getSerial() const
return mSerial;
}
-VertexBufferInterface::VertexBufferInterface(RendererD3D *renderer, bool dynamic) : mRenderer(renderer)
+VertexBufferInterface::VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic)
+ : mFactory(factory)
{
mDynamic = dynamic;
mWritePosition = 0;
mReservedSpace = 0;
- mVertexBuffer = renderer->createVertexBuffer();
+ mVertexBuffer = factory->createVertexBuffer();
}
VertexBufferInterface::~VertexBufferInterface()
@@ -167,7 +168,7 @@ bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &att
const gl::VertexAttribCurrentValueData &currentValue) const
{
gl::Buffer *buffer = attrib.buffer.get();
- BufferD3D *storage = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL;
+ BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : NULL;
if (!storage || !storage->supportsDirectBinding())
{
@@ -188,7 +189,8 @@ bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &att
getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
alignment = std::min<size_t>(outputElementSize, 4);
- requiresConversion = (mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) != 0;
+ // TODO(jmadill): add VertexFormatCaps
+ requiresConversion = (mFactory->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) != 0;
}
bool isAligned = (static_cast<size_t>(ComputeVertexAttributeStride(attrib)) % alignment == 0) &&
@@ -197,7 +199,8 @@ bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &att
return !requiresConversion && isAligned;
}
-StreamingVertexBufferInterface::StreamingVertexBufferInterface(RendererD3D *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
+StreamingVertexBufferInterface::StreamingVertexBufferInterface(BufferFactoryD3D *factory, std::size_t initialSize)
+ : VertexBufferInterface(factory, true)
{
setBufferSize(initialSize);
}
@@ -231,7 +234,8 @@ gl::Error StreamingVertexBufferInterface::reserveSpace(unsigned int size)
return gl::Error(GL_NO_ERROR);
}
-StaticVertexBufferInterface::StaticVertexBufferInterface(RendererD3D *renderer) : VertexBufferInterface(renderer, false)
+StaticVertexBufferInterface::StaticVertexBufferInterface(BufferFactoryD3D *factory)
+ : VertexBufferInterface(factory, false)
{
}
@@ -293,7 +297,7 @@ gl::Error StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAtt
}
size_t attributeOffset = static_cast<size_t>(attrib.offset) % ComputeVertexAttributeStride(attrib);
- VertexElement element = { attrib.type, attrib.size, ComputeVertexAttributeStride(attrib), attrib.normalized, attrib.pureInteger, attributeOffset, streamOffset };
+ VertexElement element = { attrib.type, attrib.size, static_cast<GLuint>(ComputeVertexAttributeStride(attrib)), attrib.normalized, attrib.pureInteger, attributeOffset, streamOffset };
mCache.push_back(element);
if (outStreamOffset)
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.h
index 4b40818f8e..5cb03fe3a1 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.h
@@ -7,11 +7,11 @@
// VertexBuffer.h: Defines the abstract VertexBuffer class and VertexBufferInterface
// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
-#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER_H_
-#define LIBGLESV2_RENDERER_VERTEXBUFFER_H_
+#ifndef LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_
+#define LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_
#include "common/angleutils.h"
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
#include <GLES2/gl2.h>
@@ -26,9 +26,9 @@ struct VertexAttribCurrentValueData;
namespace rx
{
-class RendererD3D;
+class BufferFactoryD3D;
-class VertexBuffer
+class VertexBuffer : angle::NonCopyable
{
public:
VertexBuffer();
@@ -47,20 +47,21 @@ class VertexBuffer
unsigned int getSerial() const;
+ // This may be overridden (e.g. by VertexBuffer11) if necessary.
+ virtual void hintUnmapResource() { };
+
protected:
void updateSerial();
private:
- DISALLOW_COPY_AND_ASSIGN(VertexBuffer);
-
unsigned int mSerial;
static unsigned int mNextSerial;
};
-class VertexBufferInterface
+class VertexBufferInterface : angle::NonCopyable
{
public:
- VertexBufferInterface(RendererD3D *renderer, bool dynamic);
+ VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic);
virtual ~VertexBufferInterface();
gl::Error reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances);
@@ -88,9 +89,7 @@ class VertexBufferInterface
gl::Error setBufferSize(unsigned int size);
private:
- DISALLOW_COPY_AND_ASSIGN(VertexBufferInterface);
-
- RendererD3D *const mRenderer;
+ BufferFactoryD3D *const mFactory;
VertexBuffer* mVertexBuffer;
@@ -102,7 +101,7 @@ class VertexBufferInterface
class StreamingVertexBufferInterface : public VertexBufferInterface
{
public:
- StreamingVertexBufferInterface(RendererD3D *renderer, std::size_t initialSize);
+ StreamingVertexBufferInterface(BufferFactoryD3D *factory, std::size_t initialSize);
~StreamingVertexBufferInterface();
protected:
@@ -112,7 +111,7 @@ class StreamingVertexBufferInterface : public VertexBufferInterface
class StaticVertexBufferInterface : public VertexBufferInterface
{
public:
- explicit StaticVertexBufferInterface(RendererD3D *renderer);
+ explicit StaticVertexBufferInterface(BufferFactoryD3D *factory);
~StaticVertexBufferInterface();
gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
@@ -141,4 +140,4 @@ class StaticVertexBufferInterface : public VertexBufferInterface
}
-#endif // LIBGLESV2_RENDERER_VERTEXBUFFER_H_ \ No newline at end of file
+#endif // LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp
index 8d3df31c8b..cb70b9e4ef 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp
@@ -7,14 +7,15 @@
// VertexDataManager.h: Defines the VertexDataManager, a class that
// runs the Buffer translation process.
-#include "libGLESv2/renderer/d3d/VertexDataManager.h"
-#include "libGLESv2/renderer/d3d/BufferD3D.h"
-#include "libGLESv2/renderer/d3d/VertexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/State.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
+
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/State.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/VertexBuffer.h"
namespace
{
@@ -46,13 +47,16 @@ static int StreamingBufferElementCount(const gl::VertexAttribute &attrib, int ve
// non-instanced vertices, and the instanced vertex index advances once every "mDivisor" instances.
if (instanceDrawCount > 0 && attrib.divisor > 0)
{
- return instanceDrawCount / attrib.divisor;
+ // 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 (instanceDrawCount + attrib.divisor - 1) / attrib.divisor;
}
return vertexDrawCount;
}
-VertexDataManager::VertexDataManager(RendererD3D *renderer) : mRenderer(renderer)
+VertexDataManager::VertexDataManager(BufferFactoryD3D *factory)
+ : mFactory(factory)
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
@@ -65,7 +69,7 @@ VertexDataManager::VertexDataManager(RendererD3D *renderer) : mRenderer(renderer
mCurrentValueOffsets[i] = 0;
}
- mStreamingBuffer = new StreamingVertexBufferInterface(renderer, INITIAL_STREAM_BUFFER_SIZE);
+ mStreamingBuffer = new StreamingVertexBufferInterface(factory, INITIAL_STREAM_BUFFER_SIZE);
if (!mStreamingBuffer)
{
@@ -83,6 +87,35 @@ VertexDataManager::~VertexDataManager()
}
}
+void VertexDataManager::hintUnmapAllResources(const std::vector<gl::VertexAttribute> &vertexAttributes)
+{
+ mStreamingBuffer->getVertexBuffer()->hintUnmapResource();
+
+ for (size_t i = 0; i < vertexAttributes.size(); i++)
+ {
+ const gl::VertexAttribute &attrib = vertexAttributes[i];
+ if (attrib.enabled)
+ {
+ gl::Buffer *buffer = attrib.buffer.get();
+ BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : NULL;
+ StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL;
+
+ if (staticBuffer)
+ {
+ staticBuffer->getVertexBuffer()->hintUnmapResource();
+ }
+ }
+ }
+
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ if (mCurrentValueBuffer[i] != NULL)
+ {
+ mCurrentValueBuffer[i]->getVertexBuffer()->hintUnmapResource();
+ }
+ }
+}
+
gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint start, GLsizei count,
TranslatedAttribute *translated, GLsizei instances)
{
@@ -91,25 +124,25 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
return gl::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL.");
}
+ const gl::VertexArray *vertexArray = state.getVertexArray();
+ const std::vector<gl::VertexAttribute> &vertexAttributes = vertexArray->getVertexAttributes();
+
// Invalidate static buffers that don't contain matching attributes
for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
{
- translated[attributeIndex].active = (state.getCurrentProgramBinary()->getSemanticIndex(attributeIndex) != -1);
- const gl::VertexAttribute &curAttrib = state.getVertexAttribState(attributeIndex);
-
- if (translated[attributeIndex].active && curAttrib.enabled)
+ translated[attributeIndex].active = (state.getProgram()->getSemanticIndex(attributeIndex) != -1);
+ if (translated[attributeIndex].active && vertexAttributes[attributeIndex].enabled)
{
- invalidateMatchingStaticData(curAttrib, state.getVertexAttribCurrentValue(attributeIndex));
+ invalidateMatchingStaticData(vertexAttributes[attributeIndex], state.getVertexAttribCurrentValue(attributeIndex));
}
}
// Reserve the required space in the buffers
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
- const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i);
- if (translated[i].active && curAttrib.enabled)
+ if (translated[i].active && vertexAttributes[i].enabled)
{
- gl::Error error = reserveSpaceForAttrib(curAttrib, state.getVertexAttribCurrentValue(i), count, instances);
+ gl::Error error = reserveSpaceForAttrib(vertexAttributes[i], state.getVertexAttribCurrentValue(i), count, instances);
if (error.isError())
{
return error;
@@ -120,7 +153,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
// Perform the vertex data translations
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
- const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i);
+ const gl::VertexAttribute &curAttrib = vertexAttributes[i];
if (translated[i].active)
{
if (curAttrib.enabled)
@@ -130,6 +163,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
if (error.isError())
{
+ hintUnmapAllResources(vertexAttributes);
return error;
}
}
@@ -137,7 +171,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
{
if (!mCurrentValueBuffer[i])
{
- mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mRenderer, CONSTANT_VERTEX_BUFFER_SIZE);
+ mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE);
}
gl::Error error = storeCurrentValue(curAttrib, state.getVertexAttribCurrentValue(i), &translated[i],
@@ -145,22 +179,26 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint sta
mCurrentValueBuffer[i]);
if (error.isError())
{
+ hintUnmapAllResources(vertexAttributes);
return error;
}
}
}
}
+ // Hint to unmap all the resources
+ hintUnmapAllResources(vertexAttributes);
+
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
- const gl::VertexAttribute &curAttrib = state.getVertexAttribState(i);
+ const gl::VertexAttribute &curAttrib = vertexAttributes[i];
if (translated[i].active && curAttrib.enabled)
{
gl::Buffer *buffer = curAttrib.buffer.get();
if (buffer)
{
- BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation());
+ BufferD3D *bufferImpl = GetImplAs<BufferD3D>(buffer);
bufferImpl->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(curAttrib));
}
}
@@ -176,7 +214,7 @@ void VertexDataManager::invalidateMatchingStaticData(const gl::VertexAttribute &
if (buffer)
{
- BufferD3D *bufferImpl = BufferD3D::makeBufferD3D(buffer->getImplementation());
+ BufferD3D *bufferImpl = GetImplAs<BufferD3D>(buffer);
StaticVertexBufferInterface *staticBuffer = bufferImpl->getStaticVertexBuffer();
if (staticBuffer &&
@@ -195,7 +233,7 @@ gl::Error VertexDataManager::reserveSpaceForAttrib(const gl::VertexAttribute &at
GLsizei instances) const
{
gl::Buffer *buffer = attrib.buffer.get();
- BufferD3D *bufferImpl = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL;
+ BufferD3D *bufferImpl = buffer ? GetImplAs<BufferD3D>(buffer) : NULL;
StaticVertexBufferInterface *staticBuffer = bufferImpl ? bufferImpl->getStaticVertexBuffer() : NULL;
VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
@@ -239,7 +277,7 @@ gl::Error VertexDataManager::storeAttribute(const gl::VertexAttribute &attrib,
gl::Buffer *buffer = attrib.buffer.get();
ASSERT(buffer || attrib.pointer);
- BufferD3D *storage = buffer ? BufferD3D::makeBufferD3D(buffer->getImplementation()) : NULL;
+ BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : NULL;
StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL;
VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
bool directStorage = vertexBuffer->directStoragePossible(attrib, currentValue);
@@ -247,10 +285,13 @@ gl::Error VertexDataManager::storeAttribute(const gl::VertexAttribute &attrib,
unsigned int streamOffset = 0;
unsigned int outputElementSize = 0;
+ // Instanced vertices do not apply the 'start' offset
+ GLint firstVertexIndex = (instances > 0 && attrib.divisor > 0 ? 0 : start);
+
if (directStorage)
{
outputElementSize = ComputeVertexAttributeStride(attrib);
- streamOffset = attrib.offset + outputElementSize * start;
+ streamOffset = attrib.offset + outputElementSize * firstVertexIndex;
}
else if (staticBuffer)
{
@@ -266,8 +307,8 @@ gl::Error VertexDataManager::storeAttribute(const gl::VertexAttribute &attrib,
int totalCount = ElementsInBuffer(attrib, storage->getSize());
int startIndex = attrib.offset / ComputeVertexAttributeStride(attrib);
- gl::Error error = staticBuffer->storeVertexAttributes(attrib, currentValue, -startIndex, totalCount,
- 0, &streamOffset);
+ error = staticBuffer->storeVertexAttributes(attrib, currentValue, -startIndex, totalCount,
+ 0, &streamOffset);
if (error.isError())
{
return error;
@@ -275,7 +316,7 @@ gl::Error VertexDataManager::storeAttribute(const gl::VertexAttribute &attrib,
}
unsigned int firstElementOffset = (attrib.offset / ComputeVertexAttributeStride(attrib)) * outputElementSize;
- unsigned int startOffset = (instances == 0 || attrib.divisor == 0) ? start * outputElementSize : 0;
+ unsigned int startOffset = (instances == 0 || attrib.divisor == 0) ? firstVertexIndex * outputElementSize : 0;
if (streamOffset + firstElementOffset + startOffset < streamOffset)
{
return gl::Error(GL_OUT_OF_MEMORY);
@@ -292,7 +333,8 @@ gl::Error VertexDataManager::storeAttribute(const gl::VertexAttribute &attrib,
return error;
}
- error = mStreamingBuffer->storeVertexAttributes(attrib, currentValue, start, totalCount, instances, &streamOffset);
+ error = mStreamingBuffer->storeVertexAttributes(attrib, currentValue, firstVertexIndex,
+ totalCount, instances, &streamOffset);
if (error.isError())
{
return error;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.h
index 64ef653221..898ed340b8 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.h
@@ -7,16 +7,15 @@
// VertexDataManager.h: Defines the VertexDataManager, a class that
// runs the Buffer translation process.
-#ifndef LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_
-#define LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_
+#ifndef LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
+#define LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/VertexAttribute.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/VertexAttribute.h"
#include "common/angleutils.h"
namespace gl
{
-class ProgramBinary;
class State;
struct VertexAttribute;
struct VertexAttribCurrentValueData;
@@ -25,9 +24,9 @@ struct VertexAttribCurrentValueData;
namespace rx
{
class BufferD3D;
+class BufferFactoryD3D;
class StreamingVertexBufferInterface;
class VertexBuffer;
-class RendererD3D;
struct TranslatedAttribute
{
@@ -47,18 +46,16 @@ struct TranslatedAttribute
unsigned int divisor;
};
-class VertexDataManager
+class VertexDataManager : angle::NonCopyable
{
public:
- VertexDataManager(RendererD3D *renderer);
+ VertexDataManager(BufferFactoryD3D *factory);
virtual ~VertexDataManager();
gl::Error prepareVertexData(const gl::State &state, GLint start, GLsizei count,
TranslatedAttribute *outAttribs, GLsizei instances);
private:
- DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
-
gl::Error reserveSpaceForAttrib(const gl::VertexAttribute &attrib,
const gl::VertexAttribCurrentValueData &currentValue,
GLsizei count,
@@ -81,7 +78,9 @@ class VertexDataManager
size_t *cachedOffset,
StreamingVertexBufferInterface *buffer);
- RendererD3D *const mRenderer;
+ void hintUnmapAllResources(const std::vector<gl::VertexAttribute> &vertexAttributes);
+
+ BufferFactoryD3D *const mFactory;
StreamingVertexBufferInterface *mStreamingBuffer;
@@ -93,4 +92,4 @@ class VertexDataManager
}
-#endif // LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_
+#endif // LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.cpp
index aabc9f04e9..b1798454ca 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.cpp
@@ -6,7 +6,7 @@
// copyimage.cpp: Defines image copying functions
-#include "libGLESv2/renderer/copyimage.h"
+#include "libANGLE/renderer/d3d/copyimage.h"
namespace rx
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.h
index 513eb5cb3d..189654ca39 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.h
@@ -6,13 +6,13 @@
// copyimage.h: Defines image copying functions
-#ifndef LIBGLESV2_RENDERER_COPYIMAGE_H_
-#define LIBGLESV2_RENDERER_COPYIMAGE_H_
+#ifndef LIBANGLE_RENDERER_D3D_COPYIMAGE_H_
+#define LIBANGLE_RENDERER_D3D_COPYIMAGE_H_
#include "common/mathutil.h"
-#include "libGLESv2/angletypes.h"
+#include "libANGLE/angletypes.h"
-#include <cstdint>
+#include <stdint.h>
namespace rx
{
@@ -32,4 +32,4 @@ void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest);
#include "copyimage.inl"
-#endif // LIBGLESV2_RENDERER_COPYIMAGE_H_
+#endif // LIBANGLE_RENDERER_D3D_COPYIMAGE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.inl
index 0498cf7750..0498cf7750 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/copyimage.inl
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.inl
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
index 06aea9befe..e38b61709f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
@@ -6,56 +6,58 @@
// Blit11.cpp: Texture copy utility class.
-#include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/formatutils.h"
-
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2duips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2duips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2duips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2duips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2dips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum2dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2dps.h"
-
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3dvs.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3dgs.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3duips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3duips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3duips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3duips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3dips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum3dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3dps.h"
-
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h"
+#include "libANGLE/renderer/d3d/d3d11/Blit11.h"
+
+#include <float.h>
+
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/formatutils.h"
+
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.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/passthroughr2d11ps.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/passthroughlum2d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h"
+
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.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/passthroughrgb3d11ps.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/passthroughrg3d11ps.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/passthroughr3d11ps.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/passthroughlum3d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h"
+
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h"
namespace rx
{
@@ -209,7 +211,7 @@ Blit11::Blit11(Renderer11 *renderer)
pointSamplerDesc.BorderColor[2] = 0.0f;
pointSamplerDesc.BorderColor[3] = 0.0f;
pointSamplerDesc.MinLOD = 0.0f;
- pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f;
+ pointSamplerDesc.MaxLOD = FLT_MAX;
result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler);
ASSERT(SUCCEEDED(result));
@@ -228,7 +230,7 @@ Blit11::Blit11(Renderer11 *renderer)
linearSamplerDesc.BorderColor[2] = 0.0f;
linearSamplerDesc.BorderColor[3] = 0.0f;
linearSamplerDesc.MinLOD = 0.0f;
- linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f;
+ linearSamplerDesc.MaxLOD = FLT_MAX;
result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler);
ASSERT(SUCCEEDED(result));
@@ -290,7 +292,7 @@ Blit11::Blit11(Renderer11 *renderer)
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mQuad2DVS, "Blit11 2D vertex shader");
- if (!renderer->isLevel9())
+ if (renderer->isES3Capable())
{
result = device->CreatePixelShader(g_PS_PassthroughDepth2D, ArraySize(g_PS_PassthroughDepth2D), NULL, &mDepthPS);
ASSERT(SUCCEEDED(result));
@@ -524,7 +526,7 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s
BlitParameters parameters = { 0 };
parameters.mDestinationFormat = destFormat;
parameters.mSignedInteger = (internalFormatInfo.componentType == GL_INT);
- parameters.m3DBlit = sourceArea.depth > 1;
+ parameters.m3DBlit = sourceSRVDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D;
BlitShaderMap::const_iterator i = mBlitShaderMap.find(parameters);
if (i == mBlitShaderMap.end())
@@ -972,6 +974,7 @@ void Blit11::buildShaderMap()
{
ID3D11Device *device = mRenderer->getDevice();
+ // 2D shaders (OpenGL ES 2+)
add2DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader" ));
add2DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader" ));
add2DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader" ));
@@ -981,50 +984,59 @@ void Blit11::buildShaderMap()
add2DBlitShaderToMap(GL_LUMINANCE, false, d3d11::CompilePS(device, g_PS_PassthroughLum2D, "Blit11 2D lum pixel shader" ));
add2DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha2D, "Blit11 2D luminance alpha pixel shader"));
- addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader" ));
-
- if (mRenderer->isLevel9())
- return;
-
- add2DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI, "Blit11 2D RGBA UI pixel shader" ));
- add2DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader" ));
- add2DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader" ));
- add2DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader" ));
- add2DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader" ));
- add2DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader" ));
- add2DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader" ));
- add2DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader" ));
- add3DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader" ));
- add3DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader" ));
- add3DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader" ));
- add3DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader" ));
- add3DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader" ));
- add3DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader" ));
- add3DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader" ));
- add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" ));
- add3DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader" ));
- add3DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader" ));
- add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" ));
- add3DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader" ));
- add3DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader" ));
- add3DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader" ));
- add3DBlitShaderToMap(GL_LUMINANCE, false, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader" ));
- add3DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader"));
-
- addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleUI2D, "Blit11 2D UI swizzle pixel shader"));
- addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader" ));
-
- addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Cube F swizzle pixel shader" ));
- addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Cube UI swizzle pixel shader"));
- addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Cube I swizzle pixel shader" ));
-
- addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleF3D, "Blit11 3D F swizzle pixel shader" ));
- addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleUI3D, "Blit11 3D UI swizzle pixel shader"));
- addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleI3D, "Blit11 3D I swizzle pixel shader" ));
-
- addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Array F swizzle pixel shader" ));
- addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Array UI swizzle pixel shader"));
- addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Array I swizzle pixel shader" ));
+ // 2D shaders (OpenGL ES 3+)
+ if (mRenderer->isES3Capable())
+ {
+ add2DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI, "Blit11 2D RGBA UI pixel shader" ));
+ add2DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader" ));
+ add2DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader" ));
+ add2DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader" ));
+ add2DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader" ));
+ add2DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader" ));
+ add2DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader" ));
+ add2DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader" ));
+ }
+
+ // 3D shaders (OpenGL ES 3+)
+ if (mRenderer->isES3Capable())
+ {
+ add3DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader" ));
+ add3DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader" ));
+ add3DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader" ));
+ add3DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader" ));
+ add3DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader" ));
+ add3DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader" ));
+ add3DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader" ));
+ add3DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader" ));
+ add3DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader" ));
+ add3DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader" ));
+ add3DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader" ));
+ add3DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader" ));
+ add3DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader" ));
+ add3DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader" ));
+ add3DBlitShaderToMap(GL_LUMINANCE, false, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader" ));
+ add3DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader"));
+ }
+
+ // Swizzling shaders (OpenGL ES 3+)
+ if (mRenderer->isES3Capable())
+ {
+ addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader" ));
+ addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleUI2D, "Blit11 2D UI swizzle pixel shader"));
+ addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader" ));
+
+ addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Cube F swizzle pixel shader" ));
+ addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Cube UI swizzle pixel shader"));
+ addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURECUBE, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Cube I swizzle pixel shader" ));
+
+ addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleF3D, "Blit11 3D F swizzle pixel shader" ));
+ addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleUI3D, "Blit11 3D UI swizzle pixel shader"));
+ addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE3D, d3d11::CompilePS(device, g_PS_SwizzleI3D, "Blit11 3D I swizzle pixel shader" ));
+
+ addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Array F swizzle pixel shader" ));
+ addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Array UI swizzle pixel shader"));
+ addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE2DARRAY, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Array I swizzle pixel shader" ));
+ }
}
void Blit11::clearShaderMap()
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h
index 821fa9d0cc..d3a8c2c8a3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h
@@ -6,12 +6,12 @@
// Blit11.cpp: Texture copy utility class.
-#ifndef LIBGLESV2_BLIT11_H_
-#define LIBGLESV2_BLIT11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_
#include "common/angleutils.h"
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/Error.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Error.h"
#include <map>
@@ -19,7 +19,7 @@ namespace rx
{
class Renderer11;
-class Blit11
+class Blit11 : angle::NonCopyable
{
public:
explicit Blit11(Renderer11 *renderer);
@@ -114,10 +114,8 @@ class Blit11
ID3D11GeometryShader *mQuad3DGS;
ID3D11Buffer *mSwizzleCB;
-
- DISALLOW_COPY_AND_ASSIGN(Blit11);
};
}
-#endif // LIBGLESV2_BLIT11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
index 5aab37938f..d56b0ea7ad 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
@@ -6,10 +6,17 @@
// Buffer11.cpp Defines the Buffer11 class.
-#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+
+#include "common/MemoryBuffer.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+
+#if defined(ANGLE_MINGW32_COMPAT)
+typedef enum D3D11_MAP_FLAG {
+ D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000
+} D3D11_MAP_FLAG;
+#endif
namespace rx
{
@@ -67,32 +74,34 @@ D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access)
}
-// Each instance of Buffer11::BufferStorage11 is specialized for a class of D3D binding points
+// 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::BufferStorage11
+class Buffer11::BufferStorage : angle::NonCopyable
{
public:
- virtual ~BufferStorage11() {}
+ virtual ~BufferStorage() {}
DataRevision getDataRevision() const { return mRevision; }
BufferUsage getUsage() const { return mUsage; }
size_t getSize() const { return mBufferSize; }
- bool isMappable() const { return (mUsage == BUFFER_USAGE_STAGING || mUsage == BUFFER_USAGE_PIXEL_PACK); }
-
void setDataRevision(DataRevision rev) { mRevision = rev; }
- virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
+ virtual bool isMappable() const = 0;
+
+ virtual bool copyFromStorage(BufferStorage *source, size_t sourceOffset,
size_t size, size_t destOffset) = 0;
virtual gl::Error resize(size_t size, bool preserveData) = 0;
- virtual void *map(size_t offset, size_t length, GLbitfield access) = 0;
+ virtual uint8_t *map(size_t offset, size_t length, GLbitfield access) = 0;
virtual void unmap() = 0;
+ gl::Error setData(const uint8_t *data, size_t offset, size_t size);
+
protected:
- BufferStorage11(Renderer11 *renderer, BufferUsage usage);
+ BufferStorage(Renderer11 *renderer, BufferUsage usage);
Renderer11 *mRenderer;
DataRevision mRevision;
@@ -102,48 +111,49 @@ class Buffer11::BufferStorage11
// A native buffer storage represents an underlying D3D11 buffer for a particular
// type of storage.
-class Buffer11::NativeBuffer11 : public Buffer11::BufferStorage11
+class Buffer11::NativeStorage : public Buffer11::BufferStorage
{
public:
- NativeBuffer11(Renderer11 *renderer, BufferUsage usage);
- ~NativeBuffer11();
+ NativeStorage(Renderer11 *renderer, BufferUsage usage);
+ ~NativeStorage() override;
- ID3D11Buffer *getNativeBuffer() const { return mNativeBuffer; }
+ bool isMappable() const override { return mUsage == BUFFER_USAGE_STAGING; }
- virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
- size_t size, size_t destOffset);
- virtual gl::Error resize(size_t size, bool preserveData);
+ ID3D11Buffer *getNativeStorage() const { return mNativeStorage; }
- virtual void *map(size_t offset, size_t length, GLbitfield access);
- virtual void unmap();
+ bool copyFromStorage(BufferStorage *source, size_t sourceOffset,
+ size_t size, size_t destOffset) override;
+ gl::Error resize(size_t size, bool preserveData) override;
- gl::Error setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset);
+ uint8_t *map(size_t offset, size_t length, GLbitfield access) override;
+ void unmap() override;
private:
- ID3D11Buffer *mNativeBuffer;
-
static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize);
+
+ ID3D11Buffer *mNativeStorage;
};
// 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::PackStorage11 : public Buffer11::BufferStorage11
+class Buffer11::PackStorage : public Buffer11::BufferStorage
{
public:
- PackStorage11(Renderer11 *renderer);
- ~PackStorage11();
+ explicit PackStorage(Renderer11 *renderer);
+ ~PackStorage() override;
+
+ bool isMappable() const override { return true; }
- virtual bool copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
- size_t size, size_t destOffset);
- virtual gl::Error resize(size_t size, bool preserveData);
+ bool copyFromStorage(BufferStorage *source, size_t sourceOffset,
+ size_t size, size_t destOffset) override;
+ gl::Error resize(size_t size, bool preserveData) override;
- virtual void *map(size_t offset, size_t length, GLbitfield access);
- virtual void unmap();
+ uint8_t *map(size_t offset, size_t length, GLbitfield access) override;
+ void unmap() override;
gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params);
private:
-
gl::Error flushQueuedPackCommand();
ID3D11Texture2D *mStagingTexture;
@@ -155,14 +165,37 @@ class Buffer11::PackStorage11 : public Buffer11::BufferStorage11
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 isMappable() const override { return true; }
+
+ bool copyFromStorage(BufferStorage *source, size_t sourceOffset,
+ size_t size, size_t destOffset) override;
+ gl::Error resize(size_t size, bool preserveData) override;
+
+ uint8_t *map(size_t offset, size_t length, GLbitfield access) override;
+ void unmap() override;
+
+ MemoryBuffer *getSystemCopy() { return &mSystemCopy; }
+
+ protected:
+ MemoryBuffer mSystemCopy;
+};
Buffer11::Buffer11(Renderer11 *renderer)
- : BufferD3D(),
+ : BufferD3D(renderer),
mRenderer(renderer),
mSize(0),
mMappedStorage(NULL),
- mResolvedDataRevision(0),
- mReadUsageCount(0)
+ mReadUsageCount(0),
+ mHasSystemMemoryStorage(false)
{}
Buffer11::~Buffer11()
@@ -197,54 +230,34 @@ gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage)
gl::Error Buffer11::getData(const uint8_t **outData)
{
- NativeBuffer11 *stagingBuffer = getStagingBuffer();
+ SystemMemoryStorage *systemMemoryStorage = nullptr;
+ gl::Error error = getSystemMemoryStorage(&systemMemoryStorage);
- if (!stagingBuffer)
+ if (error.isError())
{
- // Out-of-memory
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to get internal staging buffer.");
+ *outData = nullptr;
+ return error;
}
- if (stagingBuffer->getDataRevision() > mResolvedDataRevision)
- {
- if (stagingBuffer->getSize() > mResolvedData.size())
- {
- if (!mResolvedData.resize(stagingBuffer->getSize()))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize data resolve buffer.");
- }
- }
-
- ID3D11DeviceContext *context = mRenderer->getDeviceContext();
-
- D3D11_MAPPED_SUBRESOURCE mappedResource;
- HRESULT result = context->Map(stagingBuffer->getNativeBuffer(), 0, D3D11_MAP_READ, 0, &mappedResource);
- if (FAILED(result))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer, result: 0x%X.", result);
- }
-
- memcpy(mResolvedData.data(), mappedResource.pData, stagingBuffer->getSize());
+ mReadUsageCount = 0;
- context->Unmap(stagingBuffer->getNativeBuffer(), 0);
+ ASSERT(systemMemoryStorage->getSize() >= mSize);
- mResolvedDataRevision = stagingBuffer->getDataRevision();
- }
+ *outData = systemMemoryStorage->getSystemCopy()->data();
+ return gl::Error(GL_NO_ERROR);
+}
- mReadUsageCount = 0;
+gl::Error Buffer11::getSystemMemoryStorage(SystemMemoryStorage **storageOut)
+{
+ BufferStorage *memStorageUntyped = getBufferStorage(BUFFER_USAGE_SYSTEM_MEMORY);
- // Only happens if we initialized the buffer with no data (NULL)
- if (mResolvedData.empty())
+ if (memStorageUntyped == nullptr)
{
- if (!mResolvedData.resize(mSize))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize data resolve buffer.");
- }
+ // TODO(jmadill): convert all to errors
+ return gl::Error(GL_OUT_OF_MEMORY);
}
- ASSERT(mResolvedData.size() >= mSize);
-
- *outData = mResolvedData.data();
+ *storageOut = GetAs<SystemMemoryStorage>(memStorageUntyped);
return gl::Error(GL_NO_ERROR);
}
@@ -254,32 +267,46 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset)
if (data && size > 0)
{
- NativeBuffer11 *stagingBuffer = getStagingBuffer();
+ // Use system memory storage for dynamic buffers.
- if (!stagingBuffer)
+ BufferStorage *writeBuffer = nullptr;
+ if (supportsDirectBinding())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer.");
+ writeBuffer = getStagingStorage();
+
+ if (!writeBuffer)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer.");
+ }
}
+ else
+ {
+ SystemMemoryStorage *systemMemoryStorage = nullptr;
+ gl::Error error = getSystemMemoryStorage(&systemMemoryStorage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ writeBuffer = systemMemoryStorage;
+ }
+
+ ASSERT(writeBuffer);
// Explicitly resize the staging buffer, preserving data if the new data will not
// completely fill the buffer
- if (stagingBuffer->getSize() < requiredSize)
+ if (writeBuffer->getSize() < requiredSize)
{
bool preserveData = (offset > 0);
- gl::Error error = stagingBuffer->resize(requiredSize, preserveData);
+ gl::Error error = writeBuffer->resize(requiredSize, preserveData);
if (error.isError())
{
return error;
}
}
- gl::Error error = stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset);
- if (error.isError())
- {
- return error;
- }
-
- stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1);
+ writeBuffer->setData(static_cast<const uint8_t *>(data), offset, size);
+ writeBuffer->setDataRevision(writeBuffer->getDataRevision() + 1);
}
mSize = std::max(mSize, requiredSize);
@@ -293,13 +320,13 @@ gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLint
Buffer11 *sourceBuffer = makeBuffer11(source);
ASSERT(sourceBuffer != NULL);
- BufferStorage11 *copyDest = getLatestBufferStorage();
+ BufferStorage *copyDest = getLatestBufferStorage();
if (!copyDest)
{
- copyDest = getStagingBuffer();
+ copyDest = getStagingStorage();
}
- BufferStorage11 *copySource = sourceBuffer->getLatestBufferStorage();
+ BufferStorage *copySource = sourceBuffer->getLatestBufferStorage();
if (!copySource || !copyDest)
{
@@ -310,11 +337,11 @@ gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLint
// pack buffer partner, because other native buffers can't be mapped
if (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable())
{
- copySource = sourceBuffer->getStagingBuffer();
+ copySource = sourceBuffer->getStagingStorage();
}
else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copyDest->isMappable())
{
- copyDest = getStagingBuffer();
+ copyDest = getStagingStorage();
}
// D3D11 does not allow overlapped copies until 11.1, and only if the
@@ -328,7 +355,7 @@ gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLint
}
else
{
- copySource = getStagingBuffer();
+ copySource = getStagingStorage();
}
}
@@ -345,7 +372,7 @@ gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid
{
ASSERT(!mMappedStorage);
- BufferStorage11 *latestStorage = getLatestBufferStorage();
+ BufferStorage *latestStorage = getLatestBufferStorage();
if (latestStorage &&
(latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
latestStorage->getUsage() == BUFFER_USAGE_STAGING))
@@ -357,7 +384,7 @@ gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid
{
// Fall back to using the staging buffer if the latest storage does
// not exist or is not CPU-accessible.
- mMappedStorage = getStagingBuffer();
+ mMappedStorage = getStagingStorage();
}
if (!mMappedStorage)
@@ -371,13 +398,13 @@ gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid
mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1);
}
- void *mappedBuffer = mMappedStorage->map(offset, length, access);
+ uint8_t *mappedBuffer = mMappedStorage->map(offset, length, access);
if (!mappedBuffer)
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer.");
}
- *mapPtr = mappedBuffer;
+ *mapPtr = static_cast<GLvoid *>(mappedBuffer);
return gl::Error(GL_NO_ERROR);
}
@@ -391,7 +418,7 @@ gl::Error Buffer11::unmap()
void Buffer11::markTransformFeedbackUsage()
{
- BufferStorage11 *transformFeedbackStorage = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
+ BufferStorage *transformFeedbackStorage = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
if (transformFeedbackStorage)
{
@@ -405,25 +432,25 @@ void Buffer11::markBufferUsage()
{
mReadUsageCount++;
+ // Free the system memory storage if we decide it isn't being used very often.
const unsigned int usageLimit = 5;
- if (mReadUsageCount > usageLimit && mResolvedData.size() > 0)
+ if (mReadUsageCount > usageLimit && mHasSystemMemoryStorage)
{
- mResolvedData.resize(0);
- mResolvedDataRevision = 0;
- }
-}
+ auto systemMemoryStorageIt = mBufferStorages.find(BUFFER_USAGE_SYSTEM_MEMORY);
+ ASSERT(systemMemoryStorageIt != mBufferStorages.end());
-RendererD3D* Buffer11::getRenderer()
-{
- return mRenderer;
+ SafeDelete(systemMemoryStorageIt->second);
+ mBufferStorages.erase(systemMemoryStorageIt);
+ mHasSystemMemoryStorage = false;
+ }
}
ID3D11Buffer *Buffer11::getBuffer(BufferUsage usage)
{
markBufferUsage();
- BufferStorage11 *bufferStorage = getBufferStorage(usage);
+ BufferStorage *bufferStorage = getBufferStorage(usage);
if (!bufferStorage)
{
@@ -431,14 +458,14 @@ ID3D11Buffer *Buffer11::getBuffer(BufferUsage usage)
return NULL;
}
- ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, bufferStorage));
+ ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, bufferStorage));
- return static_cast<NativeBuffer11*>(bufferStorage)->getNativeBuffer();
+ return static_cast<NativeStorage*>(bufferStorage)->getNativeStorage();
}
ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat)
{
- BufferStorage11 *storage = getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK);
+ BufferStorage *storage = getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK);
if (!storage)
{
@@ -446,8 +473,8 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat)
return NULL;
}
- ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, storage));
- ID3D11Buffer *buffer = static_cast<NativeBuffer11*>(storage)->getNativeBuffer();
+ ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, storage));
+ ID3D11Buffer *buffer = static_cast<NativeStorage*>(storage)->getNativeStorage();
auto bufferSRVIt = mBufferResourceViews.find(srvFormat);
@@ -486,9 +513,8 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat)
gl::Error Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams &params)
{
- PackStorage11 *packStorage = getPackStorage();
-
- BufferStorage11 *latestStorage = getLatestBufferStorage();
+ PackStorage *packStorage = getPackStorage();
+ BufferStorage *latestStorage = getLatestBufferStorage();
if (packStorage)
{
@@ -503,76 +529,84 @@ gl::Error Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource,
return gl::Error(GL_NO_ERROR);
}
-Buffer11::BufferStorage11 *Buffer11::getBufferStorage(BufferUsage usage)
+Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage)
{
- BufferStorage11 *directBuffer = NULL;
+ BufferStorage *newStorage = NULL;
auto directBufferIt = mBufferStorages.find(usage);
if (directBufferIt != mBufferStorages.end())
{
- directBuffer = directBufferIt->second;
+ newStorage = directBufferIt->second;
}
- if (!directBuffer)
+ if (!newStorage)
{
if (usage == BUFFER_USAGE_PIXEL_PACK)
{
- directBuffer = new PackStorage11(mRenderer);
+ newStorage = new PackStorage(mRenderer);
+ }
+ else if (usage == BUFFER_USAGE_SYSTEM_MEMORY)
+ {
+ newStorage = new SystemMemoryStorage(mRenderer);
+ mHasSystemMemoryStorage = true;
}
else
{
// buffer is not allocated, create it
- directBuffer = new NativeBuffer11(mRenderer, usage);
+ newStorage = new NativeStorage(mRenderer, usage);
}
- mBufferStorages.insert(std::make_pair(usage, directBuffer));
+ mBufferStorages.insert(std::make_pair(usage, newStorage));
}
// resize buffer
- if (directBuffer->getSize() < mSize)
+ if (newStorage->getSize() < mSize)
{
- if (directBuffer->resize(mSize, true).isError())
+ if (newStorage->resize(mSize, true).isError())
{
// Out of memory error
return NULL;
}
}
- BufferStorage11 *latestBuffer = getLatestBufferStorage();
- if (latestBuffer && latestBuffer->getDataRevision() > directBuffer->getDataRevision())
+ BufferStorage *latestBuffer = getLatestBufferStorage();
+ if (latestBuffer && latestBuffer->getDataRevision() > newStorage->getDataRevision())
{
- // if copying from a pack buffer to a non-staging native buffer, we must first
- // copy through the staging buffer, because other native buffers can't be mapped
- if (latestBuffer->getUsage() == BUFFER_USAGE_PIXEL_PACK && !directBuffer->isMappable())
+ // 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 &&
+ newStorage->getUsage() != BUFFER_USAGE_STAGING &&
+ (!latestBuffer->isMappable() || !newStorage->isMappable()))
{
- NativeBuffer11 *stagingBuffer = getStagingBuffer();
+ NativeStorage *stagingBuffer = getStagingStorage();
stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0);
- directBuffer->setDataRevision(latestBuffer->getDataRevision());
+ stagingBuffer->setDataRevision(latestBuffer->getDataRevision());
latestBuffer = stagingBuffer;
}
// if copyFromStorage returns true, the D3D buffer has been recreated
// and we should update our serial
- if (directBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0))
+ if (newStorage->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0))
{
updateSerial();
}
- directBuffer->setDataRevision(latestBuffer->getDataRevision());
+ newStorage->setDataRevision(latestBuffer->getDataRevision());
}
- return directBuffer;
+ return newStorage;
}
-Buffer11::BufferStorage11 *Buffer11::getLatestBufferStorage() const
+Buffer11::BufferStorage *Buffer11::getLatestBufferStorage() const
{
// Even though we iterate over all the direct buffers, it is expected that only
// 1 or 2 will be present.
- BufferStorage11 *latestStorage = NULL;
+ BufferStorage *latestStorage = NULL;
DataRevision latestRevision = 0;
for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++)
{
- BufferStorage11 *storage = it->second;
+ BufferStorage *storage = it->second;
if (!latestStorage || storage->getDataRevision() > latestRevision)
{
latestStorage = storage;
@@ -580,12 +614,22 @@ Buffer11::BufferStorage11 *Buffer11::getLatestBufferStorage() const
}
}
+ // resize buffer
+ if (latestStorage && latestStorage->getSize() < mSize)
+ {
+ if (latestStorage->resize(mSize, true).isError())
+ {
+ // Out of memory error
+ return NULL;
+ }
+ }
+
return latestStorage;
}
-Buffer11::NativeBuffer11 *Buffer11::getStagingBuffer()
+Buffer11::NativeStorage *Buffer11::getStagingStorage()
{
- BufferStorage11 *stagingStorage = getBufferStorage(BUFFER_USAGE_STAGING);
+ BufferStorage *stagingStorage = getBufferStorage(BUFFER_USAGE_STAGING);
if (!stagingStorage)
{
@@ -593,13 +637,13 @@ Buffer11::NativeBuffer11 *Buffer11::getStagingBuffer()
return NULL;
}
- ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, stagingStorage));
- return static_cast<NativeBuffer11*>(stagingStorage);
+ ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, stagingStorage));
+ return static_cast<NativeStorage*>(stagingStorage);
}
-Buffer11::PackStorage11 *Buffer11::getPackStorage()
+Buffer11::PackStorage *Buffer11::getPackStorage()
{
- BufferStorage11 *packStorage = getBufferStorage(BUFFER_USAGE_PIXEL_PACK);
+ BufferStorage *packStorage = getBufferStorage(BUFFER_USAGE_PIXEL_PACK);
if (!packStorage)
{
@@ -607,8 +651,8 @@ Buffer11::PackStorage11 *Buffer11::getPackStorage()
return NULL;
}
- ASSERT(HAS_DYNAMIC_TYPE(PackStorage11*, packStorage));
- return static_cast<PackStorage11*>(packStorage);
+ ASSERT(HAS_DYNAMIC_TYPE(PackStorage*, packStorage));
+ return static_cast<PackStorage*>(packStorage);
}
bool Buffer11::supportsDirectBinding() const
@@ -619,7 +663,7 @@ bool Buffer11::supportsDirectBinding() const
return (mStaticVertexBuffer && mStaticIndexBuffer);
}
-Buffer11::BufferStorage11::BufferStorage11(Renderer11 *renderer, BufferUsage usage)
+Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage)
: mRenderer(renderer),
mUsage(usage),
mRevision(0),
@@ -627,25 +671,42 @@ Buffer11::BufferStorage11::BufferStorage11(Renderer11 *renderer, BufferUsage usa
{
}
-Buffer11::NativeBuffer11::NativeBuffer11(Renderer11 *renderer, BufferUsage usage)
- : BufferStorage11(renderer, usage),
- mNativeBuffer(NULL)
+gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, size_t size)
+{
+ ASSERT(isMappable());
+
+ uint8_t *writePointer = map(offset, size, GL_MAP_WRITE_BIT);
+ if (!writePointer)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer.");
+ }
+
+ memcpy(writePointer, data, size);
+
+ unmap();
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer, BufferUsage usage)
+ : BufferStorage(renderer, usage),
+ mNativeStorage(NULL)
{
}
-Buffer11::NativeBuffer11::~NativeBuffer11()
+Buffer11::NativeStorage::~NativeStorage()
{
- SafeRelease(mNativeBuffer);
+ SafeRelease(mNativeStorage);
}
// Returns true if it recreates the direct buffer
-bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
+bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, size_t sourceOffset,
size_t size, size_t destOffset)
{
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
size_t requiredSize = sourceOffset + size;
- bool createBuffer = !mNativeBuffer || mBufferSize < requiredSize;
+ bool createBuffer = !mNativeStorage || mBufferSize < requiredSize;
// (Re)initialize D3D buffer if needed
if (createBuffer)
@@ -654,29 +715,30 @@ bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t s
resize(source->getSize(), preserveData);
}
- if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK)
+ if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
+ source->getUsage() == BUFFER_USAGE_SYSTEM_MEMORY)
{
- ASSERT(HAS_DYNAMIC_TYPE(PackStorage11*, source));
+ ASSERT(source->isMappable());
- void *sourcePointer = source->map(sourceOffset, size, GL_MAP_READ_BIT);
+ uint8_t *sourcePointer = source->map(sourceOffset, size, GL_MAP_READ_BIT);
D3D11_MAPPED_SUBRESOURCE mappedResource;
- HRESULT hr = context->Map(mNativeBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource);
+ HRESULT hr = context->Map(mNativeStorage, 0, D3D11_MAP_WRITE, 0, &mappedResource);
UNUSED_ASSERTION_VARIABLE(hr);
ASSERT(SUCCEEDED(hr));
- unsigned char *destPointer = static_cast<unsigned char *>(mappedResource.pData) + destOffset;
+ uint8_t *destPointer = static_cast<uint8_t *>(mappedResource.pData) + destOffset;
// Offset bounds are validated at the API layer
ASSERT(sourceOffset + size <= destOffset + mBufferSize);
memcpy(destPointer, sourcePointer, size);
- context->Unmap(mNativeBuffer, 0);
+ context->Unmap(mNativeStorage, 0);
source->unmap();
}
else
{
- ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, source));
+ ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, source));
D3D11_BOX srcBox;
srcBox.left = sourceOffset;
@@ -686,16 +748,16 @@ bool Buffer11::NativeBuffer11::copyFromStorage(BufferStorage11 *source, size_t s
srcBox.front = 0;
srcBox.back = 1;
- ASSERT(HAS_DYNAMIC_TYPE(NativeBuffer11*, source));
- ID3D11Buffer *sourceBuffer = static_cast<NativeBuffer11*>(source)->getNativeBuffer();
+ ASSERT(HAS_DYNAMIC_TYPE(NativeStorage*, source));
+ ID3D11Buffer *sourceBuffer = static_cast<NativeStorage*>(source)->getNativeStorage();
- context->CopySubresourceRegion(mNativeBuffer, 0, destOffset, 0, 0, sourceBuffer, 0, &srcBox);
+ context->CopySubresourceRegion(mNativeStorage, 0, destOffset, 0, 0, sourceBuffer, 0, &srcBox);
}
return createBuffer;
}
-gl::Error Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
+gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData)
{
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
@@ -711,7 +773,7 @@ gl::Error Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer, result: 0x%X.", result);
}
- if (mNativeBuffer && preserveData)
+ if (mNativeStorage && preserveData)
{
// We don't call resize if the buffer is big enough already.
ASSERT(mBufferSize <= size);
@@ -724,19 +786,19 @@ gl::Error Buffer11::NativeBuffer11::resize(size_t size, bool preserveData)
srcBox.front = 0;
srcBox.back = 1;
- context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mNativeBuffer, 0, &srcBox);
+ context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mNativeStorage, 0, &srcBox);
}
// No longer need the old buffer
- SafeRelease(mNativeBuffer);
- mNativeBuffer = newBuffer;
+ SafeRelease(mNativeStorage);
+ mNativeStorage = newBuffer;
mBufferSize = bufferDesc.ByteWidth;
return gl::Error(GL_NO_ERROR);
}
-void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer,
+void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer,
BufferUsage usage, unsigned int bufferSize)
{
bufferDesc->ByteWidth = bufferSize;
@@ -754,8 +816,12 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren
case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
bufferDesc->Usage = D3D11_USAGE_DEFAULT;
bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER;
- if (!renderer->isLevel9())
+
+ if (renderer->isES3Capable())
+ {
bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT;
+ }
+
bufferDesc->CPUAccessFlags = 0;
break;
@@ -782,12 +848,12 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren
bufferDesc->ByteWidth = std::min<UINT>(bufferDesc->ByteWidth, renderer->getRendererCaps().maxUniformBlockSize);
break;
- default:
+ default:
UNREACHABLE();
}
}
-void *Buffer11::NativeBuffer11::map(size_t offset, size_t length, GLbitfield access)
+uint8_t *Buffer11::NativeStorage::map(size_t offset, size_t length, GLbitfield access)
{
ASSERT(mUsage == BUFFER_USAGE_STAGING);
@@ -796,41 +862,22 @@ void *Buffer11::NativeBuffer11::map(size_t offset, size_t length, GLbitfield acc
D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(access);
UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0);
- HRESULT result = context->Map(mNativeBuffer, 0, d3dMapType, d3dMapFlag, &mappedResource);
+ HRESULT result = context->Map(mNativeStorage, 0, d3dMapType, d3dMapFlag, &mappedResource);
UNUSED_ASSERTION_VARIABLE(result);
ASSERT(SUCCEEDED(result));
- return static_cast<GLubyte*>(mappedResource.pData) + offset;
+ return static_cast<uint8_t*>(mappedResource.pData) + offset;
}
-gl::Error Buffer11::NativeBuffer11::setData(D3D11_MAP mapMode, const uint8_t *data, size_t size, size_t offset)
-{
- ID3D11DeviceContext *context = mRenderer->getDeviceContext();
-
- D3D11_MAPPED_SUBRESOURCE mappedResource;
- HRESULT result = context->Map(mNativeBuffer, 0, mapMode, 0, &mappedResource);
- if (FAILED(result))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer, result: 0x%X.", result);
- }
-
- uint8_t *offsetBufferPointer = reinterpret_cast<uint8_t *>(mappedResource.pData) + offset;
- memcpy(offsetBufferPointer, data, size);
-
- context->Unmap(mNativeBuffer, 0);
-
- return gl::Error(GL_NO_ERROR);
-}
-
-void Buffer11::NativeBuffer11::unmap()
+void Buffer11::NativeStorage::unmap()
{
ASSERT(mUsage == BUFFER_USAGE_STAGING);
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
- context->Unmap(mNativeBuffer, 0);
+ context->Unmap(mNativeStorage, 0);
}
-Buffer11::PackStorage11::PackStorage11(Renderer11 *renderer)
- : BufferStorage11(renderer, BUFFER_USAGE_PIXEL_PACK),
+Buffer11::PackStorage::PackStorage(Renderer11 *renderer)
+ : BufferStorage(renderer, BUFFER_USAGE_PIXEL_PACK),
mStagingTexture(NULL),
mTextureFormat(DXGI_FORMAT_UNKNOWN),
mQueuedPackCommand(NULL),
@@ -838,13 +885,13 @@ Buffer11::PackStorage11::PackStorage11(Renderer11 *renderer)
{
}
-Buffer11::PackStorage11::~PackStorage11()
+Buffer11::PackStorage::~PackStorage()
{
SafeRelease(mStagingTexture);
SafeDelete(mQueuedPackCommand);
}
-bool Buffer11::PackStorage11::copyFromStorage(BufferStorage11 *source, size_t sourceOffset,
+bool Buffer11::PackStorage::copyFromStorage(BufferStorage *source, size_t sourceOffset,
size_t size, size_t destOffset)
{
// We copy through a staging buffer when drawing with a pack buffer,
@@ -853,7 +900,7 @@ bool Buffer11::PackStorage11::copyFromStorage(BufferStorage11 *source, size_t so
return false;
}
-gl::Error Buffer11::PackStorage11::resize(size_t size, bool preserveData)
+gl::Error Buffer11::PackStorage::resize(size_t size, bool preserveData)
{
if (size != mBufferSize)
{
@@ -867,7 +914,7 @@ gl::Error Buffer11::PackStorage11::resize(size_t size, bool preserveData)
return gl::Error(GL_NO_ERROR);
}
-void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield access)
+uint8_t *Buffer11::PackStorage::map(size_t offset, size_t length, GLbitfield access)
{
ASSERT(offset + length <= getSize());
// TODO: fast path
@@ -886,12 +933,12 @@ void *Buffer11::PackStorage11::map(size_t offset, size_t length, GLbitfield acce
return mMemoryBuffer.data() + offset;
}
-void Buffer11::PackStorage11::unmap()
+void Buffer11::PackStorage::unmap()
{
// No-op
}
-gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
+gl::Error Buffer11::PackStorage::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams &params)
{
gl::Error error = flushQueuedPackCommand();
if (error.isError())
@@ -963,7 +1010,7 @@ gl::Error Buffer11::PackStorage11::packPixels(ID3D11Texture2D *srcTexure, UINT s
return gl::Error(GL_NO_ERROR);
}
-gl::Error Buffer11::PackStorage11::flushQueuedPackCommand()
+gl::Error Buffer11::PackStorage::flushQueuedPackCommand()
{
ASSERT(mMemoryBuffer.size() > 0);
@@ -980,4 +1027,44 @@ gl::Error Buffer11::PackStorage11::flushQueuedPackCommand()
return gl::Error(GL_NO_ERROR);
}
+Buffer11::SystemMemoryStorage::SystemMemoryStorage(Renderer11 *renderer)
+ : Buffer11::BufferStorage(renderer, BUFFER_USAGE_SYSTEM_MEMORY)
+{}
+
+bool Buffer11::SystemMemoryStorage::copyFromStorage(BufferStorage *source, size_t sourceOffset,
+ size_t size, size_t destOffset)
+{
+ ASSERT(source->isMappable());
+ const uint8_t *sourceData = source->map(sourceOffset, size, GL_MAP_READ_BIT);
+ ASSERT(destOffset + size <= mSystemCopy.size());
+ memcpy(mSystemCopy.data() + destOffset, sourceData, size);
+ source->unmap();
+ return true;
+}
+
+gl::Error Buffer11::SystemMemoryStorage::resize(size_t size, bool preserveData)
+{
+ if (mSystemCopy.size() < size)
+ {
+ if (!mSystemCopy.resize(size))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize SystemMemoryStorage");
+ }
+ mBufferSize = size;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+uint8_t *Buffer11::SystemMemoryStorage::map(size_t offset, size_t length, GLbitfield access)
+{
+ ASSERT(!mSystemCopy.empty() && offset + length <= mSystemCopy.size());
+ return mSystemCopy.data() + offset;
+}
+
+void Buffer11::SystemMemoryStorage::unmap()
+{
+ // No-op
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
index 1c06bbf88a..39bafe880e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
@@ -6,12 +6,11 @@
// Buffer11.h: Defines the rx::Buffer11 class which implements rx::BufferImpl via rx::BufferD3D.
-#ifndef LIBGLESV2_RENDERER_BUFFER11_H_
-#define LIBGLESV2_RENDERER_BUFFER11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
-#include "libGLESv2/renderer/d3d/BufferD3D.h"
-#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
-#include "libGLESv2/angletypes.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
namespace rx
{
@@ -25,6 +24,7 @@ enum BufferUsage
BUFFER_USAGE_PIXEL_UNPACK,
BUFFER_USAGE_PIXEL_PACK,
BUFFER_USAGE_UNIFORM,
+ BUFFER_USAGE_SYSTEM_MEMORY,
};
struct PackPixelsParams
@@ -60,7 +60,6 @@ class Buffer11 : public BufferD3D
// BufferD3D implementation
virtual size_t getSize() const { return mSize; }
virtual bool supportsDirectBinding() const;
- RendererD3D *getRenderer() override;
// BufferImpl implementation
virtual gl::Error setData(const void* data, size_t size, GLenum usage);
@@ -72,34 +71,33 @@ class Buffer11 : public BufferD3D
virtual void markTransformFeedbackUsage();
private:
- DISALLOW_COPY_AND_ASSIGN(Buffer11);
-
- class BufferStorage11;
- class NativeBuffer11;
- class PackStorage11;
+ class BufferStorage;
+ class NativeStorage;
+ class PackStorage;
+ class SystemMemoryStorage;
Renderer11 *mRenderer;
size_t mSize;
- BufferStorage11 *mMappedStorage;
+ BufferStorage *mMappedStorage;
- std::map<BufferUsage, BufferStorage11*> mBufferStorages;
+ std::map<BufferUsage, BufferStorage*> mBufferStorages;
typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair;
std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews;
- MemoryBuffer mResolvedData;
- DataRevision mResolvedDataRevision;
unsigned int mReadUsageCount;
+ bool mHasSystemMemoryStorage;
void markBufferUsage();
- NativeBuffer11 *getStagingBuffer();
- PackStorage11 *getPackStorage();
+ NativeStorage *getStagingStorage();
+ PackStorage *getPackStorage();
+ gl::Error getSystemMemoryStorage(SystemMemoryStorage **storageOut);
- BufferStorage11 *getBufferStorage(BufferUsage usage);
- BufferStorage11 *getLatestBufferStorage() const;
+ BufferStorage *getBufferStorage(BufferUsage usage);
+ BufferStorage *getLatestBufferStorage() const;
};
}
-#endif // LIBGLESV2_RENDERER_BUFFER11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
index 7185a05506..057c3bed42 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
@@ -6,23 +6,28 @@
// Clear11.cpp: Framebuffer clear utility class.
-#include "libGLESv2/renderer/d3d/d3d11/Clear11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
+#include "libANGLE/renderer/d3d/d3d11/Clear11.h"
+
+#include <algorithm>
+
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
// Precompiled shaders
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloatvs.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloatps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuintvs.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuintps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsintvs.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsintps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h"
namespace rx
{
@@ -80,7 +85,7 @@ Clear11::ClearShader Clear11::CreateClearShader(ID3D11Device *device, DXGI_FORMA
Clear11::Clear11(Renderer11 *renderer)
: mRenderer(renderer), mClearBlendStates(StructLessThan<ClearBlendInfo>), mClearDepthStencilStates(StructLessThan<ClearDepthStencilInfo>),
- mVertexBuffer(NULL), mRasterizerState(NULL)
+ mVertexBuffer(NULL), mRasterizerState(NULL), mSupportsClearView(false)
{
HRESULT result;
ID3D11Device *device = renderer->getDevice();
@@ -104,7 +109,7 @@ Clear11::Clear11(Renderer11 *renderer)
rsDesc.DepthBias = 0;
rsDesc.DepthBiasClamp = 0.0f;
rsDesc.SlopeScaledDepthBias = 0.0f;
- rsDesc.DepthClipEnable = renderer->isLevel9();
+ rsDesc.DepthClipEnable = TRUE;
rsDesc.ScissorEnable = FALSE;
rsDesc.MultisampleEnable = FALSE;
rsDesc.AntialiasedLineEnable = FALSE;
@@ -113,14 +118,29 @@ Clear11::Clear11(Renderer11 *renderer)
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mRasterizerState, "Clear11 masked clear rasterizer state");
- mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat);
- if (mRenderer->isLevel9()) {
- memset(&mUintClearShader, 0, sizeof(ClearShader));
- memset(&mIntClearShader, 0, sizeof(ClearShader));
- return;
+ if (renderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3)
+ {
+ mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat_FL9);
+ }
+ else
+ {
+ mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat);
+ }
+
+ if (renderer->isES3Capable())
+ {
+ mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint );
+ mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint );
+ }
+
+#if defined(ANGLE_ENABLE_D3D11_1)
+ if (renderer->getDeviceContext1IfSupported())
+ {
+ D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options;
+ device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
+ mSupportsClearView = (d3d11Options.ClearView != FALSE);
}
- mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint );
- mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint );
+#endif
}
Clear11::~Clear11()
@@ -135,13 +155,16 @@ Clear11::~Clear11()
SafeRelease(mFloatClearShader.vertexShader);
SafeRelease(mFloatClearShader.pixelShader);
- SafeRelease(mUintClearShader.inputLayout);
- SafeRelease(mUintClearShader.vertexShader);
- SafeRelease(mUintClearShader.pixelShader);
+ if (mRenderer->isES3Capable())
+ {
+ SafeRelease(mUintClearShader.inputLayout);
+ SafeRelease(mUintClearShader.vertexShader);
+ SafeRelease(mUintClearShader.pixelShader);
- SafeRelease(mIntClearShader.inputLayout);
- SafeRelease(mIntClearShader.vertexShader);
- SafeRelease(mIntClearShader.pixelShader);
+ SafeRelease(mIntClearShader.inputLayout);
+ SafeRelease(mIntClearShader.vertexShader);
+ SafeRelease(mIntClearShader.pixelShader);
+ }
for (ClearDepthStencilStateMap::iterator i = mClearDepthStencilStates.begin(); i != mClearDepthStencilStates.end(); i++)
{
@@ -153,17 +176,28 @@ Clear11::~Clear11()
SafeRelease(mRasterizerState);
}
-gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer)
+gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl::Framebuffer::Data &fboData)
{
- // First determine if a scissored clear is needed, this will always require drawing a quad.
- //
- // Otherwise, iterate over the color buffers which require clearing and determine if they can be
- // cleared with ID3D11DeviceContext::ClearRenderTargetView... This requires:
+ const auto &colorAttachments = fboData.mColorAttachments;
+ const auto &drawBufferStates = fboData.mDrawBufferStates;
+ const auto *depthAttachment = fboData.mDepthAttachment;
+ const auto *stencilAttachment = fboData.mStencilAttachment;
+
+ ASSERT(colorAttachments.size() == drawBufferStates.size());
+
+ // 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 draw a quad.
+ //
// Also determine if the depth stencil can be cleared with ID3D11DeviceContext::ClearDepthStencilView
// by checking if the stencil write mask covers the entire stencil.
//
@@ -171,18 +205,24 @@ gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, cons
// attribute.
gl::Extents framebufferSize;
- if (frameBuffer->getFirstColorbuffer() != NULL)
+
+ auto iter = std::find_if(colorAttachments.begin(), colorAttachments.end(), [](const gl::FramebufferAttachment *attachment) { return attachment != nullptr; });
+ if (iter != colorAttachments.end())
+ {
+ framebufferSize.width = (*iter)->getWidth();
+ framebufferSize.height = (*iter)->getHeight();
+ framebufferSize.depth = 1;
+ }
+ else if (depthAttachment != nullptr)
{
- gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer();
- framebufferSize.width = attachment->getWidth();
- framebufferSize.height = attachment->getHeight();
+ framebufferSize.width = depthAttachment->getWidth();
+ framebufferSize.height = depthAttachment->getHeight();
framebufferSize.depth = 1;
}
- else if (frameBuffer->getDepthOrStencilbuffer() != NULL)
+ else if (stencilAttachment != nullptr)
{
- gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer();
- framebufferSize.width = attachment->getWidth();
- framebufferSize.height = attachment->getHeight();
+ framebufferSize.width = stencilAttachment->getWidth();
+ framebufferSize.height = stencilAttachment->getHeight();
framebufferSize.depth = 1;
}
else
@@ -208,77 +248,96 @@ gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, cons
RenderTarget11* maskedClearDepthStencil = NULL;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
- for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+ for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++)
{
- if (clearParams.clearColor[colorAttachment] && frameBuffer->isEnabledColorAttachment(colorAttachment))
+ if (clearParams.clearColor[colorAttachment] &&
+ colorAttachments[colorAttachment] != nullptr &&
+ drawBufferStates[colorAttachment] != GL_NONE)
{
- gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(colorAttachment);
- if (attachment)
+ const gl::FramebufferAttachment *attachment = colorAttachments[colorAttachment];
+
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
{
- RenderTarget11 *renderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
- if (error.isError())
- {
- return error;
- }
+ return error;
+ }
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
- if (clearParams.colorClearType == GL_FLOAT &&
- !(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.componentType == GL_SIGNED_NORMALIZED))
+ if (clearParams.colorClearType == GL_FLOAT &&
+ !(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.componentType == GL_SIGNED_NORMALIZED))
+ {
+ ERR("It is undefined behaviour to clear a render buffer which is not normalized fixed point or floating-"
+ "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment,
+ attachment->getInternalFormat());
+ }
+
+ if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) &&
+ (formatInfo.greenBits == 0 || !clearParams.colorMaskGreen) &&
+ (formatInfo.blueBits == 0 || !clearParams.colorMaskBlue) &&
+ (formatInfo.alphaBits == 0 || !clearParams.colorMaskAlpha))
+ {
+ // Every channel either does not exist in the render target or is masked out
+ continue;
+ }
+ else if ((!mSupportsClearView && needScissoredClear) || clearParams.colorClearType != GL_FLOAT ||
+ (formatInfo.redBits > 0 && !clearParams.colorMaskRed) ||
+ (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) ||
+ (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) ||
+ (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha))
+ {
+ // A masked clear is required, or a scissored clear is required and ID3D11DeviceContext1::ClearView is unavailable
+ MaskedRenderTarget maskAndRt;
+ bool clearColor = clearParams.clearColor[colorAttachment];
+ maskAndRt.colorMask[0] = (clearColor && clearParams.colorMaskRed);
+ maskAndRt.colorMask[1] = (clearColor && clearParams.colorMaskGreen);
+ maskAndRt.colorMask[2] = (clearColor && clearParams.colorMaskBlue);
+ maskAndRt.colorMask[3] = (clearColor && clearParams.colorMaskAlpha);
+ maskAndRt.renderTarget = renderTarget;
+ maskedClearRenderTargets.push_back(maskAndRt);
+ }
+ else
+ {
+ // ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView is possible
+
+ ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
+ if (!framebufferRTV)
{
- ERR("It is undefined behaviour to clear a render buffer which is not normalized fixed point or floating-"
- "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment,
- attachment->getInternalFormat());
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
}
- if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) &&
- (formatInfo.greenBits == 0 || !clearParams.colorMaskGreen) &&
- (formatInfo.blueBits == 0 || !clearParams.colorMaskBlue) &&
- (formatInfo.alphaBits == 0 || !clearParams.colorMaskAlpha))
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget->getDXGIFormat());
+
+ // Check if the actual format has a channel that the internal format does not and set them to the
+ // default values
+ const float clearValues[4] =
{
- // Every channel either does not exist in the render target or is masked out
- continue;
- }
- else if (needScissoredClear || clearParams.colorClearType != GL_FLOAT ||
- (formatInfo.redBits > 0 && !clearParams.colorMaskRed) ||
- (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) ||
- (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) ||
- (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha))
+ ((formatInfo.redBits == 0 && dxgiFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red),
+ ((formatInfo.greenBits == 0 && dxgiFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green),
+ ((formatInfo.blueBits == 0 && dxgiFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue),
+ ((formatInfo.alphaBits == 0 && dxgiFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha),
+ };
+
+ if (needScissoredClear)
{
- // A scissored or masked clear is required
- MaskedRenderTarget maskAndRt;
- bool clearColor = clearParams.clearColor[colorAttachment];
- maskAndRt.colorMask[0] = (clearColor && clearParams.colorMaskRed);
- maskAndRt.colorMask[1] = (clearColor && clearParams.colorMaskGreen);
- maskAndRt.colorMask[2] = (clearColor && clearParams.colorMaskBlue);
- maskAndRt.colorMask[3] = (clearColor && clearParams.colorMaskAlpha);
- maskAndRt.renderTarget = renderTarget;
- maskedClearRenderTargets.push_back(maskAndRt);
+#if defined(ANGLE_ENABLE_D3D11_1)
+ // We shouldn't reach here if deviceContext1 is unavailable.
+ ASSERT(deviceContext1);
+
+ D3D11_RECT rect;
+ rect.left = clearParams.scissor.x;
+ rect.right = clearParams.scissor.x + clearParams.scissor.width;
+ rect.top = clearParams.scissor.y;
+ rect.bottom = clearParams.scissor.y + clearParams.scissor.height;
+
+ deviceContext1->ClearView(framebufferRTV, clearValues, &rect, 1);
+#endif
}
else
{
- // ID3D11DeviceContext::ClearRenderTargetView is possible
-
- ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
- if (!framebufferRTV)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null.");
- }
-
- const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
-
- // Check if the actual format has a channel that the internal format does not and set them to the
- // default values
- const float clearValues[4] =
- {
- ((formatInfo.redBits == 0 && actualFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red),
- ((formatInfo.greenBits == 0 && actualFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green),
- ((formatInfo.blueBits == 0 && actualFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue),
- ((formatInfo.alphaBits == 0 && actualFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha),
- };
-
deviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
}
}
@@ -287,40 +346,39 @@ gl::Error Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, cons
if (clearParams.clearDepth || clearParams.clearStencil)
{
- gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer();
- if (attachment)
+ const gl::FramebufferAttachment *attachment = (depthAttachment != nullptr) ? depthAttachment : stencilAttachment;
+ ASSERT(attachment != nullptr);
+
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
{
- RenderTarget11 *renderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget);
- if (error.isError())
- {
- return error;
- }
+ return error;
+ }
- const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget->getDXGIFormat());
- unsigned int stencilUnmasked = frameBuffer->hasStencil() ? (1 << actualFormatInfo.stencilBits) - 1 : 0;
- bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
+ unsigned int stencilUnmasked = (stencilAttachment != nullptr) ? (1 << dxgiFormatInfo.stencilBits) - 1 : 0;
+ bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
- if (needScissoredClear || needMaskedStencilClear)
+ if (needScissoredClear || needMaskedStencilClear)
+ {
+ maskedClearDepthStencil = renderTarget;
+ }
+ else
+ {
+ ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
+ if (!framebufferDSV)
{
- maskedClearDepthStencil = renderTarget;
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null.");
}
- else
- {
- ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
- if (!framebufferDSV)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null.");
- }
- UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) |
- (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0);
- FLOAT depthClear = gl::clamp01(clearParams.depthClearValue);
- UINT8 stencilClear = clearParams.stencilClearValue & 0xFF;
+ UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) |
+ (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0);
+ FLOAT depthClear = gl::clamp01(clearParams.depthClearValue);
+ UINT8 stencilClear = clearParams.stencilClearValue & 0xFF;
- deviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
- }
+ deviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
}
}
@@ -484,13 +542,13 @@ ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>&
blendDesc.AlphaToCoverageEnable = FALSE;
blendDesc.IndependentBlendEnable = (rts.size() > 1) ? TRUE : FALSE;
- for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
+ for (unsigned int j = 0; j < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; j++)
{
- blendDesc.RenderTarget[i].BlendEnable = FALSE;
- blendDesc.RenderTarget[i].RenderTargetWriteMask = gl_d3d11::ConvertColorMask(blendKey.maskChannels[i][0],
- blendKey.maskChannels[i][1],
- blendKey.maskChannels[i][2],
- blendKey.maskChannels[i][3]);
+ blendDesc.RenderTarget[j].BlendEnable = FALSE;
+ blendDesc.RenderTarget[j].RenderTargetWriteMask = gl_d3d11::ConvertColorMask(blendKey.maskChannels[j][0],
+ blendKey.maskChannels[j][1],
+ blendKey.maskChannels[j][2],
+ blendKey.maskChannels[j][3]);
}
ID3D11Device *device = mRenderer->getDevice();
@@ -508,7 +566,7 @@ ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>&
}
}
-ID3D11DepthStencilState *Clear11::getDepthStencilState(const gl::ClearParameters &clearParams)
+ID3D11DepthStencilState *Clear11::getDepthStencilState(const ClearParameters &clearParams)
{
ClearDepthStencilInfo dsKey = { 0 };
dsKey.clearDepth = clearParams.clearDepth;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h
index a7e8fea56a..4797ca1aa0 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h
@@ -6,45 +6,32 @@
// Clear11.h: Framebuffer clear utility class.
-#ifndef LIBGLESV2_RENDERER_CLEAR11_H_
-#define LIBGLESV2_RENDERER_CLEAR11_H_
-
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/Error.h"
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_CLEAR11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_CLEAR11_H_
#include <map>
#include <vector>
-namespace gl
-{
-class Framebuffer;
-}
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Framebuffer.h"
namespace rx
{
class Renderer11;
class RenderTarget11;
+struct ClearParameters;
-class Clear11
+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.
- gl::Error clearFramebuffer(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer);
+ gl::Error clearFramebuffer(const ClearParameters &clearParams, const gl::Framebuffer::Data &fboData);
private:
- Renderer11 *mRenderer;
-
- struct ClearBlendInfo
- {
- bool maskChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4];
- };
- typedef bool (*ClearBlendInfoComparisonFunction)(const ClearBlendInfo&, const ClearBlendInfo &);
- typedef std::map<ClearBlendInfo, ID3D11BlendState*, ClearBlendInfoComparisonFunction> ClearBlendStateMap;
- ClearBlendStateMap mClearBlendStates;
-
struct MaskedRenderTarget
{
bool colorMask[4];
@@ -52,6 +39,7 @@ class Clear11
};
ID3D11BlendState *getBlendState(const std::vector<MaskedRenderTarget> &rts);
+ ID3D11DepthStencilState *getDepthStencilState(const ClearParameters &clearParams);
struct ClearShader
{
@@ -59,13 +47,24 @@ class Clear11
ID3D11VertexShader *vertexShader;
ID3D11PixelShader *pixelShader;
};
+
+ template <unsigned int vsSize, unsigned int psSize>
+ static ClearShader CreateClearShader(ID3D11Device *device, DXGI_FORMAT colorType, const BYTE(&vsByteCode)[vsSize], const BYTE(&psByteCode)[psSize]);
+
+ Renderer11 *mRenderer;
+
+ struct ClearBlendInfo
+ {
+ bool maskChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4];
+ };
+ typedef bool(*ClearBlendInfoComparisonFunction)(const ClearBlendInfo&, const ClearBlendInfo &);
+ typedef std::map<ClearBlendInfo, ID3D11BlendState*, ClearBlendInfoComparisonFunction> ClearBlendStateMap;
+ ClearBlendStateMap mClearBlendStates;
+
ClearShader mFloatClearShader;
ClearShader mUintClearShader;
ClearShader mIntClearShader;
- template <unsigned int vsSize, unsigned int psSize>
- static ClearShader CreateClearShader(ID3D11Device *device, DXGI_FORMAT colorType, const BYTE (&vsByteCode)[vsSize], const BYTE (&psByteCode)[psSize]);
-
struct ClearDepthStencilInfo
{
bool clearDepth;
@@ -76,12 +75,12 @@ class Clear11
typedef std::map<ClearDepthStencilInfo, ID3D11DepthStencilState*, ClearDepthStencilInfoComparisonFunction> ClearDepthStencilStateMap;
ClearDepthStencilStateMap mClearDepthStencilStates;
- ID3D11DepthStencilState *getDepthStencilState(const gl::ClearParameters &clearParams);
-
ID3D11Buffer *mVertexBuffer;
ID3D11RasterizerState *mRasterizerState;
+
+ bool mSupportsClearView;
};
}
-#endif // LIBGLESV2_RENDERER_CLEAR11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_CLEAR11_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
new file mode 100644
index 0000000000..f1fe2bb2c7
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
@@ -0,0 +1,119 @@
+//
+// 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 "common/debug.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace rx
+{
+
+DebugAnnotator11::DebugAnnotator11()
+ : mInitialized(false),
+ mD3d11Module(nullptr),
+ mUserDefinedAnnotation(nullptr)
+{
+ // D3D11 devices can't be created during DllMain.
+ // We defer device creation until the object is actually used.
+}
+
+DebugAnnotator11::~DebugAnnotator11()
+{
+ if (mInitialized)
+ {
+#if defined(ANGLE_ENABLE_D3D11_1)
+ SafeRelease(mUserDefinedAnnotation);
+#endif
+
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ FreeLibrary(mD3d11Module);
+#endif // !ANGLE_ENABLE_WINDOWS_STORE
+ }
+}
+
+void DebugAnnotator11::beginEvent(const std::wstring &eventName)
+{
+ initializeDevice();
+
+#if defined(ANGLE_ENABLE_D3D11_1)
+ mUserDefinedAnnotation->BeginEvent(eventName.c_str());
+#endif
+}
+
+void DebugAnnotator11::endEvent()
+{
+ initializeDevice();
+
+#if defined(ANGLE_ENABLE_D3D11_1)
+ mUserDefinedAnnotation->EndEvent();
+#endif
+}
+
+void DebugAnnotator11::setMarker(const std::wstring &markerName)
+{
+ initializeDevice();
+
+#if defined(ANGLE_ENABLE_D3D11_1)
+ mUserDefinedAnnotation->SetMarker(markerName.c_str());
+#endif
+}
+
+bool DebugAnnotator11::getStatus()
+{
+ // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in Visual Studio 2013.
+
+#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
+ // In the Windows Store, we can use IDXGraphicsAnalysis. The call to GetDebugInterface1 only succeeds if the app is under capture.
+ // This should only be called in DEBUG mode.
+ // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows Store ingestion checks.
+ IDXGraphicsAnalysis *graphicsAnalysis;
+ DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis));
+ bool underCapture = (graphicsAnalysis != nullptr);
+ SafeRelease(graphicsAnalysis);
+ return underCapture;
+#endif // _DEBUG && !ANGLE_ENABLE_WINDOWS_STORE
+
+ // Otherwise, we have to return true here.
+ return true;
+}
+
+void DebugAnnotator11::initializeDevice()
+{
+ if (!mInitialized)
+ {
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
+ ASSERT(mD3d11Module);
+
+ PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
+ ASSERT(D3D11CreateDevice != nullptr);
+#endif // !ANGLE_ENABLE_WINDOWS_STORE
+
+ ID3D11Device *device = nullptr;
+ ID3D11DeviceContext *context = nullptr;
+
+ HRESULT hr = E_FAIL;
+
+ // Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device.
+ hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context);
+ ASSERT(SUCCEEDED(hr));
+
+#if defined(ANGLE_ENABLE_D3D11_1)
+ mUserDefinedAnnotation = d3d11::DynamicCastComObject<ID3DUserDefinedAnnotation>(context);
+ ASSERT(mUserDefinedAnnotation != nullptr);
+#endif
+
+ SafeRelease(device);
+ SafeRelease(context);
+
+ mInitialized = true;
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h
new file mode 100644
index 0000000000..3df62b015c
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.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.
+//
+// DebugAnnotator11.h: D3D11 helpers for adding trace annotations.
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_DEBUGANNOTATOR11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_DEBUGANNOTATOR11_H_
+
+#include "common/debug.h"
+
+struct ID3DUserDefinedAnnotation;
+
+namespace rx
+{
+
+class DebugAnnotator11 : public gl::DebugAnnotator
+{
+ public:
+ DebugAnnotator11();
+ ~DebugAnnotator11() override;
+ void beginEvent(const std::wstring &eventName) override;
+ void endEvent() override;
+ void setMarker(const std::wstring &markerName) override;
+ bool getStatus() override;
+
+ private:
+ void initializeDevice();
+
+ bool mInitialized;
+ HMODULE mD3d11Module;
+ ID3DUserDefinedAnnotation *mUserDefinedAnnotation;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_DEBUGANNOTATOR11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
index f44d934056..8552bc2beb 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
@@ -6,9 +6,8 @@
// Fence11.cpp: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl.
-#include "libGLESv2/renderer/d3d/d3d11/Fence11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/d3d11/Fence11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "common/utilities.h"
@@ -99,7 +98,7 @@ gl::Error FenceNV11::finishFence(GLboolean *outFinished)
return error;
}
- Sleep(0);
+ ScheduleYield();
}
return gl::Error(GL_NO_ERROR);
@@ -179,8 +178,8 @@ gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *ou
while (currentCounter.QuadPart < endCounter && !result)
{
- Sleep(0);
- BOOL success = QueryPerformanceCounter(&currentCounter);
+ ScheduleYield();
+ success = QueryPerformanceCounter(&currentCounter);
UNUSED_ASSERTION_VARIABLE(success);
ASSERT(success);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h
index 1223a53b90..2d87f43e76 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h
@@ -6,10 +6,11 @@
// Fence11.h: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl.
-#ifndef LIBGLESV2_RENDERER_FENCE11_H_
-#define LIBGLESV2_RENDERER_FENCE11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_FENCE11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_FENCE11_H_
-#include "libGLESv2/renderer/FenceImpl.h"
+#include "libANGLE/renderer/FenceNVImpl.h"
+#include "libANGLE/renderer/FenceSyncImpl.h"
namespace rx
{
@@ -26,8 +27,6 @@ class FenceNV11 : public FenceNVImpl
gl::Error finishFence(GLboolean *outFinished);
private:
- DISALLOW_COPY_AND_ASSIGN(FenceNV11);
-
template<class T> friend gl::Error FenceSetHelper(T *fence);
template<class T> friend gl::Error FenceTestHelper(T *fence, bool flushCommandBuffer, GLboolean *outFinished);
@@ -47,8 +46,6 @@ class FenceSync11 : public FenceSyncImpl
gl::Error getStatus(GLint *outResult);
private:
- DISALLOW_COPY_AND_ASSIGN(FenceSync11);
-
template<class T> friend gl::Error FenceSetHelper(T *fence);
template<class T> friend gl::Error FenceTestHelper(T *fence, bool flushCommandBuffer, GLboolean *outFinished);
@@ -59,4 +56,4 @@ class FenceSync11 : public FenceSyncImpl
}
-#endif // LIBGLESV2_RENDERER_FENCE11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_FENCE11_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
new file mode 100644
index 0000000000..da01f320c0
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
@@ -0,0 +1,270 @@
+//
+// 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/debug.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Clear11.h"
+#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Texture.h"
+
+namespace rx
+{
+
+Framebuffer11::Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer)
+ : FramebufferD3D(data, renderer),
+ mRenderer(renderer)
+{
+ ASSERT(mRenderer != nullptr);
+}
+
+Framebuffer11::~Framebuffer11()
+{
+}
+
+static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *attachment)
+{
+ if (attachment && attachment->type() == GL_TEXTURE)
+ {
+ gl::Texture *texture = attachment->getTexture();
+
+ TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
+
+ TextureStorage *texStorage = NULL;
+ gl::Error error = textureD3D->getNativeTexture(&texStorage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (texStorage)
+ {
+ TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage);
+ ASSERT(texStorage11);
+
+ texStorage11->invalidateSwizzleCacheLevel(attachment->mipLevel());
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Framebuffer11::invalidateSwizzles() const
+{
+ for (auto it = mData.mColorAttachments.cbegin(); it != mData.mColorAttachments.cend(); ++it)
+ {
+ gl::FramebufferAttachment *colorAttachment = *it;
+ gl::Error error = InvalidateAttachmentSwizzles(colorAttachment);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ gl::Error error = InvalidateAttachmentSwizzles(mData.mDepthAttachment);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = InvalidateAttachmentSwizzles(mData.mStencilAttachment);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Framebuffer11::clear(const gl::State &state, const ClearParameters &clearParams)
+{
+ Clear11 *clearer = mRenderer->getClearer();
+ gl::Error error = clearer->clearFramebuffer(clearParams, mData);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ error = invalidateSwizzles();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+static gl::Error getRenderTargetResource(const gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut,
+ ID3D11Texture2D **texture2DOut)
+{
+ ASSERT(colorbuffer);
+
+ RenderTarget11 *renderTarget = NULL;
+ gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11Resource *renderTargetResource = renderTarget->getTexture();
+ ASSERT(renderTargetResource);
+
+ *subresourceIndexOut = renderTarget->getSubresourceIndex();
+ *texture2DOut = d3d11::DynamicCastComObject<ID3D11Texture2D>(renderTargetResource);
+
+ if (!(*texture2DOut))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the ID3D11Texture2D from a RenderTarget");
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Framebuffer11::readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) const
+{
+ ID3D11Texture2D *colorBufferTexture = NULL;
+ unsigned int subresourceIndex = 0;
+
+ const gl::FramebufferAttachment *colorbuffer = mData.getReadAttachment();
+ ASSERT(colorbuffer);
+
+ gl::Error error = getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ gl::Buffer *packBuffer = pack.pixelBuffer.get();
+ if (packBuffer != NULL)
+ {
+ Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation());
+ PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
+
+ error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
+ if (error.isError())
+ {
+ SafeRelease(colorBufferTexture);
+ return error;
+ }
+
+ packBuffer->getIndexRangeCache()->clear();
+ }
+ else
+ {
+ error = mRenderer->readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
+ if (error.isError())
+ {
+ SafeRelease(colorBufferTexture);
+ return error;
+ }
+ }
+
+ SafeRelease(colorBufferTexture);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Framebuffer11::blit(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->getReadColorbuffer();
+ ASSERT(readBuffer);
+
+ RenderTargetD3D *readRenderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(readRenderTarget);
+
+ for (size_t colorAttachment = 0; colorAttachment < mData.mColorAttachments.size(); colorAttachment++)
+ {
+ if (mData.mColorAttachments[colorAttachment] != nullptr &&
+ mData.mDrawBufferStates[colorAttachment] != GL_NONE)
+ {
+ const gl::FramebufferAttachment *drawBuffer = mData.mColorAttachments[colorAttachment];
+
+ RenderTargetD3D *drawRenderTarget = NULL;
+ error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(drawRenderTarget);
+
+ error = mRenderer->blitRenderbufferRect(sourceArea, destArea, readRenderTarget, drawRenderTarget,
+ filter, scissor, blitRenderTarget, false, false);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+ }
+ }
+
+ if (blitDepth || blitStencil)
+ {
+ gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getDepthOrStencilbuffer();
+ ASSERT(readBuffer);
+
+ RenderTargetD3D *readRenderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(readRenderTarget);
+
+ const gl::FramebufferAttachment *drawBuffer = mData.getDepthOrStencilAttachment();
+ ASSERT(drawBuffer);
+
+ RenderTargetD3D *drawRenderTarget = NULL;
+ error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(drawRenderTarget);
+
+ error = mRenderer->blitRenderbufferRect(sourceArea, destArea, readRenderTarget, drawRenderTarget, filter, scissor,
+ false, blitDepth, blitStencil);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
+ gl::Error error = invalidateSwizzles();
+ if (error.isError())
+ {
+ return error;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const
+{
+ RenderTarget11 *renderTarget11 = RenderTarget11::makeRenderTarget11(renderTarget);
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget11->getDXGIFormat());
+ return dxgiFormatInfo.internalFormat;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
new file mode 100644
index 0000000000..07fa480fa2
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
@@ -0,0 +1,45 @@
+//
+// 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/renderer/d3d/FramebufferD3D.h"
+
+namespace rx
+{
+class Renderer11;
+
+class Framebuffer11 : public FramebufferD3D
+{
+ public:
+ Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer);
+ virtual ~Framebuffer11();
+
+ // Invalidate the cached swizzles of all bound texture attachments.
+ gl::Error invalidateSwizzles() const;
+
+ private:
+ gl::Error clear(const gl::State &state, const ClearParameters &clearParams) override;
+
+ gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch,
+ const gl::PixelPackState &pack, uint8_t *pixels) const override;
+
+ gl::Error blit(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;
+
+
+ GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override;
+
+ Renderer11 *const mRenderer;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
index e6f3e90683..956b78b5a6 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
@@ -7,23 +7,23 @@
// Image11.h: Implements the rx::Image11 class, which acts as the interface to
// the actual underlying resources of a Texture
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
-#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
-#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Image11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.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/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/formatutils.h"
#include "common/utilities.h"
namespace rx
{
-Image11::Image11()
- : mRenderer(NULL),
+Image11::Image11(Renderer11 *renderer)
+ : mRenderer(renderer),
mDXGIFormat(DXGI_FORMAT_UNKNOWN),
mStagingTexture(NULL),
mStagingSubresource(0),
@@ -31,8 +31,10 @@ Image11::Image11()
mAssociatedStorage(NULL),
mAssociatedImageIndex(gl::ImageIndex::MakeInvalid()),
mRecoveredFromStorageCount(0)
-
{
+ // mRenderer should remain unchanged during the lifetime of the Image11 object.
+ // This lets us safely use mRenderer (and its Feature Level) in Image11's methods.
+ mFeatureLevel = renderer->getFeatureLevel();
}
Image11::~Image11()
@@ -41,7 +43,7 @@ Image11::~Image11()
releaseStagingTexture();
}
-Image11 *Image11::makeImage11(Image *img)
+Image11 *Image11::makeImage11(ImageD3D *img)
{
ASSERT(HAS_DYNAMIC_TYPE(Image11*, img));
return static_cast<Image11*>(img);
@@ -92,7 +94,7 @@ bool Image11::isDirty() const
// 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)
// then isDirty should still return false.
- if (mDirty && !mStagingTexture && !mRecoverFromStorage && !(d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL))
+ if (mDirty && !mStagingTexture && !mRecoverFromStorage && !(d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel).dataInitializerFunction != NULL))
{
return false;
}
@@ -201,10 +203,10 @@ void Image11::disassociateStorage()
}
}
-bool Image11::redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
+bool Image11::redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease)
{
- if (mWidth != width ||
- mHeight != height ||
+ if (mWidth != size.width ||
+ mHeight != size.height ||
mInternalFormat != internalformat ||
forceRelease)
{
@@ -213,19 +215,15 @@ bool Image11::redefine(RendererD3D *renderer, GLenum target, GLenum internalform
disassociateStorage();
mRecoveredFromStorageCount = 0;
- mRenderer = Renderer11::makeRenderer11(renderer);
-
- mWidth = width;
- mHeight = height;
- mDepth = depth;
+ mWidth = size.width;
+ mHeight = size.height;
+ mDepth = size.depth;
mInternalFormat = internalformat;
mTarget = target;
// compute the d3d format that will be used
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, mFeatureLevel);
mDXGIFormat = formatInfo.texFormat;
- mActualFormat = dxgiFormatInfo.internalFormat;
mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
releaseStagingTexture();
@@ -248,17 +246,16 @@ DXGI_FORMAT Image11::getDXGIFormat() const
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the target pixel rectangle.
-gl::Error Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input)
+gl::Error Image11::loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input)
{
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
- GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, width, height, unpackAlignment);
+ GLsizei inputRowPitch = formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength);
+ GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, area.width, area.height, unpack.alignment, unpack.rowLength);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
- const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat);
+ const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel);
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type);
D3D11_MAPPED_SUBRESOURCE mappedImage;
@@ -268,8 +265,8 @@ gl::Error Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei
return error;
}
- uint8_t* offsetMappedData = (reinterpret_cast<uint8_t*>(mappedImage.pData) + (yoffset * mappedImage.RowPitch + xoffset * outputPixelSize + zoffset * mappedImage.DepthPitch));
- loadFunction(width, height, depth,
+ uint8_t *offsetMappedData = (reinterpret_cast<uint8_t*>(mappedImage.pData) + (area.y * mappedImage.RowPitch + area.x * outputPixelSize + area.z * mappedImage.DepthPitch));
+ loadFunction(area.width, area.height, area.depth,
reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
@@ -278,22 +275,21 @@ gl::Error Image11::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei
return gl::Error(GL_NO_ERROR);
}
-gl::Error Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input)
+gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input)
{
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
- GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
+ GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0);
+ GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat);
GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
GLuint outputBlockWidth = dxgiFormatInfo.blockWidth;
GLuint outputBlockHeight = dxgiFormatInfo.blockHeight;
- ASSERT(xoffset % outputBlockWidth == 0);
- ASSERT(yoffset % outputBlockHeight == 0);
+ ASSERT(area.x % outputBlockWidth == 0);
+ ASSERT(area.y % outputBlockHeight == 0);
- const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat);
+ const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel);
LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE);
D3D11_MAPPED_SUBRESOURCE mappedImage;
@@ -303,11 +299,11 @@ gl::Error Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffse
return error;
}
- uint8_t* offsetMappedData = reinterpret_cast<uint8_t*>(mappedImage.pData) + ((yoffset / outputBlockHeight) * mappedImage.RowPitch +
- (xoffset / outputBlockWidth) * outputPixelSize +
- zoffset * mappedImage.DepthPitch);
+ uint8_t* offsetMappedData = reinterpret_cast<uint8_t*>(mappedImage.pData) + ((area.y / outputBlockHeight) * mappedImage.RowPitch +
+ (area.x / outputBlockWidth) * outputPixelSize +
+ area.z * mappedImage.DepthPitch);
- loadFunction(width, height, depth,
+ loadFunction(area.width, area.height, area.depth,
reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
@@ -316,27 +312,23 @@ gl::Error Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffse
return gl::Error(GL_NO_ERROR);
}
-gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source)
+gl::Error Image11::copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source)
{
RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(source);
ASSERT(sourceRenderTarget->getTexture());
+ ID3D11Resource *resource = sourceRenderTarget->getTexture();
UINT subresourceIndex = sourceRenderTarget->getSubresourceIndex();
- ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(sourceRenderTarget->getTexture());
-
- if (!sourceTexture2D)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source RenderTarget.");
- }
- gl::Error error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex);
+ gl::Box sourceBox(sourceArea.x, sourceArea.y, 0, sourceArea.width, sourceArea.height, 1);
+ gl::Error error = copy(destOffset, sourceBox, resource, subresourceIndex);
- SafeRelease(sourceTexture2D);
+ SafeRelease(resource);
return error;
}
-gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, const gl::ImageIndex &sourceIndex, TextureStorage *source)
+gl::Error Image11::copy(const gl::Offset &destOffset, const gl::Box &sourceArea, const gl::ImageIndex &sourceIndex, TextureStorage *source)
{
TextureStorage11 *sourceStorage11 = TextureStorage11::makeTextureStorage11(source);
@@ -348,26 +340,52 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
return error;
}
- ID3D11Texture2D *sourceTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
+ error = copy(destOffset, sourceArea, resource, subresourceIndex);
- if (!sourceTexture2D)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the ID3D11Texture2D from the source TextureStorage.");
- }
-
- error = copy(xoffset, yoffset, zoffset, sourceArea, sourceTexture2D, subresourceIndex);
-
- SafeRelease(sourceTexture2D);
+ SafeRelease(resource);
return error;
}
-gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource)
+gl::Error Image11::copy(const gl::Offset &destOffset, const gl::Box &sourceArea, ID3D11Resource *source, UINT sourceSubResource)
{
- D3D11_TEXTURE2D_DESC textureDesc;
- source->GetDesc(&textureDesc);
+ D3D11_RESOURCE_DIMENSION dim;
+ source->GetType(&dim);
+
+ DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
+ gl::Extents extents;
+ UINT sampleCount = 0;
+
+ ID3D11Texture2D *source2D = NULL;
- if (textureDesc.Format == mDXGIFormat)
+ if (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D)
+ {
+ D3D11_TEXTURE2D_DESC textureDesc2D;
+ source2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(source);
+ ASSERT(source2D);
+ source2D->GetDesc(&textureDesc2D);
+
+ format = textureDesc2D.Format;
+ extents = gl::Extents(textureDesc2D.Width, textureDesc2D.Height, 1);
+ sampleCount = textureDesc2D.SampleDesc.Count;
+ }
+ else if (dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D)
+ {
+ D3D11_TEXTURE3D_DESC textureDesc3D;
+ ID3D11Texture3D *source3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(source);
+ ASSERT(source3D);
+ source3D->GetDesc(&textureDesc3D);
+
+ format = textureDesc3D.Format;
+ extents = gl::Extents(textureDesc3D.Width, textureDesc3D.Height, textureDesc3D.Depth);
+ sampleCount = 1;
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ if (format == mDXGIFormat)
{
// No conversion needed-- use copyback fastpath
ID3D11Resource *stagingTexture = NULL;
@@ -383,15 +401,18 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
UINT subresourceAfterResolve = sourceSubResource;
- ID3D11Texture2D* srcTex = NULL;
- if (textureDesc.SampleDesc.Count > 1)
+ ID3D11Resource *srcTex = NULL;
+
+ bool needResolve = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D && sampleCount > 1);
+
+ if (needResolve)
{
D3D11_TEXTURE2D_DESC resolveDesc;
- resolveDesc.Width = textureDesc.Width;
- resolveDesc.Height = textureDesc.Height;
+ resolveDesc.Width = extents.width;
+ resolveDesc.Height = extents.height;
resolveDesc.MipLevels = 1;
resolveDesc.ArraySize = 1;
- resolveDesc.Format = textureDesc.Format;
+ resolveDesc.Format = format;
resolveDesc.SampleDesc.Count = 1;
resolveDesc.SampleDesc.Quality = 0;
resolveDesc.Usage = D3D11_USAGE_DEFAULT;
@@ -399,13 +420,15 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
resolveDesc.CPUAccessFlags = 0;
resolveDesc.MiscFlags = 0;
- HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
+ ID3D11Texture2D *srcTex2D = NULL;
+ HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex2D);
if (FAILED(result))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
}
+ srcTex = srcTex2D;
- deviceContext->ResolveSubresource(srcTex, 0, source, sourceSubResource, textureDesc.Format);
+ deviceContext->ResolveSubresource(srcTex, 0, source, sourceSubResource, format);
subresourceAfterResolve = 0;
}
else
@@ -418,12 +441,13 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
srcBox.right = sourceArea.x + sourceArea.width;
srcBox.top = sourceArea.y;
srcBox.bottom = sourceArea.y + sourceArea.height;
- srcBox.front = 0;
- srcBox.back = 1;
+ srcBox.front = sourceArea.z;
+ srcBox.back = sourceArea.z + sourceArea.depth;
- deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, xoffset, yoffset, zoffset, srcTex, subresourceAfterResolve, &srcBox);
+ deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, destOffset.x, destOffset.y,
+ destOffset.z, srcTex, subresourceAfterResolve, &srcBox);
- if (textureDesc.SampleDesc.Count > 1)
+ if (needResolve)
{
SafeRelease(srcTex);
}
@@ -439,12 +463,18 @@ gl::Error Image11::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::R
}
// determine the offset coordinate into the destination buffer
- GLsizei rowOffset = gl::GetInternalFormatInfo(mActualFormat).pixelBytes * xoffset;
- uint8_t *dataOffset = static_cast<uint8_t*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset + zoffset * mappedImage.DepthPitch;
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(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 &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
- error = mRenderer->readTextureData(source, sourceSubResource, sourceArea, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
+ // Currently in ANGLE, the source data may only need to be converted if the source is the current framebuffer
+ // and OpenGL ES framebuffers must be 2D textures therefore we should not need to convert 3D textures between different formats.
+ ASSERT(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D);
+ ASSERT(sourceArea.z == 0 && sourceArea.depth == 1);
+ gl::Rectangle sourceRect(sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height);
+ error = mRenderer->readTextureData(source2D, sourceSubResource, sourceRect, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
unmap();
@@ -513,11 +543,11 @@ gl::Error Image11::createStagingTexture()
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
- if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
+ if (d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel).dataInitializerFunction != NULL)
{
std::vector<D3D11_SUBRESOURCE_DATA> initialData;
std::vector< std::vector<BYTE> > textureData;
- d3d11::GenerateInitialTextureData(mInternalFormat, width, height, mDepth,
+ d3d11::GenerateInitialTextureData(mInternalFormat, mFeatureLevel, width, height, mDepth,
lodOffset + 1, &initialData, &textureData);
result = device->CreateTexture3D(&desc, initialData.data(), &newTexture);
@@ -553,11 +583,11 @@ gl::Error Image11::createStagingTexture()
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
- if (d3d11::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL)
+ if (d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel).dataInitializerFunction != NULL)
{
std::vector<D3D11_SUBRESOURCE_DATA> initialData;
std::vector< std::vector<BYTE> > textureData;
- d3d11::GenerateInitialTextureData(mInternalFormat, width, height, 1,
+ d3d11::GenerateInitialTextureData(mInternalFormat, mFeatureLevel, width, height, 1,
lodOffset + 1, &initialData, &textureData);
result = device->CreateTexture2D(&desc, initialData.data(), &newTexture);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h
index a936e6d7b2..5734f73b15 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h
@@ -7,11 +7,11 @@
// Image11.h: Defines the rx::Image11 class, which acts as the interface to
// the actual underlying resources of a Texture
-#ifndef LIBGLESV2_RENDERER_IMAGE11_H_
-#define LIBGLESV2_RENDERER_IMAGE11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_IMAGE11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_IMAGE11_H_
-#include "libGLESv2/renderer/d3d/ImageD3D.h"
-#include "libGLESv2/ImageIndex.h"
+#include "libANGLE/renderer/d3d/ImageD3D.h"
+#include "libANGLE/ImageIndex.h"
#include "common/debug.h"
@@ -28,10 +28,10 @@ class TextureStorage11;
class Image11 : public ImageD3D
{
public:
- Image11();
+ Image11(Renderer11 *renderer);
virtual ~Image11();
- static Image11 *makeImage11(Image *img);
+ static Image11 *makeImage11(ImageD3D *img);
static gl::Error generateMipmap(Image11 *dest, Image11 *src);
@@ -39,17 +39,15 @@ class Image11 : public ImageD3D
virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region);
- bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) override;
+ bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) override;
DXGI_FORMAT getDXGIFormat() const;
- virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input);
- virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input);
+ virtual gl::Error loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input);
+ virtual gl::Error loadCompressedData(const gl::Box &area, const void *input);
- virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source);
- virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
+ virtual gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source);
+ virtual gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea,
const gl::ImageIndex &sourceIndex, TextureStorage *source);
gl::Error recoverFromAssociatedStorage();
@@ -61,16 +59,15 @@ class Image11 : public ImageD3D
void unmap();
private:
- DISALLOW_COPY_AND_ASSIGN(Image11);
-
gl::Error copyToStorageImpl(TextureStorage11 *storage11, const gl::ImageIndex &index, const gl::Box &region);
- gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, ID3D11Texture2D *source, UINT sourceSubResource);
+ gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea, ID3D11Resource *source, UINT sourceSubResource);
gl::Error getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex);
gl::Error createStagingTexture();
void releaseStagingTexture();
Renderer11 *mRenderer;
+ D3D_FEATURE_LEVEL mFeatureLevel;
DXGI_FORMAT mDXGIFormat;
ID3D11Resource *mStagingTexture;
@@ -84,4 +81,4 @@ class Image11 : public ImageD3D
}
-#endif // LIBGLESV2_RENDERER_IMAGE11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_IMAGE11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp
index 9a61182ee9..99c199f2b9 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp
@@ -6,8 +6,8 @@
// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation.
-#include "libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
namespace rx
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h
index 3351df5ec1..eadd03eb76 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h
@@ -6,10 +6,10 @@
// IndexBuffer11.h: Defines the D3D11 IndexBuffer implementation.
-#ifndef LIBGLESV2_RENDERER_INDEXBUFFER11_H_
-#define LIBGLESV2_RENDERER_INDEXBUFFER11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_INDEXBUFFER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_INDEXBUFFER11_H_
-#include "libGLESv2/renderer/d3d/IndexBuffer.h"
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
namespace rx
{
@@ -38,8 +38,6 @@ class IndexBuffer11 : public IndexBuffer
ID3D11Buffer *getBuffer() const;
private:
- DISALLOW_COPY_AND_ASSIGN(IndexBuffer11);
-
Renderer11 *const mRenderer;
ID3D11Buffer *mBuffer;
@@ -50,4 +48,4 @@ class IndexBuffer11 : public IndexBuffer
}
-#endif // LIBGLESV2_RENDERER_INDEXBUFFER11_H_ \ No newline at end of file
+#endif // LIBANGLE_RENDERER_D3D_D3D11_INDEXBUFFER11_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
new file mode 100644
index 0000000000..242c09d6ce
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -0,0 +1,430 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches
+// D3D11 input layouts.
+
+#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
+#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/VertexAttribute.h"
+
+#include "third_party/murmurhash/MurmurHash3.h"
+
+namespace rx
+{
+
+static void GetInputLayout(const TranslatedAttribute translatedAttributes[gl::MAX_VERTEX_ATTRIBS],
+ gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
+{
+ for (unsigned int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ const TranslatedAttribute &translatedAttribute = translatedAttributes[attributeIndex];
+
+ if (translatedAttributes[attributeIndex].active)
+ {
+ inputLayout[attributeIndex] = gl::VertexFormat(*translatedAttribute.attribute,
+ translatedAttribute.currentValueType);
+ }
+ }
+}
+
+const unsigned int InputLayoutCache::kMaxInputLayouts = 1024;
+
+InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts)
+{
+ mCounter = 0;
+ mDevice = NULL;
+ mDeviceContext = NULL;
+ mCurrentIL = NULL;
+ for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mCurrentBuffers[i] = NULL;
+ mCurrentVertexStrides[i] = static_cast<UINT>(-1);
+ mCurrentVertexOffsets[i] = static_cast<UINT>(-1);
+ }
+ mPointSpriteVertexBuffer = NULL;
+ mPointSpriteIndexBuffer = NULL;
+}
+
+InputLayoutCache::~InputLayoutCache()
+{
+ clear();
+}
+
+void InputLayoutCache::initialize(ID3D11Device *device, ID3D11DeviceContext *context)
+{
+ clear();
+ mDevice = device;
+ mDeviceContext = context;
+ mFeatureLevel = device->GetFeatureLevel();
+}
+
+void InputLayoutCache::clear()
+{
+ for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
+ {
+ SafeRelease(i->second.inputLayout);
+ }
+ mInputLayoutMap.clear();
+ SafeRelease(mPointSpriteVertexBuffer);
+ SafeRelease(mPointSpriteIndexBuffer);
+ markDirty();
+}
+
+void InputLayoutCache::markDirty()
+{
+ mCurrentIL = NULL;
+ for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mCurrentBuffers[i] = NULL;
+ mCurrentVertexStrides[i] = static_cast<UINT>(-1);
+ mCurrentVertexOffsets[i] = static_cast<UINT>(-1);
+ }
+}
+
+gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
+ GLenum mode, gl::Program *program)
+{
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+
+ int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS];
+ programD3D->sortAttributesByLayout(attributes, sortedSemanticIndices);
+ bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
+ bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS);
+
+ if (!mDevice || !mDeviceContext)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal input layout cache is not initialized.");
+ }
+
+ InputLayoutKey ilKey = { 0 };
+
+ static const char* semanticName = "TEXCOORD";
+
+ unsigned int firstIndexedElement = gl::MAX_VERTEX_ATTRIBS;
+ unsigned int firstInstancedElement = gl::MAX_VERTEX_ATTRIBS;
+ unsigned int nextAvailableInputSlot = 0;
+
+ for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ if (attributes[i].active)
+ {
+ D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
+ // If rendering points and instanced pointsprite emulation is being used, the inputClass is required to be configured as per instance data
+ inputClass = instancedPointSpritesActive ? D3D11_INPUT_PER_INSTANCE_DATA : inputClass;
+
+ gl::VertexFormat vertexFormat(*attributes[i].attribute, attributes[i].currentValueType);
+ const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel);
+
+ // Record the type of the associated vertex shader vector in our key
+ // This will prevent mismatched vertex shaders from using the same input layout
+ GLint attributeSize;
+ program->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL);
+
+ ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName;
+ ilKey.elements[ilKey.elementCount].desc.SemanticIndex = sortedSemanticIndices[i];
+ ilKey.elements[ilKey.elementCount].desc.Format = vertexFormatInfo.nativeFormat;
+ ilKey.elements[ilKey.elementCount].desc.InputSlot = i;
+ ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0;
+ ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass;
+ ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = instancedPointSpritesActive ? 1 : attributes[i].divisor;
+
+ if (inputClass == D3D11_INPUT_PER_VERTEX_DATA && firstIndexedElement == gl::MAX_VERTEX_ATTRIBS)
+ {
+ firstIndexedElement = ilKey.elementCount;
+ }
+ else if (inputClass == D3D11_INPUT_PER_INSTANCE_DATA && firstInstancedElement == gl::MAX_VERTEX_ATTRIBS)
+ {
+ firstInstancedElement = ilKey.elementCount;
+ }
+
+ ilKey.elementCount++;
+ nextAvailableInputSlot = i + 1;
+ }
+ }
+
+ // 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)
+ {
+ ilKey.elements[ilKey.elementCount].desc.SemanticName = "SPRITEPOSITION";
+ ilKey.elements[ilKey.elementCount].desc.SemanticIndex = 0;
+ ilKey.elements[ilKey.elementCount].desc.Format = DXGI_FORMAT_R32G32B32_FLOAT;
+ ilKey.elements[ilKey.elementCount].desc.InputSlot = nextAvailableInputSlot;
+ ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0;
+ ilKey.elements[ilKey.elementCount].desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = 0;
+
+ // The new elements are D3D11_INPUT_PER_VERTEX_DATA data so the indexed element
+ // tracking must be applied. This ensures that the instancing specific
+ // buffer swapping logic continues to work.
+ if (firstIndexedElement == gl::MAX_VERTEX_ATTRIBS)
+ {
+ firstIndexedElement = ilKey.elementCount;
+ }
+
+ ilKey.elementCount++;
+
+ ilKey.elements[ilKey.elementCount].desc.SemanticName = "SPRITETEXCOORD";
+ ilKey.elements[ilKey.elementCount].desc.SemanticIndex = 0;
+ ilKey.elements[ilKey.elementCount].desc.Format = DXGI_FORMAT_R32G32_FLOAT;
+ ilKey.elements[ilKey.elementCount].desc.InputSlot = nextAvailableInputSlot;
+ ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = sizeof(float) * 3;
+ ilKey.elements[ilKey.elementCount].desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = 0;
+
+ ilKey.elementCount++;
+ }
+
+ // 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.
+ ASSERT(!(mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && firstIndexedElement == gl::MAX_VERTEX_ATTRIBS));
+ bool moveFirstIndexedIntoSlotZero = mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && firstInstancedElement == 0 && firstIndexedElement != gl::MAX_VERTEX_ATTRIBS;
+
+ if (moveFirstIndexedIntoSlotZero)
+ {
+ ilKey.elements[firstInstancedElement].desc.InputSlot = ilKey.elements[firstIndexedElement].desc.InputSlot;
+ ilKey.elements[firstIndexedElement].desc.InputSlot = 0;
+
+ // Instanced PointSprite emulation uses multiple layout entries across a single vertex buffer.
+ // If an index swap is performed, we need to ensure that all elements get the proper InputSlot.
+ if (programUsesInstancedPointSprites)
+ {
+ ilKey.elements[firstIndexedElement + 1].desc.InputSlot = 0;
+ }
+ }
+
+ ID3D11InputLayout *inputLayout = NULL;
+
+ InputLayoutMap::iterator keyIter = mInputLayoutMap.find(ilKey);
+ if (keyIter != mInputLayoutMap.end())
+ {
+ inputLayout = keyIter->second.inputLayout;
+ keyIter->second.lastUsedTime = mCounter++;
+ }
+ else
+ {
+ gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
+ GetInputLayout(attributes, shaderInputLayout);
+
+ ShaderExecutableD3D *shader = NULL;
+ gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader, nullptr);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ShaderExecutableD3D *shader11 = ShaderExecutable11::makeShaderExecutable11(shader);
+
+ D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS];
+ for (unsigned int j = 0; j < ilKey.elementCount; ++j)
+ {
+ descs[j] = ilKey.elements[j].desc;
+ }
+
+ HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader11->getFunction(), shader11->getLength(), &inputLayout);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal input layout, HRESULT: 0x%08x", result);
+ }
+
+ if (mInputLayoutMap.size() >= kMaxInputLayouts)
+ {
+ TRACE("Overflowed the limit of %u input layouts, removing the least recently used "
+ "to make room.", kMaxInputLayouts);
+
+ InputLayoutMap::iterator leastRecentlyUsed = mInputLayoutMap.begin();
+ for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
+ {
+ if (i->second.lastUsedTime < leastRecentlyUsed->second.lastUsedTime)
+ {
+ leastRecentlyUsed = i;
+ }
+ }
+ SafeRelease(leastRecentlyUsed->second.inputLayout);
+ mInputLayoutMap.erase(leastRecentlyUsed);
+ }
+
+ InputLayoutCounterPair inputCounterPair;
+ inputCounterPair.inputLayout = inputLayout;
+ inputCounterPair.lastUsedTime = mCounter++;
+
+ mInputLayoutMap.insert(std::make_pair(ilKey, inputCounterPair));
+ }
+
+ if (inputLayout != mCurrentIL)
+ {
+ mDeviceContext->IASetInputLayout(inputLayout);
+ mCurrentIL = inputLayout;
+ }
+
+ bool dirtyBuffers = false;
+ size_t minDiff = gl::MAX_VERTEX_ATTRIBS;
+ size_t maxDiff = 0;
+ unsigned int nextAvailableIndex = 0;
+
+ for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ ID3D11Buffer *buffer = NULL;
+
+ if (attributes[i].active)
+ {
+ VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer);
+ Buffer11 *bufferStorage = attributes[i].storage ? Buffer11::makeBuffer11(attributes[i].storage) : NULL;
+
+ buffer = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK)
+ : vertexBuffer->getBuffer();
+ }
+
+ UINT vertexStride = attributes[i].stride;
+ UINT vertexOffset = attributes[i].offset;
+
+ if (buffer != mCurrentBuffers[i] || vertexStride != mCurrentVertexStrides[i] ||
+ vertexOffset != mCurrentVertexOffsets[i])
+ {
+ dirtyBuffers = true;
+ minDiff = std::min(minDiff, static_cast<size_t>(i));
+ maxDiff = std::max(maxDiff, static_cast<size_t>(i));
+
+ mCurrentBuffers[i] = buffer;
+ mCurrentVertexStrides[i] = vertexStride;
+ mCurrentVertexOffsets[i] = vertexOffset;
+
+ // If a non null ID3D11Buffer is being assigned to mCurrentBuffers,
+ // then the next available index needs to be tracked to ensure
+ // that any instanced pointsprite emulation buffers will be properly packed.
+ if (buffer)
+ {
+ nextAvailableIndex = i + 1;
+ }
+ }
+ }
+
+ // 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.
+ if (instancedPointSpritesActive)
+ {
+ HRESULT result = S_OK;
+ const UINT pointSpriteVertexStride = sizeof(float) * 5;
+
+ if (!mPointSpriteVertexBuffer)
+ {
+ static const float pointSpriteVertices[] =
+ {
+ // Position // TexCoord
+ -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
+ -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
+ 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
+ -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
+ };
+
+ D3D11_SUBRESOURCE_DATA vertexBufferData = { pointSpriteVertices, 0, 0 };
+ D3D11_BUFFER_DESC vertexBufferDesc;
+ vertexBufferDesc.ByteWidth = sizeof(pointSpriteVertices);
+ vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ vertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
+ vertexBufferDesc.CPUAccessFlags = 0;
+ vertexBufferDesc.MiscFlags = 0;
+ vertexBufferDesc.StructureByteStride = 0;
+
+ result = mDevice->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &mPointSpriteVertexBuffer);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create instanced pointsprite emulation vertex buffer, HRESULT: 0x%08x", result);
+ }
+ }
+
+ mCurrentBuffers[nextAvailableIndex] = mPointSpriteVertexBuffer;
+ mCurrentVertexStrides[nextAvailableIndex] = pointSpriteVertexStride;
+ mCurrentVertexOffsets[nextAvailableIndex] = 0;
+
+ if (!mPointSpriteIndexBuffer)
+ {
+ // Create an index buffer and set it for pointsprite rendering
+ static const unsigned short pointSpriteIndices[] =
+ {
+ 0, 1, 2, 3, 4, 5,
+ };
+
+ D3D11_SUBRESOURCE_DATA indexBufferData = { pointSpriteIndices, 0, 0 };
+ D3D11_BUFFER_DESC indexBufferDesc;
+ indexBufferDesc.ByteWidth = sizeof(pointSpriteIndices);
+ indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+ indexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
+ indexBufferDesc.CPUAccessFlags = 0;
+ indexBufferDesc.MiscFlags = 0;
+ indexBufferDesc.StructureByteStride = 0;
+
+ result = mDevice->CreateBuffer(&indexBufferDesc, &indexBufferData, &mPointSpriteIndexBuffer);
+ if (FAILED(result))
+ {
+ SafeRelease(mPointSpriteVertexBuffer);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create instanced pointsprite emulation index buffer, HRESULT: 0x%08x", result);
+ }
+ }
+
+ // 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.
+ mDeviceContext->IASetIndexBuffer(mPointSpriteIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
+ }
+
+ if (moveFirstIndexedIntoSlotZero)
+ {
+ // In this case, we swapped the slots of the first instanced element and the first indexed element, to ensure
+ // that the first slot contains non-instanced data (required by Feature Level 9_3).
+ // We must also swap the corresponding buffers sent to IASetVertexBuffers so that the correct data is sent to each slot.
+ std::swap(mCurrentBuffers[firstIndexedElement], mCurrentBuffers[firstInstancedElement]);
+ std::swap(mCurrentVertexStrides[firstIndexedElement], mCurrentVertexStrides[firstInstancedElement]);
+ std::swap(mCurrentVertexOffsets[firstIndexedElement], mCurrentVertexOffsets[firstInstancedElement]);
+ }
+
+ if (dirtyBuffers)
+ {
+ ASSERT(minDiff <= maxDiff && maxDiff < gl::MAX_VERTEX_ATTRIBS);
+ mDeviceContext->IASetVertexBuffers(minDiff, maxDiff - minDiff + 1, mCurrentBuffers + minDiff,
+ mCurrentVertexStrides + minDiff, mCurrentVertexOffsets + minDiff);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout)
+{
+ static const unsigned int seed = 0xDEADBEEF;
+
+ std::size_t hash = 0;
+ MurmurHash3_x86_32(inputLayout.begin(), inputLayout.end() - inputLayout.begin(), seed, &hash);
+ return hash;
+}
+
+bool InputLayoutCache::compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b)
+{
+ if (a.elementCount != b.elementCount)
+ {
+ return false;
+ }
+
+ return std::equal(a.begin(), a.end(), b.begin());
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
index cc71ac3f6f..2c94c57595 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
@@ -7,11 +7,11 @@
// InputLayoutCache.h: Defines InputLayoutCache, a class that builds and caches
// D3D11 input layouts.
-#ifndef LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_
-#define LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/Error.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Error.h"
#include "common/angleutils.h"
#include <GLES2/gl2.h>
@@ -21,14 +21,14 @@
namespace gl
{
-class ProgramBinary;
+class Program;
}
namespace rx
{
struct TranslatedAttribute;
-class InputLayoutCache
+class InputLayoutCache : angle::NonCopyable
{
public:
InputLayoutCache();
@@ -39,11 +39,9 @@ class InputLayoutCache
void markDirty();
gl::Error applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
- gl::ProgramBinary *programBinary);
+ GLenum mode, gl::Program *program);
private:
- DISALLOW_COPY_AND_ASSIGN(InputLayoutCache);
-
struct InputLayoutElement
{
D3D11_INPUT_ELEMENT_DESC desc;
@@ -77,6 +75,9 @@ class InputLayoutCache
UINT mCurrentVertexStrides[gl::MAX_VERTEX_ATTRIBS];
UINT mCurrentVertexOffsets[gl::MAX_VERTEX_ATTRIBS];
+ ID3D11Buffer *mPointSpriteVertexBuffer;
+ ID3D11Buffer *mPointSpriteIndexBuffer;
+
static std::size_t hashInputLayout(const InputLayoutKey &inputLayout);
static bool compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b);
@@ -94,8 +95,9 @@ class InputLayoutCache
ID3D11Device *mDevice;
ID3D11DeviceContext *mDeviceContext;
+ D3D_FEATURE_LEVEL mFeatureLevel;
};
}
-#endif // LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
diff --git a/src/3rdparty/angle/src/common/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h
index c4a0e42bcc..81b9ea748d 100644
--- a/src/3rdparty/angle/src/common/NativeWindow.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h
@@ -9,13 +9,14 @@
// It is used for HWND (Desktop Windows) and IInspectable objects
//(Windows Store Applications).
-#ifndef COMMON_NATIVEWINDOW_H_
-#define COMMON_NATIVEWINDOW_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW_H_
-#include <EGL/eglplatform.h>
#include "common/debug.h"
#include "common/platform.h"
+#include <EGL/eglplatform.h>
+
// DXGISwapChain and DXGIFactory are typedef'd to specific required
// types. The HWND NativeWindow implementation requires IDXGISwapChain
// and IDXGIFactory and the Windows Store NativeWindow
@@ -47,28 +48,26 @@ namespace rx
class NativeWindow
{
-public:
- explicit NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display);
+ public:
+ enum RotationFlags { RotateNone = 0, RotateLeft = 1, RotateRight = 2 };
+ explicit NativeWindow(EGLNativeWindowType window);
bool initialize();
bool getClientRect(LPRECT rect);
bool isIconic();
-
-# if defined(ANGLE_ENABLE_D3D11)
- typedef ID3D11Device Device;
-#else
- typedef IDirect3DDevice9 Device;
+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ RotationFlags rotationFlags() const;
#endif
- HRESULT createSwapChain(Device* device, DXGIFactory* factory,
+ static bool isValidNativeWindow(EGLNativeWindowType window);
+
+ HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory,
DXGI_FORMAT format, UINT width, UINT height,
DXGISwapChain** swapChain);
inline EGLNativeWindowType getNativeWindow() const { return mWindow; }
- inline EGLNativeDisplayType getNativeDisplay() const { return mDisplay; }
private:
EGLNativeWindowType mWindow;
- EGLNativeDisplayType mDisplay;
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
std::shared_ptr<InspectableNativeWindow> mImpl;
@@ -76,7 +75,6 @@ public:
};
-bool IsValidEGLNativeWindowType(EGLNativeWindowType window);
}
-#endif // COMMON_NATIVEWINDOW_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
index 6a3d3475ee..5fd5237d90 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
@@ -9,24 +9,24 @@
// Used to implement pixel transfers from unpack and to pack buffers.
//
-#include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
-#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/Context.h"
+#include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
// Precompiled shaders
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexturevs.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexturegs.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture_4fps.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture_4ips.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture_4uips.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h"
+#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"
namespace rx
{
@@ -133,13 +133,10 @@ gl::Error PixelTransfer11::loadResources()
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture vertex shader.");
}
- if (!mRenderer->isLevel9())
+ mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
+ if (!mBufferToTextureGS)
{
- mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
- if (!mBufferToTextureGS)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader.");
- }
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader.");
}
gl::Error error = buildShaderMap();
@@ -167,17 +164,18 @@ void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, cons
unsigned int alignmentBytes = static_cast<unsigned int>(unpack.alignment);
unsigned int alignmentPixels = (alignmentBytes <= bytesPerPixel ? 1 : alignmentBytes / bytesPerPixel);
- parametersOut->FirstPixelOffset = offset;
- parametersOut->PixelsPerRow = static_cast<unsigned int>(destArea.width);
+ 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;
}
-gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
{
gl::Error error = loadResources();
@@ -202,9 +200,9 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac
// 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::GetInternalFormatInfo(destinationFormat).format;
- GLenum sourceFormat = gl::GetFormatTypeInfo(unsizedFormat, sourcePixelsType).internalFormat;
+ GLenum sourceFormat = gl::GetSizedInternalFormat(unsizedFormat, sourcePixelsType);
- const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat);
+ const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat, mRenderer->getFeatureLevel());
DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat;
ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN);
Buffer11 *bufferStorage11 = Buffer11::makeBuffer11(sourceBuffer.getImplementation());
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h
index 29552140bb..1672121ec7 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h
@@ -8,10 +8,10 @@
// Buffer-to-Texture and Texture-to-Buffer data transfers.
// Used to implement pixel unpack and pixel pack buffers in ES3.
-#ifndef LIBGLESV2_PIXELTRANSFER11_H_
-#define LIBGLESV2_PIXELTRANSFER11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
#include "common/platform.h"
@@ -32,7 +32,7 @@ struct PixelUnpackState;
namespace rx
{
class Renderer11;
-class RenderTarget;
+class RenderTargetD3D;
class PixelTransfer11
{
@@ -45,7 +45,7 @@ class PixelTransfer11
// destRenderTarget: individual slice/layer of a target texture
// destinationFormat/sourcePixelsType: determines shaders + shader parameters
// destArea: the sub-section of destRenderTarget to copy to
- gl::Error copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ gl::Error copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
private:
@@ -60,6 +60,7 @@ class PixelTransfer11
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,
@@ -85,4 +86,4 @@ class PixelTransfer11
}
-#endif // LIBGLESV2_PIXELTRANSFER11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
index 17ab1f8ab3..4979ff51a9 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
@@ -6,14 +6,20 @@
// Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl.
-#include "libGLESv2/renderer/d3d/d3d11/Query11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/d3d11/Query11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "common/utilities.h"
#include <GLES2/gl2ext.h>
+#if defined(ANGLE_MINGW32_COMPAT)
+typedef struct D3D11_QUERY_DATA_SO_STATISTICS {
+ UINT64 NumPrimitivesWritten;
+ UINT64 PrimitivesStorageNeeded;
+} D3D11_QUERY_DATA_SO_STATISTICS;
+#endif
+
namespace rx
{
@@ -73,7 +79,7 @@ gl::Error Query11::getResult(GLuint *params)
if (!mQueryFinished)
{
- Sleep(0);
+ ScheduleYield();
}
}
@@ -145,8 +151,9 @@ gl::Error Query11::testQuery()
break;
}
- if (!mQueryFinished && mRenderer->testDeviceLost(true))
+ if (!mQueryFinished && mRenderer->testDeviceLost())
{
+ mRenderer->notifyDeviceLost();
return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost.");
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h
index f9ff467873..bd53fed250 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h
@@ -6,10 +6,10 @@
// Query11.h: Defines the rx::Query11 class which implements rx::QueryImpl.
-#ifndef LIBGLESV2_RENDERER_QUERY11_H_
-#define LIBGLESV2_RENDERER_QUERY11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_
-#include "libGLESv2/renderer/QueryImpl.h"
+#include "libANGLE/renderer/QueryImpl.h"
namespace rx
{
@@ -27,8 +27,6 @@ class Query11 : public QueryImpl
virtual gl::Error isResultAvailable(GLuint *available);
private:
- DISALLOW_COPY_AND_ASSIGN(Query11);
-
gl::Error testQuery();
GLuint mResult;
@@ -41,4 +39,4 @@ class Query11 : public QueryImpl
}
-#endif // LIBGLESV2_RENDERER_QUERY11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
index ab4f60bd98..4990e6bc6e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
@@ -7,14 +7,16 @@
// RenderStateCache.cpp: Defines rx::RenderStateCache, a cache of Direct3D render
// state objects.
-#include "libGLESv2/renderer/d3d/d3d11/RenderStateCache.h"
-#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
-#include "common/debug.h"
+#include <float.h>
+#include "common/debug.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "third_party/murmurhash/MurmurHash3.h"
namespace rx
@@ -92,7 +94,8 @@ gl::Error RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, co
bool mrt = false;
- const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(mRenderer->getWorkarounds());
+ const FramebufferD3D *framebufferD3D = GetImplAs<FramebufferD3D>(framebuffer);
+ const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender(mRenderer->getWorkarounds());
BlendStateKey key = { 0 };
key.blendState = blendState;
@@ -422,6 +425,16 @@ gl::Error RenderStateCache::getSamplerState(const gl::SamplerState &samplerState
samplerDesc.MinLOD = samplerState.minLod;
samplerDesc.MaxLOD = samplerState.maxLod;
+ if (mRenderer->getFeatureLevel() <= 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.maxLod >= 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;
+ }
+
ID3D11SamplerState *dx11SamplerState = NULL;
HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState);
if (FAILED(result) || !dx11SamplerState)
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h
index dfd1d84265..0099b94a04 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h
@@ -7,11 +7,11 @@
// RenderStateCache.h: Defines rx::RenderStateCache, a cache of Direct3D render
// state objects.
-#ifndef LIBGLESV2_RENDERER_RENDERSTATECACHE_H_
-#define LIBGLESV2_RENDERER_RENDERSTATECACHE_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/Error.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Error.h"
#include "common/angleutils.h"
#include <unordered_map>
@@ -25,7 +25,7 @@ namespace rx
{
class Renderer11;
-class RenderStateCache
+class RenderStateCache : angle::NonCopyable
{
public:
RenderStateCache(Renderer11 *renderer);
@@ -40,8 +40,6 @@ class RenderStateCache
gl::Error getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState);
private:
- DISALLOW_COPY_AND_ASSIGN(RenderStateCache);
-
Renderer11 *mRenderer;
unsigned long long mCounter;
@@ -110,4 +108,4 @@ class RenderStateCache
}
-#endif // LIBGLESV2_RENDERER_RENDERSTATECACHE_H_ \ No newline at end of file
+#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
index aff3453492..ecd9e13c90 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
@@ -7,12 +7,11 @@
// RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers
// retained by Renderbuffers.
-#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
namespace rx
{
@@ -177,24 +176,19 @@ static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11Depth
return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
}
-RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
+RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTargetD3D *target)
{
ASSERT(HAS_DYNAMIC_TYPE(RenderTarget11*, target));
return static_cast<RenderTarget11*>(target);
}
-void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
-{
- // Currently a no-op
-}
-
TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples)
: mWidth(width),
mHeight(height),
mDepth(depth),
mInternalFormat(internalFormat),
- mActualFormat(internalFormat),
+ mDXGIFormat(DXGI_FORMAT_UNKNOWN),
mSamples(samples),
mSubresourceIndex(0),
mTexture(resource),
@@ -223,9 +217,7 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11
D3D11_RENDER_TARGET_VIEW_DESC desc;
mRenderTarget->GetDesc(&desc);
-
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
- mActualFormat = dxgiFormatInfo.internalFormat;
+ mDXGIFormat = desc.Format;
}
}
@@ -235,7 +227,7 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11
mHeight(height),
mDepth(depth),
mInternalFormat(internalFormat),
- mActualFormat(internalFormat),
+ mDXGIFormat(DXGI_FORMAT_UNKNOWN),
mSamples(samples),
mSubresourceIndex(0),
mTexture(resource),
@@ -264,9 +256,7 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11
D3D11_DEPTH_STENCIL_VIEW_DESC desc;
mDepthStencil->GetDesc(&desc);
-
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
- mActualFormat = dxgiFormatInfo.internalFormat;
+ mDXGIFormat = desc.Format;
}
}
@@ -318,11 +308,6 @@ GLenum TextureRenderTarget11::getInternalFormat() const
return mInternalFormat;
}
-GLenum TextureRenderTarget11::getActualFormat() const
-{
- return mActualFormat;
-}
-
GLsizei TextureRenderTarget11::getSamples() const
{
return mSamples;
@@ -333,9 +318,14 @@ unsigned int TextureRenderTarget11::getSubresourceIndex() const
return mSubresourceIndex;
}
+DXGI_FORMAT TextureRenderTarget11::getDXGIFormat() const
+{
+ return mDXGIFormat;
+}
-SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, bool depth)
+SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, Renderer11 *renderer, bool depth)
: mSwapChain(swapChain),
+ mRenderer(renderer),
mDepth(depth)
{
ASSERT(mSwapChain);
@@ -365,11 +355,6 @@ GLenum SurfaceRenderTarget11::getInternalFormat() const
return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat());
}
-GLenum SurfaceRenderTarget11::getActualFormat() const
-{
- return d3d11::GetDXGIFormatInfo(d3d11::GetTextureFormatInfo(getInternalFormat()).texFormat).internalFormat;
-}
-
GLsizei SurfaceRenderTarget11::getSamples() const
{
// Our EGL surfaces do not support multisampling.
@@ -401,4 +386,9 @@ unsigned int SurfaceRenderTarget11::getSubresourceIndex() const
return 0;
}
+DXGI_FORMAT SurfaceRenderTarget11::getDXGIFormat() const
+{
+ return d3d11::GetTextureFormatInfo(getInternalFormat(), mRenderer->getFeatureLevel()).texFormat;
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
index c7babdda3f..4472a56175 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
@@ -7,24 +7,23 @@
// RenderTarget11.h: Defines a DX11-specific wrapper for ID3D11View pointers
// retained by Renderbuffers.
-#ifndef LIBGLESV2_RENDERER_RENDERTARGET11_H_
-#define LIBGLESV2_RENDERER_RENDERTARGET11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_
-#include "libGLESv2/renderer/RenderTarget.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
namespace rx
{
class SwapChain11;
+class Renderer11;
-class RenderTarget11 : public RenderTarget
+class RenderTarget11 : public RenderTargetD3D
{
public:
RenderTarget11() { }
virtual ~RenderTarget11() { }
- static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget);
-
- void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) override;
+ static RenderTarget11 *makeRenderTarget11(RenderTargetD3D *renderTarget);
virtual ID3D11Resource *getTexture() const = 0;
virtual ID3D11RenderTargetView *getRenderTargetView() const = 0;
@@ -33,8 +32,10 @@ class RenderTarget11 : public RenderTarget
virtual unsigned int getSubresourceIndex() const = 0;
+ virtual DXGI_FORMAT getDXGIFormat() const = 0;
+
private:
- DISALLOW_COPY_AND_ASSIGN(RenderTarget11);
+ D3D_FEATURE_LEVEL mFeatureLevel;
};
class TextureRenderTarget11 : public RenderTarget11
@@ -51,7 +52,6 @@ class TextureRenderTarget11 : public RenderTarget11
GLsizei getHeight() const override;
GLsizei getDepth() const override;
GLenum getInternalFormat() const override;
- GLenum getActualFormat() const override;
GLsizei getSamples() const override;
ID3D11Resource *getTexture() const override;
@@ -61,14 +61,14 @@ class TextureRenderTarget11 : public RenderTarget11
unsigned int getSubresourceIndex() const override;
- private:
- DISALLOW_COPY_AND_ASSIGN(TextureRenderTarget11);
+ DXGI_FORMAT getDXGIFormat() const override;
+ private:
GLsizei mWidth;
GLsizei mHeight;
GLsizei mDepth;
GLenum mInternalFormat;
- GLenum mActualFormat;
+ DXGI_FORMAT mDXGIFormat;
GLsizei mSamples;
unsigned int mSubresourceIndex;
@@ -81,14 +81,13 @@ class TextureRenderTarget11 : public RenderTarget11
class SurfaceRenderTarget11 : public RenderTarget11
{
public:
- SurfaceRenderTarget11(SwapChain11 *swapChain, bool depth);
+ SurfaceRenderTarget11(SwapChain11 *swapChain, Renderer11 *renderer, bool depth);
virtual ~SurfaceRenderTarget11();
GLsizei getWidth() const override;
GLsizei getHeight() const override;
GLsizei getDepth() const override;
GLenum getInternalFormat() const override;
- GLenum getActualFormat() const override;
GLsizei getSamples() const override;
ID3D11Resource *getTexture() const override;
@@ -98,13 +97,14 @@ class SurfaceRenderTarget11 : public RenderTarget11
unsigned int getSubresourceIndex() const override;
- private:
- DISALLOW_COPY_AND_ASSIGN(SurfaceRenderTarget11);
+ DXGI_FORMAT getDXGIFormat() const override;
+ private:
SwapChain11 *mSwapChain;
+ Renderer11 *mRenderer;
bool mDepth;
};
}
-#endif // LIBGLESV2_RENDERER_RENDERTARGET11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index 777308e6cc..5291a3a086 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -6,46 +6,49 @@
// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
-#include "libGLESv2/main.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/State.h"
-#include "libGLESv2/renderer/d3d/ProgramD3D.h"
-#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
-#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
-#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
-#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
-#include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
-#include "libGLESv2/renderer/d3d/VertexDataManager.h"
-#include "libGLESv2/renderer/d3d/IndexDataManager.h"
-#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Query11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Fence11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Clear11.h"
-#include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/VertexArray11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
-#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
-
-#include "libEGL/Display.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "common/utilities.h"
#include "common/tls.h"
-
-#include <EGL/eglext.h>
+#include "libANGLE/Buffer.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/renderer/d3d/CompilerD3D.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/TransformFeedbackD3D.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/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/Query11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
+#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
+#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.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 <sstream>
+#include <EGL/eglext.h>
// 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.
@@ -59,46 +62,174 @@
#define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1
#endif
+#ifndef __d3d11sdklayers_h__
+#define D3D11_MESSAGE_CATEGORY UINT
+#define D3D11_MESSAGE_SEVERITY UINT
+#define D3D11_MESSAGE_ID UINT
+struct D3D11_MESSAGE;
+typedef struct D3D11_INFO_QUEUE_FILTER_DESC
+{
+ UINT NumCategories;
+ D3D11_MESSAGE_CATEGORY *pCategoryList;
+ UINT NumSeverities;
+ D3D11_MESSAGE_SEVERITY *pSeverityList;
+ UINT NumIDs;
+ D3D11_MESSAGE_ID *pIDList;
+} D3D11_INFO_QUEUE_FILTER_DESC;
+typedef struct D3D11_INFO_QUEUE_FILTER
+{
+ D3D11_INFO_QUEUE_FILTER_DESC AllowList;
+ D3D11_INFO_QUEUE_FILTER_DESC DenyList;
+} D3D11_INFO_QUEUE_FILTER;
+static const IID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 };
+MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") ID3D11InfoQueue : public IUnknown
+{
+public:
+ virtual HRESULT __stdcall SetMessageCountLimit(UINT64) = 0;
+ virtual void __stdcall ClearStoredMessages() = 0;
+ virtual HRESULT __stdcall GetMessage(UINT64, D3D11_MESSAGE *, SIZE_T *) = 0;
+ virtual UINT64 __stdcall GetNumMessagesAllowedByStorageFilter() = 0;
+ virtual UINT64 __stdcall GetNumMessagesDeniedByStorageFilter() = 0;
+ virtual UINT64 __stdcall GetNumStoredMessages() = 0;
+ virtual UINT64 __stdcall GetNumStoredMessagesAllowedByRetrievalFilter() = 0;
+ virtual UINT64 __stdcall GetNumMessagesDiscardedByMessageCountLimit() = 0;
+ virtual UINT64 __stdcall GetMessageCountLimit() = 0;
+ virtual HRESULT __stdcall AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
+ virtual HRESULT __stdcall GetStorageFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
+ virtual void __stdcall ClearStorageFilter() = 0;
+ virtual HRESULT __stdcall PushEmptyStorageFilter() = 0;
+ virtual HRESULT __stdcall PushCopyOfStorageFilter() = 0;
+ virtual HRESULT __stdcall PushStorageFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
+ virtual void __stdcall PopStorageFilter() = 0;
+ virtual UINT __stdcall GetStorageFilterStackSize() = 0;
+ virtual HRESULT __stdcall AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
+ virtual HRESULT __stdcall GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
+ virtual void __stdcall ClearRetrievalFilter() = 0;
+ virtual HRESULT __stdcall PushEmptyRetrievalFilter() = 0;
+ virtual HRESULT __stdcall PushCopyOfRetrievalFilter() = 0;
+ virtual HRESULT __stdcall PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
+ virtual void __stdcall PopRetrievalFilter() = 0;
+ virtual UINT __stdcall GetRetrievalFilterStackSize() = 0;
+ virtual HRESULT __stdcall AddMessage(D3D11_MESSAGE_CATEGORY, D3D11_MESSAGE_SEVERITY, D3D11_MESSAGE_ID, LPCSTR) = 0;
+ virtual HRESULT __stdcall AddApplicationMessage(D3D11_MESSAGE_SEVERITY, LPCSTR) = 0;
+ virtual HRESULT __stdcall SetBreakOnCategory(D3D11_MESSAGE_CATEGORY, BOOL) = 0;
+ virtual HRESULT __stdcall SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY, BOOL) = 0;
+ virtual HRESULT __stdcall SetBreakOnID(D3D11_MESSAGE_ID, BOOL) = 0;
+ virtual BOOL __stdcall GetBreakOnCategory(D3D11_MESSAGE_CATEGORY) = 0;
+ virtual BOOL __stdcall GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY) = 0;
+ virtual BOOL __stdcall GetBreakOnID(D3D11_MESSAGE_ID) = 0;
+ virtual void __stdcall SetMuteDebugOutput(BOOL) = 0;
+ virtual BOOL __stdcall GetMuteDebugOutput() = 0;
+};
+#endif
+
namespace rx
{
namespace
{
-static const DXGI_FORMAT RenderTargetFormats[] =
- {
- DXGI_FORMAT_B8G8R8A8_UNORM,
- DXGI_FORMAT_R8G8B8A8_UNORM
- };
-
-static const DXGI_FORMAT DepthStencilFormats[] =
- {
- DXGI_FORMAT_UNKNOWN,
- DXGI_FORMAT_D24_UNORM_S8_UINT,
- DXGI_FORMAT_D16_UNORM
- };
enum
{
MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
};
+// dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state.
+static const uintptr_t DirtyPointer = static_cast<uintptr_t>(-1);
+
+static bool ImageIndexConflictsWithSRV(const gl::ImageIndex *index, D3D11_SHADER_RESOURCE_VIEW_DESC desc)
+{
+ unsigned mipLevel = index->mipIndex;
+ unsigned layerIndex = index->layerIndex;
+ GLenum type = index->type;
+
+ switch (desc.ViewDimension)
+ {
+ case D3D11_SRV_DIMENSION_TEXTURE2D:
+ {
+ unsigned maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip;
+ maxSrvMip = (desc.Texture2D.MipLevels == -1) ? INT_MAX : maxSrvMip;
+
+ unsigned mipMin = index->mipIndex;
+ unsigned mipMax = (layerIndex == -1) ? INT_MAX : layerIndex;
+
+ return type == GL_TEXTURE_2D && RangeUI(mipMin, mipMax).intersects(RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip));
+ }
+
+ case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
+ {
+ unsigned maxSrvMip = desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip;
+ maxSrvMip = (desc.Texture2DArray.MipLevels == -1) ? INT_MAX : maxSrvMip;
+
+ unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize;
+
+ // Cube maps can be mapped to Texture2DArray SRVs
+ return (type == GL_TEXTURE_2D_ARRAY || gl::IsCubeMapTextureTarget(type)) &&
+ desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip &&
+ desc.Texture2DArray.FirstArraySlice <= layerIndex && layerIndex < maxSlice;
+ }
+
+ case D3D11_SRV_DIMENSION_TEXTURECUBE:
+ {
+ unsigned maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip;
+ maxSrvMip = (desc.TextureCube.MipLevels == -1) ? INT_MAX : maxSrvMip;
+
+ return gl::IsCubeMapTextureTarget(type) &&
+ desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
+ }
+
+ case D3D11_SRV_DIMENSION_TEXTURE3D:
+ {
+ unsigned maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip;
+ maxSrvMip = (desc.Texture3D.MipLevels == -1) ? INT_MAX : maxSrvMip;
+
+ return type == GL_TEXTURE_3D &&
+ desc.Texture3D.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
+ }
+ default:
+ // We only handle the cases corresponding to valid image indexes
+ UNIMPLEMENTED();
+ }
+
+ return false;
+}
+
// Does *not* increment the resource ref count!!
-ID3D11Resource *GetSRVResource(ID3D11ShaderResourceView *srv)
+ID3D11Resource *GetViewResource(ID3D11View *view)
{
ID3D11Resource *resource = NULL;
- ASSERT(srv);
- srv->GetResource(&resource);
+ ASSERT(view);
+ view->GetResource(&resource);
resource->Release();
return resource;
}
+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 = 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 = rx::roundUp(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
}
-Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes)
+}
+
+Renderer11::Renderer11(egl::Display *display)
: RendererD3D(display),
- mDc(hDc),
mStateCache(this)
{
+ // Initialize global annotator
+ gl::InitializeDebugAnnotations(&mAnnotator);
+
mVertexDataManager = NULL;
mIndexDataManager = NULL;
@@ -110,15 +241,18 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const eg
mClear = NULL;
+ mTrim = NULL;
+
mSyncQuery = NULL;
+ mSupportsConstantBufferOffsets = false;
+
mD3d11Module = NULL;
mDxgiModule = NULL;
- mDeviceLost = false;
-
mDevice = NULL;
mDeviceContext = NULL;
+ mDeviceContext1 = NULL;
mDxgiAdapter = NULL;
mDxgiFactory = NULL;
@@ -127,9 +261,12 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const eg
mAppliedVertexShader = NULL;
mAppliedGeometryShader = NULL;
- mCurPointGeometryShader = NULL;
mAppliedPixelShader = NULL;
+ mAppliedNumXFBBindings = static_cast<size_t>(-1);
+
+ const auto &attributes = mDisplay->getAttributeMap();
+
EGLint requestedMajorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE);
EGLint requestedMinorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE);
@@ -153,31 +290,45 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const eg
}
}
-#if !defined(ANGLE_ENABLE_D3D9)
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9)
+#else
+ if (requestedMajorVersion == 9 && requestedMinorVersion == 3)
+#endif
{
- if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3)
- {
- mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3);
- }
- if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 2)
- {
- mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_2);
- }
- if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
- {
- mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_1);
- }
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3);
}
-#endif
- mDriverType = (attributes.get(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_FALSE) == EGL_TRUE) ? D3D_DRIVER_TYPE_WARP
- : D3D_DRIVER_TYPE_HARDWARE;
+ EGLint requestedDeviceType = 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:
+ mDriverType = D3D_DRIVER_TYPE_HARDWARE;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE:
+ mDriverType = D3D_DRIVER_TYPE_WARP;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE:
+ mDriverType = D3D_DRIVER_TYPE_REFERENCE;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
+ mDriverType = D3D_DRIVER_TYPE_NULL;
+ break;
+
+ default:
+ UNREACHABLE();
+ }
}
Renderer11::~Renderer11()
{
release();
+
+ gl::UninitializeDebugAnnotations();
}
Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
@@ -190,11 +341,13 @@ Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
#define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081)
#endif
-EGLint Renderer11::initialize()
+egl::Error Renderer11::initialize()
{
if (!mCompiler.initialize())
{
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_COMPILER_ERROR,
+ "Failed to initialize compiler.");
}
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
@@ -203,8 +356,9 @@ EGLint Renderer11::initialize()
if (mD3d11Module == NULL || mDxgiModule == NULL)
{
- ERR("Could not load D3D11 or DXGI library - aborting!\n");
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_MISSING_DEP,
+ "Could not load D3D11 or DXGI library.");
}
// create the D3D11 device
@@ -213,8 +367,9 @@ EGLint Renderer11::initialize()
if (D3D11CreateDevice == NULL)
{
- ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_MISSING_DEP,
+ "Could not retrieve D3D11CreateDevice address.");
}
#endif
@@ -250,29 +405,29 @@ EGLint Renderer11::initialize()
&mFeatureLevel,
&mDeviceContext);
+ if (result == E_INVALIDARG)
+ {
+ // Cleanup done by destructor through glDestroyRenderer
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_CREATEDEVICE_INVALIDARG,
+ "Could not create D3D11 device.");
+ }
+
if (!mDevice || FAILED(result))
{
- ERR("Could not create D3D11 device - aborting!\n");
- return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer
+ // Cleanup done by destructor through glDestroyRenderer
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_CREATEDEVICE_ERROR,
+ "Could not create D3D11 device.");
}
}
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED");
- if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1"))
- {
- ID3D10Multithread *multithread;
- result = mDevice->QueryInterface(IID_PPV_ARGS(&multithread));
- ASSERT(SUCCEEDED(result));
- result = multithread->SetMultithreadProtected(true);
- ASSERT(SUCCEEDED(result));
- multithread->Release();
- }
#if !ANGLE_SKIP_DXGI_1_2_CHECK
// 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(mDc);
+ HWND hwnd = WindowFromDC(mDisplay->getNativeDisplayId());
if (hwnd)
{
DWORD currentProcessId = GetCurrentProcessId();
@@ -291,34 +446,72 @@ EGLint Renderer11::initialize()
result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void**)&dxgiDevice2);
if (FAILED(result))
{
- ERR("DXGI 1.2 required to present to HWNDs owned by another process.\n");
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_INCOMPATIBLE_DXGI,
+ "DXGI 1.2 required to present to HWNDs owned by another process.");
}
SafeRelease(dxgiDevice2);
}
#endif
#endif
+ // Cast the DeviceContext to a DeviceContext1.
+ // This could fail on Windows 7 without the Platform Update.
+ // Don't error in this case- just don't use mDeviceContext1.
+#if defined(ANGLE_ENABLE_D3D11_1)
+ mDeviceContext1 = d3d11::DynamicCastComObject<ID3D11DeviceContext1>(mDeviceContext);
+#endif
+
IDXGIDevice *dxgiDevice = NULL;
result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
if (FAILED(result))
{
- ERR("Could not query DXGI device - aborting!\n");
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_OTHER_ERROR,
+ "Could not query DXGI device.");
}
result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
if (FAILED(result))
{
- ERR("Could not retrieve DXGI adapter - aborting!\n");
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_OTHER_ERROR,
+ "Could not retrieve DXGI adapter");
}
SafeRelease(dxgiDevice);
- mDxgiAdapter->GetDesc(&mAdapterDescription);
+#if defined(ANGLE_ENABLE_D3D11_1)
+ 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 (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && dxgiAdapter2 != NULL)
+ {
+ DXGI_ADAPTER_DESC2 adapterDesc2 = {0};
+ dxgiAdapter2->GetDesc2(&adapterDesc2);
+
+ // 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
+ {
+ mDxgiAdapter->GetDesc(&mAdapterDescription);
+ }
+
+ SafeRelease(dxgiAdapter2);
+#endif
+
memset(mDescription, 0, sizeof(mDescription));
wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
@@ -326,14 +519,15 @@ EGLint Renderer11::initialize()
if (!mDxgiFactory || FAILED(result))
{
- ERR("Could not create DXGI factory - aborting!\n");
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D11_INIT_OTHER_ERROR,
+ "Could not create DXGI factory.");
}
// Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
ID3D11InfoQueue *infoQueue;
- result = mDevice->QueryInterface(IID_ID3D11InfoQueue, (void **)&infoQueue);
+ result = mDevice->QueryInterface(IID_ID3D11InfoQueue, (void **)&infoQueue);
if (SUCCEEDED(result))
{
@@ -353,7 +547,7 @@ EGLint Renderer11::initialize()
initializeDevice();
- return EGL_SUCCESS;
+ return egl::Error(EGL_SUCCESS);
}
// do any one-time device initialization
@@ -366,7 +560,7 @@ void Renderer11::initializeDevice()
ASSERT(!mVertexDataManager && !mIndexDataManager);
mVertexDataManager = new VertexDataManager(this);
- mIndexDataManager = new IndexDataManager(this);
+ mIndexDataManager = new IndexDataManager(this, getRendererClass());
ASSERT(!mBlit);
mBlit = new Blit11(this);
@@ -374,11 +568,32 @@ void Renderer11::initializeDevice()
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 = 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);
const gl::Caps &rendererCaps = getRendererCaps();
+#if defined(ANGLE_ENABLE_D3D11_1)
+ if (getDeviceContext1IfSupported())
+ {
+ D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options;
+ mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
+ mSupportsConstantBufferOffsets = (d3d11Options.ConstantBufferOffsetting != FALSE);
+ }
+#endif
+
mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
@@ -391,96 +606,139 @@ void Renderer11::initializeDevice()
markAllStateDirty();
}
-int Renderer11::generateConfigs(ConfigDesc **configDescList)
+egl::ConfigSet Renderer11::generateConfigs() const
{
- unsigned int numRenderFormats = ArraySize(RenderTargetFormats);
- unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
- (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
- int numConfigs = 0;
+ static const GLenum colorBufferFormats[] =
+ {
+ GL_BGRA8_EXT,
+ GL_RGBA8_OES,
+ };
- for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
+ static const GLenum depthStencilBufferFormats[] =
{
- const d3d11::DXGIFormat &renderTargetFormatInfo = d3d11::GetDXGIFormatInfo(RenderTargetFormats[formatIndex]);
- const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat);
- if (renderTargetFormatCaps.renderable)
+ GL_NONE,
+ GL_DEPTH24_STENCIL8_OES,
+ GL_DEPTH_COMPONENT16,
+ };
+
+ const gl::Caps &rendererCaps = getRendererCaps();
+ const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps();
+
+ 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.renderable)
{
- for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
+ for (size_t depthStencilIndex = 0; depthStencilIndex < ArraySize(depthStencilBufferFormats); depthStencilIndex++)
{
- const d3d11::DXGIFormat &depthStencilFormatInfo = d3d11::GetDXGIFormatInfo(DepthStencilFormats[depthStencilIndex]);
- const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat);
- if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == DXGI_FORMAT_UNKNOWN)
+ GLenum depthStencilBufferInternalFormat = depthStencilBufferFormats[depthStencilIndex];
+ const gl::TextureCaps &depthStencilBufferFormatCaps = rendererTextureCaps.get(depthStencilBufferInternalFormat);
+ if (depthStencilBufferFormatCaps.renderable || depthStencilBufferInternalFormat == GL_NONE)
{
- ConfigDesc newConfig;
- newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat;
- newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat;
- newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
- newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast
- newConfig.es3Capable = true;
-
- (*configDescList)[numConfigs++] = newConfig;
+ const gl::InternalFormat &colorBufferFormatInfo = gl::GetInternalFormatInfo(colorBufferInternalFormat);
+ const gl::InternalFormat &depthStencilBufferFormatInfo = gl::GetInternalFormatInfo(depthStencilBufferInternalFormat);
+
+ 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;
+ config.configID = static_cast<EGLint>(configs.size() + 1);
+ // Can only support a conformant ES2 with feature level greater than 10.0.
+ config.conformant = (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) ? (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR) : EGL_NONE;
+ config.configCaveat = config.conformant == EGL_NONE ? EGL_NON_CONFORMANT_CONFIG : EGL_NONE;
+ 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.0
+ config.renderableType = EGL_OPENGL_ES2_BIT | ((mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) ? EGL_OPENGL_ES3_BIT_KHR : 0);
+ 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;
+
+ configs.add(config);
}
}
}
}
- return numConfigs;
+ ASSERT(configs.size() > 0);
+ return configs;
}
-void Renderer11::deleteConfigs(ConfigDesc *configDescList)
+gl::Error Renderer11::flush()
{
- delete [] (configDescList);
+ mDeviceContext->Flush();
+ return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::sync(bool block)
+gl::Error Renderer11::finish()
{
- if (block)
+ HRESULT result;
+
+ if (!mSyncQuery)
{
- HRESULT result;
+ D3D11_QUERY_DESC queryDesc;
+ queryDesc.Query = D3D11_QUERY_EVENT;
+ queryDesc.MiscFlags = 0;
- if (!mSyncQuery)
+ result = mDevice->CreateQuery(&queryDesc, &mSyncQuery);
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
{
- D3D11_QUERY_DESC queryDesc;
- queryDesc.Query = D3D11_QUERY_EVENT;
- queryDesc.MiscFlags = 0;
-
- result = mDevice->CreateQuery(&queryDesc, &mSyncQuery);
- ASSERT(SUCCEEDED(result));
- if (FAILED(result))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result);
- }
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result);
}
+ }
- mDeviceContext->End(mSyncQuery);
- mDeviceContext->Flush();
+ mDeviceContext->End(mSyncQuery);
+ mDeviceContext->Flush();
- do
+ do
+ {
+ result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
+ if (FAILED(result))
{
- result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
- if (FAILED(result))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result);
- }
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result);
+ }
- // Keep polling, but allow other threads to do something useful first
- Sleep(0);
+ // Keep polling, but allow other threads to do something useful first
+ ScheduleYield();
- if (testDeviceLost(true))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while waiting for sync.");
- }
+ if (testDeviceLost())
+ {
+ mDisplay->notifyDeviceLost();
+ return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while waiting for sync.");
}
- while (result == S_FALSE);
- }
- else
- {
- mDeviceContext->Flush();
}
+ while (result == S_FALSE);
return gl::Error(GL_NO_ERROR);
}
-SwapChain *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+SwapChainD3D *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
{
return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
}
@@ -489,17 +747,23 @@ gl::Error Renderer11::generateSwizzle(gl::Texture *texture)
{
if (texture)
{
- TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
ASSERT(textureD3D);
- TextureStorage *texStorage = textureD3D->getNativeTexture();
+ TextureStorage *texStorage = nullptr;
+ gl::Error error = textureD3D->getNativeTexture(&texStorage);
+ if (error.isError())
+ {
+ return error;
+ }
+
if (texStorage)
{
TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
- gl::Error error = storage11->generateSwizzles(texture->getSamplerState().swizzleRed,
- texture->getSamplerState().swizzleGreen,
- texture->getSamplerState().swizzleBlue,
- texture->getSamplerState().swizzleAlpha);
+ error = storage11->generateSwizzles(texture->getSamplerState().swizzleRed,
+ texture->getSamplerState().swizzleGreen,
+ texture->getSamplerState().swizzleBlue,
+ texture->getSamplerState().swizzleAlpha);
if (error.isError())
{
return error;
@@ -513,9 +777,20 @@ gl::Error Renderer11::generateSwizzle(gl::Texture *texture)
gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerStateParam)
{
// Make sure to add the level offset for our tiny compressed texture workaround
- TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
+ TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
gl::SamplerState samplerStateInternal = samplerStateParam;
- samplerStateInternal.baseLevel += textureD3D->getNativeTexture()->getTopLevel();
+
+ TextureStorage *storage = nullptr;
+ gl::Error error = textureD3D->getNativeTexture(&storage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ // Storage should exist, texture should be complete
+ ASSERT(storage);
+
+ samplerStateInternal.baseLevel += storage->getTopLevel();
if (type == gl::SAMPLER_PIXEL)
{
@@ -524,7 +799,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Textu
if (mForceSetPixelSamplerStates[index] || memcmp(&samplerStateInternal, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = NULL;
- gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
+ error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
if (error.isError())
{
return error;
@@ -545,7 +820,7 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Textu
if (mForceSetVertexSamplerStates[index] || memcmp(&samplerStateInternal, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
{
ID3D11SamplerState *dxSamplerState = NULL;
- gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
+ error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
if (error.isError())
{
return error;
@@ -570,9 +845,17 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t
if (texture)
{
- TextureD3D *textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
- TextureStorage *texStorage = textureImpl->getNativeTexture();
- ASSERT(texStorage != NULL);
+ TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
+
+ TextureStorage *texStorage = nullptr;
+ gl::Error error = textureImpl->getNativeTexture(&texStorage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ // Texture should be complete and have a storage
+ ASSERT(texStorage);
TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
@@ -580,7 +863,7 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t
gl::SamplerState samplerState = texture->getSamplerState();
samplerState.baseLevel += storage11->getTopLevel();
- gl::Error error = storage11->getSRV(samplerState, &textureSRV);
+ error = storage11->getSRV(samplerState, &textureSRV);
if (error.isError())
{
return error;
@@ -601,11 +884,23 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[])
+gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
+ const GLint vertexUniformBuffers[],
+ const GLint fragmentUniformBuffers[])
{
- for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++)
+ for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < data.caps->maxVertexUniformBlocks; uniformBufferIndex++)
{
- const gl::Buffer *uniformBuffer = vertexUniformBuffers[uniformBufferIndex];
+ GLint binding = vertexUniformBuffers[uniformBufferIndex];
+
+ if (binding == -1)
+ {
+ continue;
+ }
+
+ gl::Buffer *uniformBuffer = data.state->getIndexedUniformBuffer(binding);
+ GLintptr uniformBufferOffset = data.state->getIndexedUniformBufferOffset(binding);
+ GLsizeiptr uniformBufferSize = data.state->getIndexedUniformBufferSize(binding);
+
if (uniformBuffer)
{
Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation());
@@ -616,18 +911,46 @@ gl::Error Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[]
return gl::Error(GL_OUT_OF_MEMORY);
}
- if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial())
+ if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial() ||
+ mCurrentConstantBufferVSOffset[uniformBufferIndex] != uniformBufferOffset ||
+ mCurrentConstantBufferVSSize[uniformBufferIndex] != uniformBufferSize)
{
- mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers() + uniformBufferIndex,
- 1, &constantBuffer);
+#if defined(ANGLE_ENABLE_D3D11_1)
+ if (mSupportsConstantBufferOffsets && uniformBufferSize != 0)
+ {
+ UINT firstConstant = 0, numConstants = 0;
+ CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, &firstConstant, &numConstants);
+ mDeviceContext1->VSSetConstantBuffers1(getReservedVertexUniformBuffers() + uniformBufferIndex,
+ 1, &constantBuffer, &firstConstant, &numConstants);
+ }
+ else
+#endif
+ {
+ ASSERT(uniformBufferOffset == 0);
+ mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers() + uniformBufferIndex,
+ 1, &constantBuffer);
+ }
+
mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial();
+ mCurrentConstantBufferVSOffset[uniformBufferIndex] = uniformBufferOffset;
+ mCurrentConstantBufferVSSize[uniformBufferIndex] = uniformBufferSize;
}
}
}
- for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++)
+ for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < data.caps->maxFragmentUniformBlocks; uniformBufferIndex++)
{
- const gl::Buffer *uniformBuffer = fragmentUniformBuffers[uniformBufferIndex];
+ GLint binding = fragmentUniformBuffers[uniformBufferIndex];
+
+ if (binding == -1)
+ {
+ continue;
+ }
+
+ gl::Buffer *uniformBuffer = data.state->getIndexedUniformBuffer(binding);
+ GLintptr uniformBufferOffset = data.state->getIndexedUniformBufferOffset(binding);
+ GLsizeiptr uniformBufferSize = data.state->getIndexedUniformBufferSize(binding);
+
if (uniformBuffer)
{
Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation());
@@ -638,11 +961,29 @@ gl::Error Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[]
return gl::Error(GL_OUT_OF_MEMORY);
}
- if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial())
+ if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial() ||
+ mCurrentConstantBufferPSOffset[uniformBufferIndex] != uniformBufferOffset ||
+ mCurrentConstantBufferPSSize[uniformBufferIndex] != uniformBufferSize)
{
- mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers() + uniformBufferIndex,
- 1, &constantBuffer);
+#if defined(ANGLE_ENABLE_D3D11_1)
+ if (mSupportsConstantBufferOffsets && uniformBufferSize != 0)
+ {
+ UINT firstConstant = 0, numConstants = 0;
+ CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, &firstConstant, &numConstants);
+ mDeviceContext1->PSSetConstantBuffers1(getReservedFragmentUniformBuffers() + uniformBufferIndex,
+ 1, &constantBuffer, &firstConstant, &numConstants);
+ }
+ else
+#endif
+ {
+ ASSERT(uniformBufferOffset == 0);
+ mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers() + uniformBufferIndex,
+ 1, &constantBuffer);
+ }
+
mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial();
+ mCurrentConstantBufferPSOffset[uniformBufferIndex] = uniformBufferOffset;
+ mCurrentConstantBufferPSSize[uniformBufferIndex] = uniformBufferSize;
}
}
}
@@ -739,8 +1080,8 @@ gl::Error Renderer11::setDepthStencilState(const gl::DepthStencilState &depthSte
// 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
- META_ASSERT(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF);
- META_ASSERT(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF);
+ 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 = std::min<UINT>(stencilRef, 0xFFu);
mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
@@ -799,33 +1140,67 @@ void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float z
actualZFar = 1.0f;
}
- const gl::Caps& caps = getRendererCaps();
-
- // Clamp width and height first to the gl maximum, then clamp further if we extend past the D3D maximum bounds
- D3D11_VIEWPORT dxViewport;
- dxViewport.TopLeftX = gl::clamp(actualViewport.x, -static_cast<int>(caps.maxViewportWidth), static_cast<int>(caps.maxViewportWidth));
- dxViewport.TopLeftY = gl::clamp(actualViewport.y, -static_cast<int>(caps.maxViewportHeight), static_cast<int>(caps.maxViewportHeight));
- dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(caps.maxViewportWidth - dxViewport.TopLeftX));
- dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(caps.maxViewportHeight - dxViewport.TopLeftY));
- dxViewport.MinDepth = actualZNear;
- dxViewport.MaxDepth = actualZFar;
-
bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
actualZNear != mCurNear || actualZFar != mCurFar;
if (viewportChanged)
{
+ const gl::Caps& caps = getRendererCaps();
+
+ int dxMaxViewportBoundsX = static_cast<int>(caps.maxViewportWidth);
+ int dxMaxViewportBoundsY = static_cast<int>(caps.maxViewportHeight);
+ int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
+ int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
+
+ if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget.
+ dxMaxViewportBoundsX = mRenderTargetDesc.width;
+ dxMaxViewportBoundsY = mRenderTargetDesc.height;
+ dxMinViewportBoundsX = 0;
+ dxMinViewportBoundsY = 0;
+ }
+
+ int dxViewportTopLeftX = gl::clamp(actualViewport.x, dxMinViewportBoundsX, dxMaxViewportBoundsX);
+ int dxViewportTopLeftY = gl::clamp(actualViewport.y, dxMinViewportBoundsY, dxMaxViewportBoundsY);
+ int dxViewportWidth = gl::clamp(actualViewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX);
+ int dxViewportHeight = gl::clamp(actualViewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY);
+
+ D3D11_VIEWPORT dxViewport;
+ dxViewport.TopLeftX = static_cast<float>(dxViewportTopLeftX);
+ dxViewport.TopLeftY = static_cast<float>(dxViewportTopLeftY);
+ dxViewport.Width = static_cast<float>(dxViewportWidth);
+ dxViewport.Height = static_cast<float>(dxViewportHeight);
+ dxViewport.MinDepth = actualZNear;
+ dxViewport.MaxDepth = actualZFar;
+
mDeviceContext->RSSetViewports(1, &dxViewport);
mCurViewport = actualViewport;
mCurNear = actualZNear;
mCurFar = actualZFar;
+ // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders using viewAdjust (like the D3D9 renderer).
+ if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ mVertexConstants.viewAdjust[0] = static_cast<float>((actualViewport.width - dxViewportWidth) + 2 * (actualViewport.x - dxViewportTopLeftX)) / dxViewport.Width;
+ mVertexConstants.viewAdjust[1] = static_cast<float>((actualViewport.height - dxViewportHeight) + 2 * (actualViewport.y - dxViewportTopLeftY)) / dxViewport.Height;
+ mVertexConstants.viewAdjust[2] = static_cast<float>(actualViewport.width) / dxViewport.Width;
+ mVertexConstants.viewAdjust[3] = static_cast<float>(actualViewport.height) / dxViewport.Height;
+ }
+
mPixelConstants.viewCoords[0] = actualViewport.width * 0.5f;
mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f;
mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f);
mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
+ // Instanced pointsprite emulation requires ViewCoords to be defined in the
+ // the vertex shader.
+ mVertexConstants.viewCoords[0] = mPixelConstants.viewCoords[0];
+ mVertexConstants.viewCoords[1] = mPixelConstants.viewCoords[1];
+ mVertexConstants.viewCoords[2] = mPixelConstants.viewCoords[2];
+ mVertexConstants.viewCoords[3] = mPixelConstants.viewCoords[3];
+
mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
@@ -841,7 +1216,7 @@ void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float z
mForceSetViewport = false;
}
-bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
+bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize)
{
D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
@@ -862,6 +1237,14 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
return false;
}
+ // If instanced pointsprite emulation is being used and If gl_PointSize is used in the shader,
+ // GL_POINTS mode is expected to render pointsprites.
+ // Instanced PointSprite emulation requires that the topology to be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST.
+ if (mode == GL_POINTS && usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation)
+ {
+ primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
+ }
+
if (primitiveTopology != mCurrentPrimitiveTopology)
{
mDeviceContext->IASetPrimitiveTopology(primitiveTopology);
@@ -871,15 +1254,15 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
return count >= minCount;
}
-void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11Resource *resource)
+void Renderer11::unsetConflictingSRVs(gl::SamplerType samplerType, uintptr_t resource, const gl::ImageIndex *index)
{
- std::vector<ID3D11ShaderResourceView *> &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+ auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
{
- ID3D11ShaderResourceView *srv = currentSRVs[resourceIndex];
+ auto &record = currentSRVs[resourceIndex];
- if (srv && GetSRVResource(srv) == resource)
+ if (record.srv && record.resource == resource && ImageIndexConflictsWithSRV(index, record.desc))
{
setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL);
}
@@ -892,12 +1275,12 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
// Also extract the render target dimensions and view
unsigned int renderTargetWidth = 0;
unsigned int renderTargetHeight = 0;
- GLenum renderTargetFormat = 0;
- unsigned int renderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {0};
+ DXGI_FORMAT renderTargetFormat = DXGI_FORMAT_UNKNOWN;
ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
bool missingColorRenderTarget = true;
- const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(getWorkarounds());
+ const FramebufferD3D *framebufferD3D = GetImplAs<FramebufferD3D>(framebuffer);
+ const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender(getWorkarounds());
for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
{
@@ -915,8 +1298,6 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
return gl::Error(GL_NO_ERROR);
}
- renderTargetSerials[colorAttachment] = GetAttachmentSerial(colorbuffer);
-
// Extract the render target dimensions and view
RenderTarget11 *renderTarget = NULL;
gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
@@ -931,36 +1312,29 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
if (missingColorRenderTarget)
{
- renderTargetWidth = colorbuffer->getWidth();
- renderTargetHeight = colorbuffer->getHeight();
- renderTargetFormat = colorbuffer->getActualFormat();
+ renderTargetWidth = renderTarget->getWidth();
+ renderTargetHeight = renderTarget->getHeight();
+ renderTargetFormat = renderTarget->getDXGIFormat();
missingColorRenderTarget = false;
}
-#if !defined(NDEBUG)
// Unbind render target SRVs from the shader here to prevent D3D11 warnings.
- ID3D11Resource *renderTargetResource = renderTarget->getTexture();
- unsetSRVsWithResource(gl::SAMPLER_VERTEX, renderTargetResource);
- unsetSRVsWithResource(gl::SAMPLER_PIXEL, renderTargetResource);
-#endif
+ if (colorbuffer->type() == GL_TEXTURE)
+ {
+ uintptr_t rtResource = reinterpret_cast<uintptr_t>(GetViewResource(framebufferRTVs[colorAttachment]));
+ const gl::ImageIndex *index = colorbuffer->getTextureImageIndex();
+ ASSERT(index);
+ // The index doesn't need to be corrected for the small compressed texture workaround
+ // because a rendertarget is never compressed.
+ unsetConflictingSRVs(gl::SAMPLER_VERTEX, rtResource, index);
+ unsetConflictingSRVs(gl::SAMPLER_PIXEL, rtResource, index);
+ }
}
}
- // Get the depth stencil render buffter and serials
- gl::FramebufferAttachment *depthStencil = framebuffer->getDepthbuffer();
- unsigned int depthbufferSerial = 0;
- unsigned int stencilbufferSerial = 0;
- if (depthStencil)
- {
- depthbufferSerial = GetAttachmentSerial(depthStencil);
- }
- else if (framebuffer->getStencilbuffer())
- {
- depthStencil = framebuffer->getStencilbuffer();
- stencilbufferSerial = GetAttachmentSerial(depthStencil);
- }
-
+ // Get the depth stencil buffers
ID3D11DepthStencilView* framebufferDSV = NULL;
+ gl::FramebufferAttachment *depthStencil = framebuffer->getDepthOrStencilbuffer();
if (depthStencil)
{
RenderTarget11 *depthStencilRenderTarget = NULL;
@@ -979,17 +1353,28 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
// the depth stencil
if (missingColorRenderTarget)
{
- renderTargetWidth = depthStencil->getWidth();
- renderTargetHeight = depthStencil->getHeight();
- renderTargetFormat = depthStencil->getActualFormat();
+ renderTargetWidth = depthStencilRenderTarget->getWidth();
+ renderTargetHeight = depthStencilRenderTarget->getHeight();
+ renderTargetFormat = depthStencilRenderTarget->getDXGIFormat();
+ }
+
+ // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
+ if (depthStencil->type() == GL_TEXTURE)
+ {
+ uintptr_t depthStencilResource = reinterpret_cast<uintptr_t>(GetViewResource(framebufferDSV));
+ const gl::ImageIndex *index = depthStencil->getTextureImageIndex();
+ ASSERT(index);
+ // The index doesn't need to be corrected for the small compressed texture workaround
+ // because a rendertarget is never compressed.
+ unsetConflictingSRVs(gl::SAMPLER_VERTEX, depthStencilResource, index);
+ unsetConflictingSRVs(gl::SAMPLER_PIXEL, depthStencilResource, index);
}
}
// Apply the render target and depth stencil
if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
- memcmp(renderTargetSerials, mAppliedRenderTargetSerials, sizeof(renderTargetSerials)) != 0 ||
- depthbufferSerial != mAppliedDepthbufferSerial ||
- stencilbufferSerial != mAppliedStencilbufferSerial)
+ memcmp(framebufferRTVs, mAppliedRTVs, sizeof(framebufferRTVs)) != 0 ||
+ reinterpret_cast<uintptr_t>(framebufferDSV) != mAppliedDSV)
{
mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, framebufferRTVs, framebufferDSV);
@@ -1005,22 +1390,26 @@ gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
mForceSetRasterState = true;
}
- for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
+ for (size_t rtIndex = 0; rtIndex < ArraySize(framebufferRTVs); rtIndex++)
{
- mAppliedRenderTargetSerials[rtIndex] = renderTargetSerials[rtIndex];
+ mAppliedRTVs[rtIndex] = reinterpret_cast<uintptr_t>(framebufferRTVs[rtIndex]);
}
- mAppliedDepthbufferSerial = depthbufferSerial;
- mAppliedStencilbufferSerial = stencilbufferSerial;
+ mAppliedDSV = reinterpret_cast<uintptr_t>(framebufferDSV);
mRenderTargetDescInitialized = true;
mDepthStencilInitialized = true;
}
- invalidateFramebufferSwizzles(framebuffer);
+ const Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
+ gl::Error error = framebuffer11->invalidateSwizzles();
+ if (error.isError())
+ {
+ return error;
+ }
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances)
+gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances);
@@ -1029,7 +1418,7 @@ gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLint first, GLs
return error;
}
- return mInputLayoutCache.applyVertexBuffers(attributes, state.getCurrentProgramBinary());
+ return mInputLayoutCache.applyVertexBuffers(attributes, mode, state.getProgram());
}
gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
@@ -1066,31 +1455,36 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen
return gl::Error(GL_NO_ERROR);
}
-void Renderer11::applyTransformFeedbackBuffers(const gl::State& state)
+void Renderer11::applyTransformFeedbackBuffers(const gl::State &state)
{
- size_t numXFBBindings = state.getTransformFeedbackBufferIndexRange();
- ASSERT(numXFBBindings <= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
-
+ size_t numXFBBindings = 0;
bool requiresUpdate = false;
- for (size_t i = 0; i < numXFBBindings; i++)
+
+ if (state.isTransformFeedbackActiveUnpaused())
{
- gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i);
- GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i);
- ID3D11Buffer *d3dBuffer = NULL;
- if (curXFBBuffer)
- {
- Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation());
- d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
- }
+ numXFBBindings = state.getTransformFeedbackBufferIndexRange();
+ ASSERT(numXFBBindings <= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
- // TODO: mAppliedTFBuffers and friends should also be kept in a vector.
- if (d3dBuffer != mAppliedTFBuffers[i] || curXFBOffset != mAppliedTFOffsets[i])
+ for (size_t i = 0; i < numXFBBindings; i++)
{
- requiresUpdate = true;
+ gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i);
+ GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i);
+ ID3D11Buffer *d3dBuffer = NULL;
+ if (curXFBBuffer)
+ {
+ Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation());
+ d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
+ }
+
+ // TODO: mAppliedTFBuffers and friends should also be kept in a vector.
+ if (d3dBuffer != mAppliedTFBuffers[i] || curXFBOffset != mAppliedTFOffsets[i])
+ {
+ requiresUpdate = true;
+ }
}
}
- if (requiresUpdate)
+ if (requiresUpdate || numXFBBindings != mAppliedNumXFBBindings)
{
for (size_t i = 0; i < numXFBBindings; ++i)
{
@@ -1102,7 +1496,7 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State& state)
Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation());
ID3D11Buffer *d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
- mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer && mAppliedTFOffsets[i] != curXFBOffset) ?
+ mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer || mAppliedTFOffsets[i] != curXFBOffset) ?
static_cast<UINT>(curXFBOffset) : -1;
mAppliedTFBuffers[i] = d3dBuffer;
}
@@ -1114,13 +1508,16 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State& state)
mAppliedTFOffsets[i] = curXFBOffset;
}
+ mAppliedNumXFBBindings = numXFBBindings;
+
mDeviceContext->SOSetTargets(numXFBBindings, mAppliedTFBuffers, mCurrentD3DOffsets);
}
}
-gl::Error Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive)
+gl::Error Renderer11::drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize)
{
- if (mode == GL_POINTS && transformFeedbackActive)
+ bool useInstancedPointSpriteEmulation = usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation;
+ if (mode == GL_POINTS && data.state->isTransformFeedbackActiveUnpaused())
{
// Since point sprites are generated with a geometry shader, too many vertices will
// be written if transform feedback is active. To work around this, draw only the points
@@ -1138,19 +1535,38 @@ gl::Error Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances,
mDeviceContext->Draw(count, 0);
}
- mDeviceContext->GSSetShader(mCurPointGeometryShader, NULL, 0);
- mDeviceContext->PSSetShader(mAppliedPixelShader, NULL, 0);
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(data.state->getProgram());
- if (instances > 0)
+ rx::ShaderExecutableD3D *pixelExe = NULL;
+ gl::Error error = programD3D->getPixelExecutableForFramebuffer(data.state->getDrawFramebuffer(), &pixelExe);
+ if (error.isError())
{
- mDeviceContext->DrawInstanced(count, instances, 0, 0);
+ return error;
}
- else
+
+ // Skip this step if we're doing rasterizer discard.
+ if (pixelExe && !data.state->getRasterizerState().rasterizerDiscard && usesPointSize)
{
- mDeviceContext->Draw(count, 0);
- }
+ ID3D11PixelShader *pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
+ ASSERT(reinterpret_cast<uintptr_t>(pixelShader) == mAppliedPixelShader);
+ mDeviceContext->PSSetShader(pixelShader, NULL, 0);
- mDeviceContext->GSSetShader(mAppliedGeometryShader, NULL, 0);
+ // Retrieve the point sprite geometry shader
+ rx::ShaderExecutableD3D *geometryExe = programD3D->getGeometryExecutable();
+ ID3D11GeometryShader *geometryShader = (geometryExe ? ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader() : NULL);
+ mAppliedGeometryShader = reinterpret_cast<uintptr_t>(geometryShader);
+ ASSERT(geometryShader);
+ mDeviceContext->GSSetShader(geometryShader, NULL, 0);
+
+ if (instances > 0)
+ {
+ mDeviceContext->DrawInstanced(count, instances, 0, 0);
+ }
+ else
+ {
+ mDeviceContext->Draw(count, 0);
+ }
+ }
return gl::Error(GL_NO_ERROR);
}
@@ -1169,7 +1585,17 @@ gl::Error Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances,
}
else
{
- mDeviceContext->Draw(count, 0);
+ // If gl_PointSize is used and GL_POINTS is specified, then it is expected to render pointsprites.
+ // If instanced pointsprite emulation is being used the topology is expexted to be
+ // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced must be used.
+ if (mode == GL_POINTS && useInstancedPointSpriteEmulation)
+ {
+ mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
+ }
+ else
+ {
+ mDeviceContext->Draw(count, 0);
+ }
return gl::Error(GL_NO_ERROR);
}
}
@@ -1198,90 +1624,13 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons
return gl::Error(GL_NO_ERROR);
}
}
-template<typename T>
-static void fillLineLoopIndices(GLenum type, GLsizei count, const GLvoid *indices, T *data)
-{
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (int i = 0; i < count; i++)
- {
- data[i] = i;
- }
- data[count] = 0;
- break;
- case GL_UNSIGNED_BYTE:
- 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_UNSIGNED_SHORT:
- 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_UNSIGNED_INT:
- 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();
- }
-}
-
-template<typename T>
-static void fillTriangleFanIndices(GLenum type, unsigned int numTris, const GLvoid *indices, T *data)
-{
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = 0;
- data[i*3 + 1] = i + 1;
- data[i*3 + 2] = i + 2;
- }
- break;
- case GL_UNSIGNED_BYTE:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
- }
- break;
- case GL_UNSIGNED_SHORT:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
- }
- break;
- case GL_UNSIGNED_INT:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
- }
- break;
- default: UNREACHABLE();
- }
-}
gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
{
// Get the raw indices for an indexed draw
if (type != GL_NONE && elementArrayBuffer)
{
- BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
+ BufferD3D *storage = GetImplAs<BufferD3D>(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
const uint8_t *bufferData = NULL;
@@ -1294,13 +1643,10 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
indices = bufferData + offset;
}
- // TODO: some level 9 hardware supports 32-bit indices; test and store support instead
- const int indexType = isLevel9() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
-
if (!mLineLoopIB)
{
mLineLoopIB = new StreamingIndexBufferInterface(this);
- gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType);
+ gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
if (error.isError())
{
SafeDelete(mLineLoopIB);
@@ -1311,8 +1657,7 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
// Checked by Renderer11::applyPrimitiveType
ASSERT(count >= 0);
- int indexTypeSize = indexType == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int);
- if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / indexTypeSize))
+ if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int)))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required.");
}
@@ -1332,12 +1677,42 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
return error;
}
- if (indexType == GL_UNSIGNED_SHORT)
- fillLineLoopIndices(type, count, indices, reinterpret_cast<unsigned short*>(mappedMemory));
- else
- fillLineLoopIndices(type, count, indices, reinterpret_cast<unsigned int*>(mappedMemory));
+ unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
unsigned int indexBufferOffset = offset;
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+ data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+ 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_UNSIGNED_SHORT:
+ 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_UNSIGNED_INT:
+ 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();
+ }
+
error = mLineLoopIB->unmapBuffer();
if (error.isError())
{
@@ -1366,7 +1741,7 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
// Get the raw indices for an indexed draw
if (type != GL_NONE && elementArrayBuffer)
{
- BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
+ BufferD3D *storage = GetImplAs<BufferD3D>(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
const uint8_t *bufferData = NULL;
@@ -1379,12 +1754,10 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
indices = bufferData + offset;
}
- const int indexType = isLevel9() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
-
if (!mTriangleFanIB)
{
mTriangleFanIB = new StreamingIndexBufferInterface(this);
- gl::Error error = mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType);
+ gl::Error error = mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
if (error.isError())
{
SafeDelete(mTriangleFanIB);
@@ -1397,14 +1770,13 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
const unsigned int numTris = count - 2;
- int indexTypeSize = indexType == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int);
- if (numTris > (std::numeric_limits<unsigned int>::max() / (indexTypeSize * 3)))
+ if (numTris > (std::numeric_limits<unsigned int>::max() / (sizeof(unsigned int) * 3)))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required.");
}
- const unsigned int spaceNeeded = (numTris * 3) * indexTypeSize;
- gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, indexType);
+ const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
+ gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
if (error.isError())
{
return error;
@@ -1418,13 +1790,46 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
return error;
}
- if (indexType == GL_UNSIGNED_SHORT)
- fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned short*>(mappedMemory));
- else
- fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned int*>(mappedMemory));
-
+ unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
unsigned int indexBufferOffset = offset;
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (unsigned int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = 0;
+ data[i*3 + 1] = i + 1;
+ data[i*3 + 2] = i + 2;
+ }
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (unsigned int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (unsigned int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ for (unsigned int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
+ }
+ break;
+ default: UNREACHABLE();
+ }
+
error = mTriangleFanIB->unmapBuffer();
if (error.isError())
{
@@ -1455,26 +1860,26 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+gl::Error Renderer11::applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive)
{
- ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
- ShaderExecutable *vertexExe = NULL;
- gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe);
+ ShaderExecutableD3D *vertexExe = NULL;
+ gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr);
if (error.isError())
{
return error;
}
- ShaderExecutable *pixelExe = NULL;
+ ShaderExecutableD3D *pixelExe = NULL;
error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe);
if (error.isError())
{
return error;
}
- ShaderExecutable *geometryExe = programD3D->getGeometryExecutable();
+ ShaderExecutableD3D *geometryExe = programD3D->getGeometryExecutable();
ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL);
@@ -1497,33 +1902,24 @@ gl::Error Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::V
bool dirtyUniforms = false;
- if (vertexShader != mAppliedVertexShader)
+ if (reinterpret_cast<uintptr_t>(vertexShader) != mAppliedVertexShader)
{
mDeviceContext->VSSetShader(vertexShader, NULL, 0);
- mAppliedVertexShader = vertexShader;
+ mAppliedVertexShader = reinterpret_cast<uintptr_t>(vertexShader);
dirtyUniforms = true;
}
- if (geometryShader != mAppliedGeometryShader)
+ if (reinterpret_cast<uintptr_t>(geometryShader) != mAppliedGeometryShader)
{
mDeviceContext->GSSetShader(geometryShader, NULL, 0);
- mAppliedGeometryShader = geometryShader;
+ mAppliedGeometryShader = reinterpret_cast<uintptr_t>(geometryShader);
dirtyUniforms = true;
}
- if (geometryExe && mCurRasterState.pointDrawMode)
- {
- mCurPointGeometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader();
- }
- else
- {
- mCurPointGeometryShader = NULL;
- }
-
- if (pixelShader != mAppliedPixelShader)
+ if (reinterpret_cast<uintptr_t>(pixelShader) != mAppliedPixelShader)
{
mDeviceContext->PSSetShader(pixelShader, NULL, 0);
- mAppliedPixelShader = pixelShader;
+ mAppliedPixelShader = reinterpret_cast<uintptr_t>(pixelShader);
dirtyUniforms = true;
}
@@ -1560,7 +1956,7 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto
}
}
- const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(&program);
+ const ProgramD3D *programD3D = GetAs<ProgramD3D>(&program);
const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage());
const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage());
ASSERT(vertexUniformStorage);
@@ -1682,40 +2078,36 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto
memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants));
}
- // needed for the point sprite geometry shader
- if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 && mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
+ // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary
+ if (programD3D->usesGeometryShader())
{
- mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
- mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
- }
-
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer)
-{
- gl::Error error = mClear->clearFramebuffer(clearParams, frameBuffer);
- if (error.isError())
- {
- return error;
+ // needed for the point sprite geometry shader
+ if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
+ {
+ mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
+ mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
+ }
}
- invalidateFramebufferSwizzles(frameBuffer);
-
return gl::Error(GL_NO_ERROR);
}
void Renderer11::markAllStateDirty()
{
- for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
+ for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++)
{
- mAppliedRenderTargetSerials[rtIndex] = 0;
+ mAppliedRTVs[rtIndex] = DirtyPointer;
}
- mAppliedDepthbufferSerial = 0;
- mAppliedStencilbufferSerial = 0;
+ mAppliedDSV = DirtyPointer;
mDepthStencilInitialized = false;
mRenderTargetDescInitialized = false;
+ // We reset the current SRV data because it might not be in sync with D3D's state
+ // anymore. For example when a currently used SRV is used as an RTV, D3D silently
+ // remove it from its state.
+ memset(mCurVertexSRVs.data(), 0, sizeof(SRVRecord) * mCurVertexSRVs.size());
+ memset(mCurPixelSRVs.data(), 0, sizeof(SRVRecord) * mCurPixelSRVs.size());
+
ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size());
for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId)
{
@@ -1738,10 +2130,11 @@ void Renderer11::markAllStateDirty()
mAppliedIBFormat = DXGI_FORMAT_UNKNOWN;
mAppliedIBOffset = 0;
- mAppliedVertexShader = NULL;
- mAppliedGeometryShader = NULL;
- mCurPointGeometryShader = NULL;
- mAppliedPixelShader = NULL;
+ mAppliedVertexShader = DirtyPointer;
+ mAppliedGeometryShader = DirtyPointer;
+ mAppliedPixelShader = DirtyPointer;
+
+ mAppliedNumXFBBindings = static_cast<size_t>(-1);
for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
{
@@ -1756,8 +2149,12 @@ void Renderer11::markAllStateDirty()
for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++)
{
- mCurrentConstantBufferVS[i] = -1;
- mCurrentConstantBufferPS[i] = -1;
+ mCurrentConstantBufferVS[i] = static_cast<unsigned int>(-1);
+ mCurrentConstantBufferVSOffset[i] = 0;
+ mCurrentConstantBufferVSSize[i] = 0;
+ mCurrentConstantBufferPS[i] = static_cast<unsigned int>(-1);
+ mCurrentConstantBufferPSOffset[i] = 0;
+ mCurrentConstantBufferPSSize[i] = 0;
}
mCurrentVertexConstantBuffer = NULL;
@@ -1778,6 +2175,7 @@ void Renderer11::releaseDeviceResources()
SafeDelete(mTriangleFanIB);
SafeDelete(mBlit);
SafeDelete(mClear);
+ SafeDelete(mTrim);
SafeDelete(mPixelTransfer);
SafeRelease(mDriverConstantBufferVS);
@@ -1785,19 +2183,8 @@ void Renderer11::releaseDeviceResources()
SafeRelease(mSyncQuery);
}
-void Renderer11::notifyDeviceLost()
-{
- mDeviceLost = true;
- mDisplay->notifyDeviceLost();
-}
-
-bool Renderer11::isDeviceLost()
-{
- return mDeviceLost;
-}
-
// set notify to true to broadcast a message to all contexts of the device loss
-bool Renderer11::testDeviceLost(bool notify)
+bool Renderer11::testDeviceLost()
{
bool isLost = false;
@@ -1819,10 +2206,6 @@ bool Renderer11::testDeviceLost(bool notify)
// Note that we don't want to clear the device loss status here
// -- this needs to be done by resetDevice
mDeviceLost = true;
- if (notify)
- {
- notifyDeviceLost();
- }
}
return isLost;
@@ -1872,12 +2255,15 @@ void Renderer11::release()
{
RendererD3D::cleanup();
- releaseShaderCompiler();
releaseDeviceResources();
SafeRelease(mDxgiFactory);
SafeRelease(mDxgiAdapter);
+#if defined(ANGLE_ENABLE_D3D11_1)
+ SafeRelease(mDeviceContext1);
+#endif
+
if (mDeviceContext)
{
mDeviceContext->ClearState();
@@ -1906,11 +2292,11 @@ bool Renderer11::resetDevice()
{
// recreate everything
release();
- EGLint result = initialize();
+ egl::Error result = initialize();
- if (result != EGL_SUCCESS)
+ if (result.isError())
{
- ERR("Could not reinitialize D3D11 device: %08X", result);
+ ERR("Could not reinitialize D3D11 device: %08X", result.getCode());
return false;
}
@@ -1919,9 +2305,9 @@ bool Renderer11::resetDevice()
return true;
}
-DWORD Renderer11::getAdapterVendor() const
+VendorID Renderer11::getVendorId() const
{
- return mAdapterDescription.VendorId;
+ return static_cast<VendorID>(mAdapterDescription.VendorId);
}
std::string Renderer11::getRendererDescription() const
@@ -1931,8 +2317,8 @@ std::string Renderer11::getRendererDescription() const
rendererString << mDescription;
rendererString << " Direct3D11";
- rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel();
- rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel();
+ rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel() << getShaderModelSuffix();
+ rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel() << getShaderModelSuffix();
return rendererString.str();
}
@@ -1941,7 +2327,7 @@ GUID Renderer11::getAdapterIdentifier() const
{
// Use the adapter LUID as our adapter ID
// This number is local to a machine is only guaranteed to be unique between restarts
- META_ASSERT(sizeof(LUID) <= sizeof(GUID));
+ static_assert(sizeof(LUID) <= sizeof(GUID), "Size of GUID must be at least as large as LUID.");
GUID adapterId = {0};
memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID));
return adapterId;
@@ -1974,7 +2360,8 @@ bool Renderer11::getShareHandleSupport() const
// We only currently support share handles with BGRA surfaces, because
// chrome needs BGRA. Once chrome fixes this, we should always support them.
// PIX doesn't seem to support using share handles, so disable them.
- return getRendererExtensions().textureFormatBGRA8888 && !gl::perfActive();
+ // Also disable share handles on Feature Level 9_3, since it doesn't support share handles on RGBA8 textures/swapchains.
+ return getRendererExtensions().textureFormatBGRA8888 && !gl::DebugAnnotationsActive();// && !(mFeatureLevel <= D3D_FEATURE_LEVEL_9_3); Qt: we don't care about the 9_3 limitation
}
bool Renderer11::getPostSubBufferSupport() const
@@ -1989,10 +2376,8 @@ int Renderer11::getMajorShaderModel() const
{
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:
- case D3D_FEATURE_LEVEL_9_3:
- case D3D_FEATURE_LEVEL_9_2:
- case D3D_FEATURE_LEVEL_9_1: return D3D10_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;
}
}
@@ -2003,26 +2388,26 @@ int Renderer11::getMinorShaderModel() const
{
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:
- case D3D_FEATURE_LEVEL_9_3:
- case D3D_FEATURE_LEVEL_9_2:
- case D3D_FEATURE_LEVEL_9_1: return D3D10_SHADER_MINOR_VERSION; // 0
+ 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;
}
}
-int Renderer11::getMinSwapInterval() const
+std::string Renderer11::getShaderModelSuffix() const
{
- return 0;
-}
-
-int Renderer11::getMaxSwapInterval() const
-{
- return 4;
+ switch (mFeatureLevel)
+ {
+ 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 "";
+ }
}
-gl::Error Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
+gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
ASSERT(colorbuffer);
@@ -2042,7 +2427,7 @@ gl::Error Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectan
ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
- RenderTarget *destRenderTarget = NULL;
+ RenderTargetD3D *destRenderTarget = NULL;
error = storage11->getRenderTarget(index, &destRenderTarget);
if (error.isError())
{
@@ -2056,7 +2441,7 @@ gl::Error Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectan
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
- gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
+ 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
@@ -2072,8 +2457,8 @@ gl::Error Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectan
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
+gl::Error Renderer11::copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
ASSERT(colorbuffer);
@@ -2093,7 +2478,7 @@ gl::Error Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rect
ASSERT(storage11);
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
- RenderTarget *destRenderTarget = NULL;
+ RenderTargetD3D *destRenderTarget = NULL;
error = storage11->getRenderTarget(index, &destRenderTarget);
if (error.isError())
{
@@ -2107,7 +2492,7 @@ gl::Error Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rect
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
- gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
+ 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
@@ -2123,8 +2508,8 @@ gl::Error Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rect
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
ASSERT(colorbuffer);
@@ -2143,8 +2528,8 @@ gl::Error Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectan
TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage);
ASSERT(storage11);
- gl::ImageIndex index = gl::ImageIndex::Make3D(level, zOffset);
- RenderTarget *destRenderTarget = NULL;
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level, destOffset.z);
+ RenderTargetD3D *destRenderTarget = NULL;
error = storage11->getRenderTarget(index, &destRenderTarget);
if (error.isError())
{
@@ -2158,7 +2543,7 @@ gl::Error Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectan
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
- gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
+ 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
@@ -2174,8 +2559,8 @@ gl::Error Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectan
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level)
{
gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
ASSERT(colorbuffer);
@@ -2194,8 +2579,8 @@ gl::Error Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::R
TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage);
ASSERT(storage11);
- gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zOffset);
- RenderTarget *destRenderTarget = NULL;
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, destOffset.z);
+ RenderTargetD3D *destRenderTarget = NULL;
error = storage11->getRenderTarget(index, &destRenderTarget);
if (error.isError())
{
@@ -2209,7 +2594,7 @@ gl::Error Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::R
gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
- gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
+ 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
@@ -2230,6 +2615,7 @@ void Renderer11::unapplyRenderTargets()
setOneTimeRenderTarget(NULL);
}
+// When finished with this rendertarget, markAllStateDirty must be called.
void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView)
{
ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
@@ -2239,22 +2625,16 @@ void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView
mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, rtvArray, NULL);
// Do not preserve the serial for this one-time-use render target
- for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
+ for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++)
{
- mAppliedRenderTargetSerials[rtIndex] = 0;
+ mAppliedRTVs[rtIndex] = DirtyPointer;
}
+ mAppliedDSV = DirtyPointer;
}
-gl::Error Renderer11::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT)
-{
- SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
- *outRT = new SurfaceRenderTarget11(swapChain11, depth);
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT)
+gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT)
{
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format, mFeatureLevel);
const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format);
GLuint supportedSamples = textureCaps.getNearestSamples(samples);
@@ -2386,24 +2766,34 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G
return gl::Error(GL_NO_ERROR);
}
-ShaderImpl *Renderer11::createShader(const gl::Data &data, GLenum type)
+FramebufferImpl *Renderer11::createDefaultFramebuffer(const gl::Framebuffer::Data &data)
{
- return new ShaderD3D(data, type, this);
+ return createFramebuffer(data);
}
-ProgramImpl *Renderer11::createProgram()
+FramebufferImpl *Renderer11::createFramebuffer(const gl::Framebuffer::Data &data)
{
- return new ProgramD3D(this);
+ return new Framebuffer11(data, this);
}
-void Renderer11::releaseShaderCompiler()
+CompilerImpl *Renderer11::createCompiler(const gl::Data &data)
{
- ShaderD3D::releaseCompiler();
+ return new CompilerD3D(data, SH_HLSL11_OUTPUT);
+}
+
+ShaderImpl *Renderer11::createShader(GLenum type)
+{
+ return new ShaderD3D(type);
+}
+
+ProgramImpl *Renderer11::createProgram()
+{
+ return new ProgramD3D(this);
}
gl::Error Renderer11::loadExecutable(const void *function, size_t length, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, ShaderExecutable **outExecutable)
+ bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable)
{
switch (type)
{
@@ -2490,8 +2880,8 @@ gl::Error Renderer11::loadExecutable(const void *function, size_t length, Shader
gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround,
- ShaderExecutable **outExectuable)
+ bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds,
+ ShaderExecutableD3D **outExectuable)
{
const char *profileType = NULL;
switch (type)
@@ -2510,51 +2900,11 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
return gl::Error(GL_INVALID_OPERATION);
}
- unsigned int profileMajorVersion = 0;
- unsigned int profileMinorVersion = 0;
- const char *profileSuffix = NULL;
- switch (mFeatureLevel)
- {
- case D3D_FEATURE_LEVEL_11_0:
- profileMajorVersion = 5;
- profileMinorVersion = 0;
- break;
- case D3D_FEATURE_LEVEL_10_1:
- profileMajorVersion = 4;
- profileMinorVersion = 1;
- break;
- case D3D_FEATURE_LEVEL_10_0:
- profileMajorVersion = 4;
- profileMinorVersion = 0;
- break;
- case D3D_FEATURE_LEVEL_9_3:
- profileMajorVersion = 4;
- profileMinorVersion = 0;
- profileSuffix = "_level_9_3";
- break;
- case D3D_FEATURE_LEVEL_9_2:
- profileMajorVersion = 4;
- profileMinorVersion = 0;
- profileSuffix = "_level_9_2";
- break;
- case D3D_FEATURE_LEVEL_9_1:
- profileMajorVersion = 4;
- profileMinorVersion = 0;
- profileSuffix = "_level_9_1";
- break;
- break;
- default:
- UNREACHABLE();
- return gl::Error(GL_INVALID_OPERATION);
- }
-
- std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion);
- if (profileSuffix)
- profile += profileSuffix;
+ std::string profile = FormatString("%s_%d_%d%s", profileType, getMajorShaderModel(), getMinorShaderModel(), getShaderModelSuffix().c_str());
UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2;
- if (gl::perfActive())
+ if (gl::DebugAnnotationsActive())
{
#ifndef NDEBUG
flags = D3DCOMPILE_SKIP_OPTIMIZATION;
@@ -2563,6 +2913,9 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
flags |= D3DCOMPILE_DEBUG;
}
+ 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;
@@ -2605,7 +2958,7 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
return gl::Error(GL_NO_ERROR);
}
-UniformStorage *Renderer11::createUniformStorage(size_t storageSize)
+UniformStorageD3D *Renderer11::createUniformStorage(size_t storageSize)
{
return new UniformStorage11(this, storageSize);
}
@@ -2655,7 +3008,7 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
ASSERT(getRendererExtensions().pixelBufferObject);
const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
- const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat);
+ const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat, mFeatureLevel);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11FormatInfo.texFormat);
// sRGB formats do not work with D3D11 buffer SRVs
@@ -2665,7 +3018,7 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
}
// We cannot support direct copies to non-color-renderable formats
- if (d3d11FormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
+ if (d3d11FormatInfo.rtvFormat == DXGI_FORMAT_UNKNOWN)
{
return false;
}
@@ -2685,196 +3038,39 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
return true;
}
-gl::Error Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+gl::Error Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
{
ASSERT(supportsFastCopyBufferToTexture(destinationFormat));
return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea);
}
-gl::Error Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut)
-
+ImageD3D *Renderer11::createImage()
{
- ASSERT(colorbuffer);
-
- RenderTarget11 *renderTarget = NULL;
- gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
- if (error.isError())
- {
- return error;
- }
-
- ID3D11Resource *renderTargetResource = renderTarget->getTexture();
- ASSERT(renderTargetResource);
-
- *subresourceIndexOut = renderTarget->getSubresourceIndex();
- *texture2DOut = d3d11::DynamicCastComObject<ID3D11Texture2D>(renderTargetResource);
-
- if (!(*texture2DOut))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the ID3D11Texture2D from a RenderTarget");
- }
-
- return gl::Error(GL_NO_ERROR);
+ return new Image11(this);
}
-gl::Error Renderer11::blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
- const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget,
- bool blitDepth, bool blitStencil, GLenum filter)
-{
- if (blitRenderTarget)
- {
- gl::FramebufferAttachment *readBuffer = readTarget->getReadColorbuffer();
- ASSERT(readBuffer);
-
- RenderTarget *readRenderTarget = NULL;
- gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
- if (error.isError())
- {
- return error;
- }
- ASSERT(readRenderTarget);
-
- for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
- {
- if (drawTarget->isEnabledColorAttachment(colorAttachment))
- {
- gl::FramebufferAttachment *drawBuffer = drawTarget->getColorbuffer(colorAttachment);
- ASSERT(drawBuffer);
-
- RenderTarget *drawRenderTarget = NULL;
- error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
- if (error.isError())
- {
- return error;
- }
- ASSERT(drawRenderTarget);
-
- error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, blitRenderTarget,
- false, false);
- if (error.isError())
- {
- return error;
- }
- }
- }
- }
-
- if (blitDepth || blitStencil)
- {
- gl::FramebufferAttachment *readBuffer = readTarget->getDepthOrStencilbuffer();
- ASSERT(readBuffer);
-
- RenderTarget *readRenderTarget = NULL;
- gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
- if (error.isError())
- {
- return error;
- }
- ASSERT(readRenderTarget);
-
- gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer();
- ASSERT(drawBuffer);
-
- RenderTarget *drawRenderTarget = NULL;
- error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
- if (error.isError())
- {
- return error;
- }
- ASSERT(drawRenderTarget);
-
- error = blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, false,
- blitDepth, blitStencil);
- if (error.isError())
- {
- return error;
- }
- }
-
- invalidateFramebufferSwizzles(drawTarget);
-
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error Renderer11::readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
- GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
-{
- ID3D11Texture2D *colorBufferTexture = NULL;
- unsigned int subresourceIndex = 0;
-
- gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
- ASSERT(colorbuffer);
-
- gl::Error error = getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture);
- if (error.isError())
- {
- return error;
- }
-
- gl::Rectangle area;
- area.x = x;
- area.y = y;
- area.width = width;
- area.height = height;
-
- gl::Buffer *packBuffer = pack.pixelBuffer.get();
- if (packBuffer != NULL)
- {
- Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation());
- PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels));
-
- error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams);
- if (error.isError())
- {
- SafeRelease(colorBufferTexture);
- return error;
- }
-
- packBuffer->getIndexRangeCache()->clear();
- }
- else
- {
- error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels);
- if (error.isError())
- {
- SafeRelease(colorBufferTexture);
- return error;
- }
- }
-
- SafeRelease(colorBufferTexture);
-
- return gl::Error(GL_NO_ERROR);
-}
-
-Image *Renderer11::createImage()
-{
- return new Image11();
-}
-
-gl::Error Renderer11::generateMipmap(Image *dest, Image *src)
+gl::Error Renderer11::generateMipmap(ImageD3D *dest, ImageD3D *src)
{
Image11 *dest11 = Image11::makeImage11(dest);
Image11 *src11 = Image11::makeImage11(src);
return Image11::generateMipmap(dest11, src11);
}
-TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
+TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain)
{
SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
return new TextureStorage11_2D(this, swapChain11);
}
-TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
+TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly)
{
- return new TextureStorage11_2D(this, internalformat, renderTarget, width, height, levels);
+ return new TextureStorage11_2D(this, internalformat, renderTarget, width, height, levels, hintLevelZeroOnly);
}
-TextureStorage *Renderer11::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels)
+TextureStorage *Renderer11::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly)
{
- return new TextureStorage11_Cube(this, internalformat, renderTarget, size, levels);
+ return new TextureStorage11_Cube(this, internalformat, renderTarget, size, levels, hintLevelZeroOnly);
}
TextureStorage *Renderer11::createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels)
@@ -2908,13 +3104,6 @@ RenderbufferImpl *Renderer11::createRenderbuffer()
return renderbuffer;
}
-RenderbufferImpl *Renderer11::createRenderbuffer(SwapChain *swapChain, bool depth)
-{
- RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
- renderbuffer->setStorage(swapChain, depth);
- return renderbuffer;
-}
-
gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
{
@@ -3057,8 +3246,8 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP
const d3d11::DXGIFormat &sourceDXGIFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format);
ColorCopyFunction fastCopyFunc = sourceDXGIFormatInfo.getFastCopyFunction(params.format, params.type);
- const gl::FormatType &destFormatTypeInfo = gl::GetFormatTypeInfo(params.format, params.type);
- const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat);
+ GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(params.format, params.type);
+ const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat);
if (fastCopyFunc)
{
@@ -3076,10 +3265,14 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP
}
else
{
+ ColorReadFunction colorReadFunction = sourceDXGIFormatInfo.colorReadFunction;
+ ColorWriteFunction colorWriteFunction = GetColorWriteFunction(params.format, params.type);
+
uint8_t temp[16]; // Maximum size of any Color<T> type used.
- META_ASSERT(sizeof(temp) >= sizeof(gl::ColorF) &&
- sizeof(temp) >= sizeof(gl::ColorUI) &&
- sizeof(temp) >= sizeof(gl::ColorI));
+ static_assert(sizeof(temp) >= sizeof(gl::ColorF) &&
+ sizeof(temp) >= sizeof(gl::ColorUI) &&
+ sizeof(temp) >= sizeof(gl::ColorI),
+ "Unexpected size of gl::Color struct.");
for (int y = 0; y < params.area.height; y++)
{
@@ -3090,8 +3283,8 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP
// readFunc and writeFunc will be using the same type of color, CopyTexImage
// will not allow the copy otherwise.
- sourceDXGIFormatInfo.colorReadFunction(src, temp);
- destFormatTypeInfo.colorWriteFunction(temp, dest);
+ colorReadFunction(src, temp);
+ colorWriteFunction(temp, dest);
}
}
}
@@ -3102,8 +3295,8 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
- RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
+gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, 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,
@@ -3187,12 +3380,12 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const
drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width ||
drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height;
- const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getActualFormat());
- bool partialDSBlit = (actualFormatInfo.depthBits > 0 && depthBlit) != (actualFormatInfo.stencilBits > 0 && stencilBlit);
+ const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(drawRenderTarget11->getDXGIFormat());
+ bool partialDSBlit = (dxgiFormatInfo.depthBits > 0 && depthBlit) != (dxgiFormatInfo.stencilBits > 0 && stencilBlit);
gl::Error result(GL_NO_ERROR);
- if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() &&
+ if (readRenderTarget11->getDXGIFormat() == drawRenderTarget11->getDXGIFormat() &&
!stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit &&
(!(depthBlit || stencilBlit) || wholeBufferCopy))
{
@@ -3276,6 +3469,11 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const
return result;
}
+bool Renderer11::isES3Capable() const
+{
+ return (d3d11_gl::GetMaximumClientVersion(mFeatureLevel) > 2);
+};
+
ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource)
{
D3D11_TEXTURE2D_DESC textureDesc;
@@ -3314,50 +3512,6 @@ ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source,
}
}
-void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel)
-{
- ASSERT(attachment->isTexture());
- gl::Texture *texture = attachment->getTexture();
-
- TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
- TextureStorage *texStorage = textureD3D->getNativeTexture();
- if (texStorage)
- {
- TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage);
- if (!texStorage11)
- {
- ERR("texture storage pointer unexpectedly null.");
- return;
- }
-
- texStorage11->invalidateSwizzleCacheLevel(mipLevel);
- }
-}
-
-void Renderer11::invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer)
-{
- for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
- {
- gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(colorAttachment);
- if (attachment && attachment->isTexture())
- {
- invalidateFBOAttachmentSwizzles(attachment, attachment->mipLevel());
- }
- }
-
- gl::FramebufferAttachment *depthAttachment = framebuffer->getDepthbuffer();
- if (depthAttachment && depthAttachment->isTexture())
- {
- invalidateFBOAttachmentSwizzles(depthAttachment, depthAttachment->mipLevel());
- }
-
- gl::FramebufferAttachment *stencilAttachment = framebuffer->getStencilbuffer();
- if (stencilAttachment && stencilAttachment->isTexture())
- {
- invalidateFBOAttachmentSwizzles(stencilAttachment, stencilAttachment->mipLevel());
- }
-}
-
bool Renderer11::getLUID(LUID *adapterLuid) const
{
adapterLuid->HighPart = 0;
@@ -3380,31 +3534,32 @@ bool Renderer11::getLUID(LUID *adapterLuid) const
VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
{
- return d3d11::GetVertexFormatInfo(vertexFormat).conversionType;
+ return d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel).conversionType;
}
GLenum Renderer11::getVertexComponentType(const gl::VertexFormat &vertexFormat) const
{
- return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormat).nativeFormat).componentType;
+ return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel).nativeFormat).componentType;
}
void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const
{
- d3d11_gl::GenerateCaps(mDevice, outCaps, outTextureCaps, outExtensions);
+ d3d11_gl::GenerateCaps(mDevice, mDeviceContext, outCaps, outTextureCaps, outExtensions);
}
Workarounds Renderer11::generateWorkarounds() const
{
- return d3d11::GenerateWorkarounds();
+ return d3d11::GenerateWorkarounds(mFeatureLevel);
}
void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv)
{
- std::vector<ID3D11ShaderResourceView *> &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
+ auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
+ auto &record = currentSRVs[resourceSlot];
- if (currentSRVs[resourceSlot] != srv)
+ if (record.srv != reinterpret_cast<uintptr_t>(srv))
{
if (shaderType == gl::SAMPLER_VERTEX)
{
@@ -3415,8 +3570,16 @@ void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot
mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv);
}
- currentSRVs[resourceSlot] = srv;
+ record.srv = reinterpret_cast<uintptr_t>(srv);
+ if (srv)
+ {
+ record.resource = reinterpret_cast<uintptr_t>(GetViewResource(srv));
+ srv->GetDesc(&record.desc);
+ }
+ else
+ {
+ record.resource = 0;
+ }
}
}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
index d44bd2fd30..cc7d6c237b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
@@ -6,24 +6,26 @@
// Renderer11.h: Defines a back-end specific class for the D3D11 renderer.
-#ifndef LIBGLESV2_RENDERER_RENDERER11_H_
-#define LIBGLESV2_RENDERER_RENDERER11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_
#include "common/angleutils.h"
-#include "libGLESv2/angletypes.h"
#include "common/mathutil.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/HLSLCompiler.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h"
+#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
-#include "libGLESv2/renderer/d3d/d3d11/RenderStateCache.h"
-#include "libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h"
-#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
-#include "libGLESv2/renderer/RenderTarget.h"
-
-#include "libEGL/AttributeMap.h"
+struct ID3D11DeviceContext1;
namespace gl
{
class FramebufferAttachment;
+struct ImageIndex;
}
namespace rx
@@ -36,6 +38,7 @@ class Blit11;
class Clear11;
class PixelTransfer11;
class RenderTarget11;
+class Trim11;
struct PackPixelsParams;
enum
@@ -44,29 +47,51 @@ enum
MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024
};
+// 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,
+ NUM_D3D11_INIT_ERRORS
+};
+
class Renderer11 : public RendererD3D
{
public:
- Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes);
+ explicit Renderer11(egl::Display *display);
virtual ~Renderer11();
static Renderer11 *makeRenderer11(Renderer *renderer);
- virtual EGLint initialize();
+ egl::Error initialize() override;
virtual bool resetDevice();
- virtual int generateConfigs(ConfigDesc **configDescList);
- virtual void deleteConfigs(ConfigDesc *configDescList);
+ egl::ConfigSet generateConfigs() const override;
- virtual gl::Error sync(bool block);
+ gl::Error flush() override;
+ gl::Error finish() override;
- virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
virtual gl::Error generateSwizzle(gl::Texture *texture);
virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler);
virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture);
- virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
+ gl::Error setUniformBuffers(const gl::Data &data,
+ const GLint vertexUniformBuffers[],
+ const GLint fragmentUniformBuffers[]) override;
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
@@ -78,31 +103,27 @@ class Renderer11 : public RendererD3D
virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
bool ignoreViewport);
- virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
+ virtual bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize);
gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
- virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+ virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive);
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
- virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances);
+ virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
- virtual void applyTransformFeedbackBuffers(const gl::State &state);
+ void applyTransformFeedbackBuffers(const gl::State &state) override;
- virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive);
+ gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) override;
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
- gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) override;
-
virtual void markAllStateDirty();
// lost device
- void notifyDeviceLost() override;
- bool isDeviceLost() override;
- bool testDeviceLost(bool notify) override;
+ bool testDeviceLost() override;
bool testDeviceResettable() override;
- DWORD getAdapterVendor() const override;
+ VendorID getVendorId() const override;
std::string getRendererDescription() const override;
GUID getAdapterIdentifier() const override;
@@ -114,50 +135,47 @@ class Renderer11 : public RendererD3D
virtual bool getPostSubBufferSupport() const;
virtual int getMajorShaderModel() const;
- virtual int getMinSwapInterval() const;
- virtual int getMaxSwapInterval() const;
+ int getMinorShaderModel() const override;
+ std::string getShaderModelSuffix() const override;
// Pixel operations
- virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
- virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
- virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
- virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
-
- gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect, const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) override;
-
- virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
- GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
+ virtual gl::Error copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level);
+ virtual gl::Error copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level);
// RenderTarget creation
- virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT);
- virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT);
+ virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT);
+
+ // Framebuffer creation
+ FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override;
+ FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override;
// Shader creation
- virtual ShaderImpl *createShader(const gl::Data &data, GLenum type);
+ virtual CompilerImpl *createCompiler(const gl::Data &data);
+ virtual ShaderImpl *createShader(GLenum type);
virtual ProgramImpl *createProgram();
// Shader operations
- void releaseShaderCompiler() override;
virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, ShaderExecutable **outExecutable);
+ bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable);
virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround,
- ShaderExecutable **outExectuable);
- virtual UniformStorage *createUniformStorage(size_t storageSize);
+ bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds,
+ ShaderExecutableD3D **outExectuable);
+ virtual UniformStorageD3D *createUniformStorage(size_t storageSize);
// Image operations
- virtual Image *createImage();
- gl::Error generateMipmap(Image *dest, Image *source) override;
- virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
- virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
- virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels);
+ virtual ImageD3D *createImage();
+ gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override;
+ virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain);
+ virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly);
+ virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
@@ -166,7 +184,6 @@ class Renderer11 : public RendererD3D
// Renderbuffer creation
virtual RenderbufferImpl *createRenderbuffer();
- virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth);
// Buffer creation
virtual BufferImpl *createBuffer();
@@ -187,23 +204,22 @@ class Renderer11 : public RendererD3D
// D3D11-renderer specific methods
ID3D11Device *getDevice() { return mDevice; }
ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
+ ID3D11DeviceContext1 *getDeviceContext1IfSupported() { return mDeviceContext1; };
DXGIFactory *getDxgiFactory() { return mDxgiFactory; };
- bool isLevel9() { return mFeatureLevel <= D3D_FEATURE_LEVEL_9_3; }
Blit11 *getBlitter() { return mBlit; }
+ Clear11 *getClearer() { return mClear; }
// Buffer-to-texture and Texture-to-buffer copies
virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const;
- virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
- gl::Error getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, ID3D11Texture2D **texture2DOut);
-
void unapplyRenderTargets();
void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView);
gl::Error packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut);
- virtual bool getLUID(LUID *adapterLuid) const;
+ bool getLUID(LUID *adapterLuid) const override;
virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const;
@@ -212,48 +228,51 @@ class Renderer11 : public RendererD3D
void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv);
- private:
- DISALLOW_COPY_AND_ASSIGN(Renderer11);
+ gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTargetD3D *readRenderTarget,
+ RenderTargetD3D *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
+ bool colorBlit, bool depthBlit, bool stencilBlit);
+ bool isES3Capable() const;
+ D3D_FEATURE_LEVEL getFeatureLevel() const { return mFeatureLevel; };
+
+ RendererClass getRendererClass() const override { return RENDERER_D3D11; }
+
+ private:
void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override;
Workarounds generateWorkarounds() const override;
gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
gl::Error drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances);
- gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
- RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
- bool colorBlit, bool depthBlit, bool stencilBlit);
ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
- void unsetSRVsWithResource(gl::SamplerType shaderType, const ID3D11Resource *resource);
-
- static void invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel);
- static void invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer);
+ void unsetConflictingSRVs(gl::SamplerType shaderType, uintptr_t resource, const gl::ImageIndex *index);
HMODULE mD3d11Module;
HMODULE mDxgiModule;
- EGLNativeDisplayType mDc;
std::vector<D3D_FEATURE_LEVEL> mAvailableFeatureLevels;
D3D_DRIVER_TYPE mDriverType;
HLSLCompiler mCompiler;
- bool mDeviceLost;
-
void initializeDevice();
void releaseDeviceResources();
- int getMinorShaderModel() const;
void release();
RenderStateCache mStateCache;
// current render target states
- unsigned int mAppliedRenderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
- unsigned int mAppliedDepthbufferSerial;
- unsigned int mAppliedStencilbufferSerial;
+ uintptr_t mAppliedRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
+ uintptr_t mAppliedDSV;
bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized;
- RenderTarget::Desc mRenderTargetDesc;
+
+ struct RenderTargetDesc
+ {
+ size_t width;
+ size_t height;
+ DXGI_FORMAT format;
+ };
+ RenderTargetDesc mRenderTargetDesc;
// Currently applied sampler states
std::vector<bool> mForceSetVertexSamplerStates;
@@ -263,8 +282,14 @@ class Renderer11 : public RendererD3D
std::vector<gl::SamplerState> mCurPixelSamplerStates;
// Currently applied textures
- std::vector<ID3D11ShaderResourceView*> mCurVertexSRVs;
- std::vector<ID3D11ShaderResourceView*> mCurPixelSRVs;
+ struct SRVRecord
+ {
+ uintptr_t srv;
+ uintptr_t resource;
+ D3D11_SHADER_RESOURCE_VIEW_DESC desc;
+ };
+ std::vector<SRVRecord> mCurVertexSRVs;
+ std::vector<SRVRecord> mCurPixelSRVs;
// Currently applied blend state
bool mForceSetBlendState;
@@ -302,6 +327,7 @@ class Renderer11 : public RendererD3D
unsigned int mAppliedIBOffset;
// Currently applied transform feedback buffers
+ size_t mAppliedNumXFBBindings;
ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current D3D buffers
// in use for streamout
GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current GL-specified
@@ -312,22 +338,25 @@ class Renderer11 : public RendererD3D
// to different append behavior
// Currently applied shaders
- ID3D11VertexShader *mAppliedVertexShader;
- ID3D11GeometryShader *mAppliedGeometryShader;
- ID3D11GeometryShader *mCurPointGeometryShader;
- ID3D11PixelShader *mAppliedPixelShader;
+ uintptr_t mAppliedVertexShader;
+ uintptr_t mAppliedGeometryShader;
+ uintptr_t mAppliedPixelShader;
dx_VertexConstants mVertexConstants;
dx_VertexConstants mAppliedVertexConstants;
ID3D11Buffer *mDriverConstantBufferVS;
ID3D11Buffer *mCurrentVertexConstantBuffer;
unsigned int mCurrentConstantBufferVS[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
+ GLintptr mCurrentConstantBufferVSOffset[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
+ GLsizeiptr mCurrentConstantBufferVSSize[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
dx_PixelConstants mPixelConstants;
dx_PixelConstants mAppliedPixelConstants;
ID3D11Buffer *mDriverConstantBufferPS;
ID3D11Buffer *mCurrentPixelConstantBuffer;
- unsigned int mCurrentConstantBufferPS[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS];
+ unsigned int mCurrentConstantBufferPS[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS];
+ GLintptr mCurrentConstantBufferPSOffset[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS];
+ GLsizeiptr mCurrentConstantBufferPSSize[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS];
ID3D11Buffer *mCurrentGeometryConstantBuffer;
@@ -346,17 +375,26 @@ class Renderer11 : public RendererD3D
// Masked clear resources
Clear11 *mClear;
+ // Perform trim for D3D resources
+ Trim11 *mTrim;
+
// Sync query
ID3D11Query *mSyncQuery;
+ // Constant buffer offset support
+ bool mSupportsConstantBufferOffsets;
+
ID3D11Device *mDevice;
D3D_FEATURE_LEVEL mFeatureLevel;
ID3D11DeviceContext *mDeviceContext;
+ ID3D11DeviceContext1 *mDeviceContext1;
IDXGIAdapter *mDxgiAdapter;
DXGI_ADAPTER_DESC mAdapterDescription;
char mDescription[128];
DXGIFactory *mDxgiFactory;
+
+ DebugAnnotator11 mAnnotator;
};
}
-#endif // LIBGLESV2_RENDERER_RENDERER11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp
index 52f34887fb..7e64c3183d 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp
@@ -7,14 +7,14 @@
// ShaderExecutable11.cpp: Implements a D3D11-specific class to contain shader
// executable implementation details.
-#include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
namespace rx
{
ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable)
- : ShaderExecutable(function, length)
+ : ShaderExecutableD3D(function, length)
{
mPixelExecutable = executable;
mVertexExecutable = NULL;
@@ -23,7 +23,7 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D
}
ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable, ID3D11GeometryShader *streamOut)
- : ShaderExecutable(function, length)
+ : ShaderExecutableD3D(function, length)
{
mVertexExecutable = executable;
mPixelExecutable = NULL;
@@ -32,7 +32,7 @@ ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D
}
ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable)
- : ShaderExecutable(function, length)
+ : ShaderExecutableD3D(function, length)
{
mGeometryExecutable = executable;
mVertexExecutable = NULL;
@@ -48,7 +48,7 @@ ShaderExecutable11::~ShaderExecutable11()
SafeRelease(mStreamOutExecutable);
}
-ShaderExecutable11 *ShaderExecutable11::makeShaderExecutable11(ShaderExecutable *executable)
+ShaderExecutable11 *ShaderExecutable11::makeShaderExecutable11(ShaderExecutableD3D *executable)
{
ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable11*, executable));
return static_cast<ShaderExecutable11*>(executable);
@@ -75,7 +75,7 @@ ID3D11GeometryShader *ShaderExecutable11::getStreamOutShader() const
}
UniformStorage11::UniformStorage11(Renderer11 *renderer, size_t initialSize)
- : UniformStorage(initialSize),
+ : UniformStorageD3D(initialSize),
mConstantBuffer(NULL)
{
ID3D11Device *d3d11Device = renderer->getDevice();
@@ -101,7 +101,7 @@ UniformStorage11::~UniformStorage11()
SafeRelease(mConstantBuffer);
}
-const UniformStorage11 *UniformStorage11::makeUniformStorage11(const UniformStorage *uniformStorage)
+const UniformStorage11 *UniformStorage11::makeUniformStorage11(const UniformStorageD3D *uniformStorage)
{
ASSERT(HAS_DYNAMIC_TYPE(const UniformStorage11*, uniformStorage));
return static_cast<const UniformStorage11*>(uniformStorage);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h
index 74a1e03915..02558ee4dc 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h
@@ -7,17 +7,17 @@
// ShaderExecutable11.h: Defines a D3D11-specific class to contain shader
// executable implementation details.
-#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_
-#define LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_SHADEREXECUTABLE11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_SHADEREXECUTABLE11_H_
-#include "libGLESv2/renderer/ShaderExecutable.h"
+#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
namespace rx
{
class Renderer11;
class UniformStorage11;
-class ShaderExecutable11 : public ShaderExecutable
+class ShaderExecutable11 : public ShaderExecutableD3D
{
public:
ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable);
@@ -26,7 +26,7 @@ class ShaderExecutable11 : public ShaderExecutable
virtual ~ShaderExecutable11();
- static ShaderExecutable11 *makeShaderExecutable11(ShaderExecutable *executable);
+ static ShaderExecutable11 *makeShaderExecutable11(ShaderExecutableD3D *executable);
ID3D11PixelShader *getPixelShader() const;
ID3D11VertexShader *getVertexShader() const;
@@ -34,21 +34,19 @@ class ShaderExecutable11 : public ShaderExecutable
ID3D11GeometryShader *getStreamOutShader() const;
private:
- DISALLOW_COPY_AND_ASSIGN(ShaderExecutable11);
-
ID3D11PixelShader *mPixelExecutable;
ID3D11VertexShader *mVertexExecutable;
ID3D11GeometryShader *mGeometryExecutable;
ID3D11GeometryShader *mStreamOutExecutable;
};
-class UniformStorage11 : public UniformStorage
+class UniformStorage11 : public UniformStorageD3D
{
public:
UniformStorage11(Renderer11 *renderer, size_t initialSize);
virtual ~UniformStorage11();
- static const UniformStorage11 *makeUniformStorage11(const UniformStorage *uniformStorage);
+ static const UniformStorage11 *makeUniformStorage11(const UniformStorageD3D *uniformStorage);
ID3D11Buffer *getConstantBuffer() const { return mConstantBuffer; }
@@ -58,4 +56,4 @@ class UniformStorage11 : public UniformStorage
}
-#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_SHADEREXECUTABLE11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
index 52c8a81633..298f3ccbd2 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
@@ -6,17 +6,17 @@
// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
-#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
-#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h"
+#include "libANGLE/features.h"
// Precompiled shaders
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h"
-#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
-#include "common/features.h"
-#include "common/NativeWindow.h"
namespace rx
{
@@ -24,7 +24,9 @@ namespace rx
SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat)
: mRenderer(renderer),
- SwapChain(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat)
+ SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat),
+ mColorRenderTarget(this, renderer, false),
+ mDepthStencilRenderTarget(this, renderer, true)
{
mSwapChain = NULL;
mBackBufferTexture = NULL;
@@ -42,8 +44,6 @@ SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE
mPassThroughPS = NULL;
mWidth = -1;
mHeight = -1;
- mRotateL = false;
- mRotateR = false;
mSwapInterval = 0;
mAppCreatedShareHandle = mShareHandle != NULL;
mPassThroughResourcesInit = false;
@@ -94,11 +94,10 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
ASSERT(device != NULL);
// D3D11 does not allow zero size textures
- ASSERT(backbufferWidth != 0);
- ASSERT(backbufferHeight != 0);
+ ASSERT(backbufferWidth >= 1);
+ ASSERT(backbufferHeight >= 1);
// Preserve the render target content
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture;
if (previousOffscreenTexture)
{
@@ -106,11 +105,10 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
}
const int previousWidth = mWidth;
const int previousHeight = mHeight;
-#endif
releaseOffscreenTexture();
- const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat);
+ const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getFeatureLevel());
// If the app passed in a share handle, open the resource
// See EGL_ANGLE_d3d_share_handle_client_buffer
@@ -140,8 +138,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
mOffscreenTexture->GetDesc(&offscreenTextureDesc);
- if (offscreenTextureDesc.Width != UINT(abs(backbufferWidth)) ||
- offscreenTextureDesc.Height != UINT(abs(backbufferHeight)) ||
+ if (offscreenTextureDesc.Width != (UINT)backbufferWidth ||
+ offscreenTextureDesc.Height != (UINT)backbufferHeight ||
offscreenTextureDesc.Format != backbufferFormatInfo.texFormat ||
offscreenTextureDesc.MipLevels != 1 ||
offscreenTextureDesc.ArraySize != 1)
@@ -156,8 +154,14 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport();
D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
- offscreenTextureDesc.Width = abs(backbufferWidth);
- offscreenTextureDesc.Height = abs(backbufferHeight);
+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ const int textureLength = std::max(backbufferWidth, backbufferHeight);
+ offscreenTextureDesc.Width = textureLength;
+ offscreenTextureDesc.Height = textureLength;
+#else
+ offscreenTextureDesc.Width = backbufferWidth;
+ offscreenTextureDesc.Height = backbufferHeight;
+#endif
offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
offscreenTextureDesc.MipLevels = 1;
offscreenTextureDesc.ArraySize = 1;
@@ -226,26 +230,38 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat;
offscreenSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
offscreenSRVDesc.Texture2D.MostDetailedMip = 0;
- offscreenSRVDesc.Texture2D.MipLevels = -1;
+ offscreenSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1);
result = device->CreateShaderResourceView(mOffscreenTexture, &offscreenSRVDesc, &mOffscreenSRView);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mOffscreenSRView, "Offscreen back buffer shader resource");
- const d3d11::TextureFormat &depthBufferFormatInfo = d3d11::GetTextureFormatInfo(mDepthBufferFormat);
+ const d3d11::TextureFormat &depthBufferFormatInfo = d3d11::GetTextureFormatInfo(mDepthBufferFormat, mRenderer->getFeatureLevel());
if (mDepthBufferFormat != GL_NONE)
{
D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
- depthStencilTextureDesc.Width = abs(backbufferWidth);
- depthStencilTextureDesc.Height = abs(backbufferHeight);
+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ const int textureLength = std::max(backbufferWidth, backbufferHeight);
+ depthStencilTextureDesc.Width = textureLength;
+ depthStencilTextureDesc.Height = textureLength;
+#else
+ depthStencilTextureDesc.Width = backbufferWidth;
+ depthStencilTextureDesc.Height = backbufferHeight;
+#endif
depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
depthStencilTextureDesc.MipLevels = 1;
depthStencilTextureDesc.ArraySize = 1;
depthStencilTextureDesc.SampleDesc.Count = 1;
depthStencilTextureDesc.SampleDesc.Quality = 0;
depthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT;
- depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
+ depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+
+ if (depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ depthStencilTextureDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
+ }
+
depthStencilTextureDesc.CPUAccessFlags = 0;
depthStencilTextureDesc.MiscFlags = 0;
@@ -276,21 +292,23 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mDepthStencilDSView, "Offscreen depth stencil view");
- D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc;
- depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat;
- depthStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
- depthStencilSRVDesc.Texture2D.MostDetailedMip = 0;
- depthStencilSRVDesc.Texture2D.MipLevels = -1;
-
- result = device->CreateShaderResourceView(mDepthStencilTexture, &depthStencilSRVDesc, &mDepthStencilSRView);
- ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mDepthStencilSRView, "Offscreen depth stencil shader resource");
+ if (depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc;
+ depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat;
+ depthStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ depthStencilSRVDesc.Texture2D.MostDetailedMip = 0;
+ depthStencilSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1);
+
+ result = device->CreateShaderResourceView(mDepthStencilTexture, &depthStencilSRVDesc, &mDepthStencilSRView);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mDepthStencilSRView, "Offscreen depth stencil shader resource");
+ }
}
mWidth = backbufferWidth;
mHeight = backbufferHeight;
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
if (previousOffscreenTexture != NULL)
{
D3D11_BOX sourceBox = {0};
@@ -312,7 +330,6 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
swapRect(0, 0, mWidth, mHeight);
}
}
-#endif
return EGL_SUCCESS;
}
@@ -326,31 +343,23 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
return EGL_BAD_ACCESS;
}
- // Windows Phone works around the rotation limitation by using negative values for the swap chain size
-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
- mRotateL = backbufferWidth < 0; // Landscape/InvertedLandscape
- mRotateR = backbufferHeight < 0; // InvertedPortrait/InvertedLandscape
- backbufferWidth = abs(backbufferWidth);
- backbufferHeight = abs(backbufferHeight);
-#endif
-
// EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
- if (backbufferWidth == 0 || backbufferHeight == 0)
+ if (backbufferWidth < 1 || backbufferHeight < 1)
{
return EGL_SUCCESS;
}
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
// Can only call resize if we have already created our swap buffer and resources
ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // The swap chain is not directly resized on Windows Phone
SafeRelease(mBackBufferTexture);
SafeRelease(mBackBufferRTView);
// Resize swap chain
DXGI_SWAP_CHAIN_DESC desc;
mSwapChain->GetDesc(&desc);
- const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat);
+ const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getFeatureLevel());
HRESULT result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0);
if (FAILED(result))
@@ -381,9 +390,14 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
{
d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
}
-#endif
return resetOffscreenTexture(backbufferWidth, backbufferHeight);
+#else
+ // Do nothing on Windows Phone apart from updating the internal buffer/width height
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
+ return EGL_SUCCESS;
+#endif
}
EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
@@ -417,7 +431,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
if (mNativeWindow.getNativeWindow())
{
- const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat);
+ const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getFeatureLevel());
HRESULT result = mNativeWindow.createSwapChain(device, mRenderer->getDxgiFactory(),
backbufferFormatInfo.texFormat,
@@ -528,20 +542,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
- // 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);
-
- const bool rotateL = mRotateL;
- const bool rotateR = mRotateR;
-
// Set vertices
D3D11_MAPPED_SUBRESOURCE mappedResource;
HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
@@ -552,10 +552,37 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
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;
+
+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ const float dim = std::max(mWidth, mHeight);
+ float u1 = x / dim;
+ float v1 = y / dim;
+ float u2 = (x + width) / dim;
+ float v2 = (y + height) / dim;
+
+ const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags();
+ const bool rotateL = flags == NativeWindow::RotateLeft;
+ const bool rotateR = flags == NativeWindow::RotateRight;
d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1);
d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2);
d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1);
d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2);
+#else
+ float u1 = x / float(mWidth);
+ float v1 = y / float(mHeight);
+ float u2 = (x + width) / float(mWidth);
+ float v2 = (y + height) / float(mHeight);
+
+ 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);
+#endif
deviceContext->Unmap(mQuadVB, 0);
@@ -583,11 +610,15 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
// Set the viewport
D3D11_VIEWPORT viewport;
- viewport.TopLeftX = 0.0f;
- viewport.TopLeftY = 0.0f;
- const bool invertViewport = (mRotateL || mRotateR) && !(mRotateL && mRotateR);
- viewport.Width = FLOAT(invertViewport ? mHeight : mWidth);
- viewport.Height = FLOAT(invertViewport ? mWidth : mHeight);
+ viewport.TopLeftX = 0;
+ viewport.TopLeftY = 0;
+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ viewport.Width = (rotateL || rotateR) ? mHeight : mWidth;
+ viewport.Height = (rotateL || rotateR) ? mWidth : mHeight;
+#else
+ viewport.Width = mWidth;
+ viewport.Height = mHeight;
+#endif
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
@@ -661,7 +692,7 @@ ID3D11Texture2D *SwapChain11::getDepthStencilTexture()
return mDepthStencilTexture;
}
-SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain)
+SwapChain11 *SwapChain11::makeSwapChain11(SwapChainD3D *swapChain)
{
ASSERT(HAS_DYNAMIC_TYPE(SwapChain11*, swapChain));
return static_cast<SwapChain11*>(swapChain);
@@ -672,4 +703,9 @@ void SwapChain11::recreate()
// possibly should use this method instead of reset
}
+void *rx::SwapChain11::getDevice()
+{
+ return mRenderer->getDevice();
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
index 77509edcd3..48c808a261 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
@@ -6,17 +6,18 @@
// SwapChain11.h: Defines a back-end specific class for the D3D11 swap chain.
-#ifndef LIBGLESV2_RENDERER_SWAPCHAIN11_H_
-#define LIBGLESV2_RENDERER_SWAPCHAIN11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_
#include "common/angleutils.h"
-#include "libGLESv2/renderer/SwapChain.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
namespace rx
{
class Renderer11;
-class SwapChain11 : public SwapChain
+class SwapChain11 : public SwapChainD3D
{
public:
SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
@@ -28,6 +29,9 @@ class SwapChain11 : public SwapChain
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
virtual void recreate();
+ RenderTargetD3D *getColorRenderTarget() override { return &mColorRenderTarget; }
+ RenderTargetD3D *getDepthStencilRenderTarget() override { return &mDepthStencilRenderTarget; }
+
virtual ID3D11Texture2D *getOffscreenTexture();
virtual ID3D11RenderTargetView *getRenderTarget();
virtual ID3D11ShaderResourceView *getRenderTargetShaderResource();
@@ -39,11 +43,11 @@ class SwapChain11 : public SwapChain
EGLint getWidth() const { return mWidth; }
EGLint getHeight() const { return mHeight; }
- static SwapChain11 *makeSwapChain11(SwapChain *swapChain);
+ virtual void *getDevice();
- private:
- DISALLOW_COPY_AND_ASSIGN(SwapChain11);
+ static SwapChain11 *makeSwapChain11(SwapChainD3D *swapChain);
+ private:
void release();
void initPassThroughResources();
void releaseOffscreenTexture();
@@ -52,8 +56,6 @@ class SwapChain11 : public SwapChain
Renderer11 *mRenderer;
EGLint mHeight;
EGLint mWidth;
- bool mRotateL;
- bool mRotateR;
bool mAppCreatedShareHandle;
unsigned int mSwapInterval;
bool mPassThroughResourcesInit;
@@ -76,7 +78,10 @@ class SwapChain11 : public SwapChain
ID3D11InputLayout *mPassThroughIL;
ID3D11VertexShader *mPassThroughVS;
ID3D11PixelShader *mPassThroughPS;
+
+ SurfaceRenderTarget11 mColorRenderTarget;
+ SurfaceRenderTarget11 mDepthStencilRenderTarget;
};
}
-#endif // LIBGLESV2_RENDERER_SWAPCHAIN11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
index 74af27e8b3..103e90fed3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -7,23 +7,22 @@
// 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 "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
+#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
#include <tuple>
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
-#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
-#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
-#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/ImageIndex.h"
-
+#include "common/MemoryBuffer.h"
#include "common/utilities.h"
+#include "libANGLE/ImageIndex.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/Blit11.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/SwapChain11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
namespace rx
{
@@ -102,11 +101,11 @@ TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage
return static_cast<TextureStorage11*>(storage);
}
-DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, bool renderTarget)
+DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel, bool renderTarget)
{
UINT bindFlags = 0;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, featureLevel);
if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
{
bindFlags |= D3D11_BIND_SHADER_RESOURCE;
@@ -176,11 +175,27 @@ gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11S
{
bool swizzleRequired = samplerState.swizzleRequired();
bool mipmapping = gl::IsMipmapFiltered(samplerState);
- unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel) : 1;
+ unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel + 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 - samplerState.baseLevel);
+ if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3)
+ {
+ ASSERT(!swizzleRequired);
+ ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
+ }
+
+ if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
+ {
+ // We must ensure that the level zero texture is in sync with mipped texture.
+ gl::Error error = useLevelZeroWorkaroundTexture(mipLevels == 1);
+ if (error.isError())
+ {
+ return error;
+ }
+ }
+
if (swizzleRequired)
{
verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha);
@@ -329,7 +344,19 @@ gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, u
copyArea.depth == texSize.depth;
ID3D11Resource *dstTexture = NULL;
- gl::Error error = getResource(&dstTexture);
+ gl::Error error(GL_NO_ERROR);
+
+ // If the zero-LOD workaround is active and we want to update a level greater than zero, then we should
+ // update the mipmapped texture, even if mapmaps are currently disabled.
+ if (index.mipIndex > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround)
+ {
+ error = getMippedResource(&dstTexture);
+ }
+ else
+ {
+ error = getResource(&dstTexture);
+ }
+
if (error.isError())
{
return error;
@@ -351,8 +378,6 @@ gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, u
}
else
{
- const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
-
D3D11_BOX srcBox;
srcBox.left = copyArea.x;
srcBox.top = copyArea.y;
@@ -375,7 +400,19 @@ gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, uns
ASSERT(dstTexture);
ID3D11Resource *srcTexture = NULL;
- gl::Error error = getResource(&srcTexture);
+ gl::Error error(GL_NO_ERROR);
+
+ // If the zero-LOD workaround is active and we want to update a level greater than zero, then we should
+ // update the mipmapped texture, even if mapmaps are currently disabled.
+ if (index.mipIndex > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround)
+ {
+ error = getMippedResource(&srcTexture);
+ }
+ else
+ {
+ error = getResource(&srcTexture);
+ }
+
if (error.isError())
{
return error;
@@ -386,8 +423,28 @@ gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, uns
unsigned int srcSubresource = getSubresourceIndex(index);
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+ // D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox should be NULL.
+ D3D11_BOX srcBox;
+ D3D11_BOX *pSrcBox = NULL;
+ if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3)
+ {
+ // 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(d3d11::GetDXGIFormatInfo(mTextureFormat).depthBits == 0);
+ ASSERT(d3d11::GetDXGIFormatInfo(mTextureFormat).stencilBits == 0);
+ 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;
+ }
+
context->CopySubresourceRegion(dstTexture, dstSubresource, region.x, region.y, region.z,
- srcTexture, srcSubresource, NULL);
+ srcTexture, srcSubresource, pSrcBox);
return gl::Error(GL_NO_ERROR);
}
@@ -398,14 +455,14 @@ gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, co
invalidateSwizzleCacheLevel(destIndex.mipIndex);
- RenderTarget *source = NULL;
+ RenderTargetD3D *source = NULL;
gl::Error error = getRenderTarget(sourceIndex, &source);
if (error.isError())
{
return error;
}
- RenderTarget *dest = NULL;
+ RenderTargetD3D *dest = NULL;
error = getRenderTarget(destIndex, &dest);
if (error.isError())
{
@@ -462,9 +519,11 @@ gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage)
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
{
+ ASSERT(!image->isDirty());
+
ID3D11Resource *resource = NULL;
gl::Error error = getResource(&resource);
if (error.isError())
@@ -477,7 +536,8 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, c
const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(image->getInternalFormat());
- bool fullUpdate = (destBox == NULL || *destBox == gl::Box(0, 0, 0, mTextureWidth, mTextureHeight, mTextureDepth));
+ gl::Box levelBox(0, 0, 0, getLevelWidth(index.mipIndex), getLevelHeight(index.mipIndex), getLevelDepth(index.mipIndex));
+ bool fullUpdate = (destBox == NULL || *destBox == levelBox);
ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate);
// TODO(jmadill): Handle compressed formats
@@ -489,10 +549,10 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, c
int width = destBox ? destBox->width : static_cast<int>(image->getWidth());
int height = destBox ? destBox->height : static_cast<int>(image->getHeight());
int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth());
- UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment);
- UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment);
+ UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength);
+ UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment, unpack.rowLength);
- const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat());
+ const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat(), mRenderer->getFeatureLevel());
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat);
size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
@@ -500,17 +560,19 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, c
UINT bufferRowPitch = outputPixelSize * width;
UINT bufferDepthPitch = bufferRowPitch * height;
- MemoryBuffer conversionBuffer;
- if (!conversionBuffer.resize(bufferDepthPitch * depth))
+ size_t neededSize = bufferDepthPitch * depth;
+ MemoryBuffer *conversionBuffer = NULL;
+ error = mRenderer->getScratchMemoryBuffer(neededSize, &conversionBuffer);
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer.");
+ return error;
}
// TODO: fast path
LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type);
loadFunction(width, height, depth,
pixelData, srcRowPitch, srcDepthPitch,
- conversionBuffer.data(), bufferRowPitch, bufferDepthPitch);
+ conversionBuffer->data(), bufferRowPitch, bufferDepthPitch);
ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
@@ -523,17 +585,17 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, c
destD3DBox.right = destBox->x + destBox->width;
destD3DBox.top = destBox->y;
destD3DBox.bottom = destBox->y + destBox->height;
- destD3DBox.front = 0;
- destD3DBox.back = 1;
+ destD3DBox.front = destBox->z;
+ destD3DBox.back = destBox->z + destBox->depth;
immediateContext->UpdateSubresource(resource, destSubresource,
- &destD3DBox, conversionBuffer.data(),
+ &destD3DBox, conversionBuffer->data(),
bufferRowPitch, bufferDepthPitch);
}
else
{
immediateContext->UpdateSubresource(resource, destSubresource,
- NULL, conversionBuffer.data(),
+ NULL, conversionBuffer->data(),
bufferRowPitch, bufferDepthPitch);
}
@@ -543,7 +605,10 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, Image *image, c
TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain)
: TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
mTexture(swapchain->getOffscreenTexture()),
- mSwizzleTexture(NULL)
+ mSwizzleTexture(NULL),
+ mLevelZeroTexture(NULL),
+ mLevelZeroRenderTarget(NULL),
+ mUseLevelZeroTexture(false)
{
mTexture->AddRef();
@@ -575,7 +640,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swap
mRenderTargetFormat = rtvDesc.Format;
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat, mRenderer->getFeatureLevel());
mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
@@ -585,10 +650,13 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swap
initializeSerials(1, 1);
}
-TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
- : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)),
+TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly)
+ : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget)),
mTexture(NULL),
- mSwizzleTexture(NULL)
+ mSwizzleTexture(NULL),
+ mLevelZeroTexture(NULL),
+ mLevelZeroRenderTarget(NULL),
+ mUseLevelZeroTexture(false)
{
for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
@@ -599,7 +667,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalfo
mInternalFormat = internalformat;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel());
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
mDepthStencilFormat = formatInfo.dsvFormat;
@@ -614,6 +682,13 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalfo
mTextureHeight = height;
mTextureDepth = 1;
+ if (hintLevelZeroOnly && levels > 1)
+ {
+ //The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
+ ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround);
+ mUseLevelZeroTexture = true;
+ }
+
initializeSerials(getLevelCount(), 1);
}
@@ -641,6 +716,9 @@ TextureStorage11_2D::~TextureStorage11_2D()
SafeRelease(mTexture);
SafeRelease(mSwizzleTexture);
+ SafeRelease(mLevelZeroTexture);
+ SafeDelete(mLevelZeroRenderTarget);
+
for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
SafeDelete(mRenderTarget[i]);
@@ -654,6 +732,120 @@ TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage
return static_cast<TextureStorage11_2D*>(storage);
}
+gl::Error TextureStorage11_2D::copyToStorage(TextureStorage *destStorage)
+{
+ ASSERT(destStorage);
+
+ TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(destStorage);
+
+ if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
+ {
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+
+ // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the corresponding textures in destStorage.
+ if (mTexture)
+ {
+ gl::Error error = dest11->useLevelZeroWorkaroundTexture(false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11Resource *destResource = NULL;
+ error = dest11->getResource(&destResource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ immediateContext->CopyResource(destResource, mTexture);
+ }
+
+ if (mLevelZeroTexture)
+ {
+ gl::Error error = dest11->useLevelZeroWorkaroundTexture(true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11Resource *destResource = NULL;
+ error = dest11->getResource(&destResource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ immediateContext->CopyResource(destResource, mLevelZeroTexture);
+ }
+ }
+ else
+ {
+ ID3D11Resource *sourceResouce = NULL;
+ gl::Error error = getResource(&sourceResouce);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11Resource *destResource = NULL;
+ error = dest11->getResource(&destResource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+ immediateContext->CopyResource(destResource, sourceResouce);
+ }
+
+ dest11->invalidateSwizzleCache();
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(bool useLevelZeroTexture)
+{
+ if (useLevelZeroTexture && mMipLevels > 1)
+ {
+ if (!mUseLevelZeroTexture && mTexture)
+ {
+ gl::Error error = ensureTextureExists(1);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ // Pull data back from the mipped texture if necessary.
+ ASSERT(mLevelZeroTexture);
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ context->CopySubresourceRegion(mLevelZeroTexture, 0, 0, 0, 0, mTexture, 0, NULL);
+ }
+
+ mUseLevelZeroTexture = true;
+ }
+ else
+ {
+ if (mUseLevelZeroTexture && mLevelZeroTexture)
+ {
+ gl::Error error = ensureTextureExists(mMipLevels);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ // Pull data back from the level zero texture if necessary.
+ ASSERT(mTexture);
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ context->CopySubresourceRegion(mTexture, 0, 0, 0, 0, mLevelZeroTexture, 0, NULL);
+ }
+
+ mUseLevelZeroTexture = false;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &index)
{
GLint level = index.mipIndex;
@@ -733,18 +925,63 @@ gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &inde
gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource)
{
+ if (mUseLevelZeroTexture && mMipLevels > 1)
+ {
+ gl::Error error = ensureTextureExists(1);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *outResource = mLevelZeroTexture;
+ return gl::Error(GL_NO_ERROR);
+ }
+ else
+ {
+ gl::Error error = ensureTextureExists(mMipLevels);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
+ }
+}
+
+gl::Error TextureStorage11_2D::getMippedResource(ID3D11Resource **outResource)
+{
+ // This shouldn't be called unless the zero max LOD workaround is active.
+ ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround);
+
+ gl::Error error = ensureTextureExists(mMipLevels);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11_2D::ensureTextureExists(int mipLevels)
+{
+ // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
+ bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround ? (mipLevels == 1) && (mMipLevels > 1) : false;
+ ID3D11Texture2D **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 (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
+ if (*outputTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
{
- ASSERT(mMipLevels > 0);
+ ASSERT(mipLevels > 0);
ID3D11Device *device = mRenderer->getDevice();
D3D11_TEXTURE2D_DESC desc;
desc.Width = mTextureWidth; // Compressed texture size constraints?
desc.Height = mTextureHeight;
- desc.MipLevels = mRenderer->isLevel9() ? 1 : mMipLevels;
+ desc.MipLevels = mipLevels;
desc.ArraySize = 1;
desc.Format = mTextureFormat;
desc.SampleDesc.Count = 1;
@@ -754,7 +991,7 @@ gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource)
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
- HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+ HRESULT result = device->CreateTexture2D(&desc, NULL, outputTexture);
// this can happen from windows TDR
if (d3d11::isDeviceLostError(result))
@@ -769,17 +1006,23 @@ gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource)
}
}
- *outResource = mTexture;
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT)
{
ASSERT(!index.hasLayer());
int level = index.mipIndex;
ASSERT(level >= 0 && level < getLevelCount());
+ // 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->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3 && level > 0));
+
if (!mRenderTarget[level])
{
ID3D11Resource *texture = NULL;
@@ -796,6 +1039,37 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend
return error;
}
+ if (mUseLevelZeroTexture)
+ {
+ if (!mLevelZeroRenderTarget)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + level;
+
+ ID3D11RenderTargetView *rtv;
+ HRESULT result = device->CreateRenderTargetView(mLevelZeroTexture, &rtvDesc, &rtv);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+ }
+ ASSERT(SUCCEEDED(result));
+
+ mLevelZeroRenderTarget = new TextureRenderTarget11(rtv, mLevelZeroTexture, NULL, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
+
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ }
+
+ ASSERT(outRT);
+ *outRT = mLevelZeroRenderTarget;
+ return gl::Error(GL_NO_ERROR);
+ }
+
if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
{
ID3D11Device *device = mRenderer->getDevice();
@@ -863,10 +1137,32 @@ gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORM
srvDesc.Format = format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
- srvDesc.Texture2D.MipLevels = mRenderer->isLevel9() ? -1 : mipLevels;
+ srvDesc.Texture2D.MipLevels = mipLevels;
+
+ ID3D11Resource *srvTexture = texture;
+
+ if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
+ {
+ 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.
+ ASSERT(mLevelZeroTexture != NULL && texture == mLevelZeroTexture);
+ srvTexture = mLevelZeroTexture;
+ }
+ else
+ {
+ ASSERT(mipLevels == static_cast<int>(mMipLevels));
+ ASSERT(mTexture != NULL && texture == mTexture);
+ srvTexture = mTexture;
+ }
+ }
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
+ HRESULT result = device->CreateShaderResourceView(srvTexture, &srvDesc, outSRV);
ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
if (FAILED(result))
@@ -945,8 +1241,8 @@ gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11Render
return gl::Error(GL_NO_ERROR);
}
-TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
- : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
+TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly)
+ : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget))
{
mTexture = NULL;
mSwizzleTexture = NULL;
@@ -961,9 +1257,17 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum intern
}
}
+ mLevelZeroTexture = NULL;
+ mUseLevelZeroTexture = false;
+
+ for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
+ {
+ mLevelZeroRenderTarget[face] = NULL;
+ }
+
mInternalFormat = internalformat;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel());
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
mDepthStencilFormat = formatInfo.dsvFormat;
@@ -981,6 +1285,13 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum intern
mTextureHeight = size;
mTextureDepth = 1;
+ if (hintLevelZeroOnly && levels > 1)
+ {
+ //The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
+ ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround);
+ mUseLevelZeroTexture = true;
+ }
+
initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT);
}
@@ -1006,6 +1317,12 @@ TextureStorage11_Cube::~TextureStorage11_Cube()
SafeRelease(mTexture);
SafeRelease(mSwizzleTexture);
+ SafeRelease(mLevelZeroTexture);
+
+ for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++)
+ {
+ SafeDelete(mLevelZeroRenderTarget[face]);
+ }
for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
@@ -1023,6 +1340,147 @@ TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureS
return static_cast<TextureStorage11_Cube*>(storage);
}
+UINT TextureStorage11_Cube::getSubresourceIndex(const gl::ImageIndex &index) const
+{
+ if (mRenderer->getWorkarounds().zeroMaxLodWorkaround && mUseLevelZeroTexture && index.mipIndex == 0)
+ {
+ UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.layerIndex : 0);
+ UINT subresource = D3D11CalcSubresource(0, arraySlice, 1);
+ ASSERT(subresource != std::numeric_limits<UINT>::max());
+ return subresource;
+ }
+ else
+ {
+ UINT mipSlice = static_cast<UINT>(index.mipIndex + mTopLevel);
+ UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.layerIndex : 0);
+ UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
+ ASSERT(subresource != std::numeric_limits<UINT>::max());
+ return subresource;
+ }
+}
+
+gl::Error TextureStorage11_Cube::copyToStorage(TextureStorage *destStorage)
+{
+ ASSERT(destStorage);
+
+ TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(destStorage);
+
+ if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
+ {
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+
+ // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the corresponding textures in destStorage.
+ if (mTexture)
+ {
+ gl::Error error = dest11->useLevelZeroWorkaroundTexture(false);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11Resource *destResource = NULL;
+ error = dest11->getResource(&destResource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ immediateContext->CopyResource(destResource, mTexture);
+ }
+
+ if (mLevelZeroTexture)
+ {
+ gl::Error error = dest11->useLevelZeroWorkaroundTexture(true);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11Resource *destResource = NULL;
+ error = dest11->getResource(&destResource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ immediateContext->CopyResource(destResource, mLevelZeroTexture);
+ }
+ }
+ else
+ {
+ ID3D11Resource *sourceResouce = NULL;
+ gl::Error error = getResource(&sourceResouce);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11Resource *destResource = NULL;
+ error = dest11->getResource(&destResource);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+ immediateContext->CopyResource(destResource, sourceResouce);
+ }
+
+ dest11->invalidateSwizzleCache();
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11_Cube::useLevelZeroWorkaroundTexture(bool useLevelZeroTexture)
+{
+ if (useLevelZeroTexture && mMipLevels > 1)
+ {
+ if (!mUseLevelZeroTexture && mTexture)
+ {
+ gl::Error error = ensureTextureExists(1);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ // Pull data back from the mipped texture if necessary.
+ ASSERT(mLevelZeroTexture);
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+ for (int face = 0; face < 6; face++)
+ {
+ context->CopySubresourceRegion(mLevelZeroTexture, D3D11CalcSubresource(0, face, 1), 0, 0, 0, mTexture, face * mMipLevels, NULL);
+ }
+ }
+
+ mUseLevelZeroTexture = true;
+ }
+ else
+ {
+ if (mUseLevelZeroTexture && mLevelZeroTexture)
+ {
+ gl::Error error = ensureTextureExists(mMipLevels);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ // Pull data back from the level zero texture if necessary.
+ ASSERT(mTexture);
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+ for (int face = 0; face < 6; face++)
+ {
+ context->CopySubresourceRegion(mTexture, D3D11CalcSubresource(0, face, mMipLevels), 0, 0, 0, mLevelZeroTexture, face, NULL);
+ }
+ }
+
+ mUseLevelZeroTexture = false;
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
void TextureStorage11_Cube::associateImage(Image11* image, const gl::ImageIndex &index)
{
GLint level = index.mipIndex;
@@ -1121,9 +1579,54 @@ gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &in
gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource)
{
+ if (mUseLevelZeroTexture && mMipLevels > 1)
+ {
+ gl::Error error = ensureTextureExists(1);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *outResource = mLevelZeroTexture;
+ return gl::Error(GL_NO_ERROR);
+ }
+ else
+ {
+ gl::Error error = ensureTextureExists(mMipLevels);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
+ }
+}
+
+gl::Error TextureStorage11_Cube::getMippedResource(ID3D11Resource **outResource)
+{
+ // This shouldn't be called unless the zero max LOD workaround is active.
+ ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround);
+
+ gl::Error error = ensureTextureExists(mMipLevels);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ *outResource = mTexture;
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error TextureStorage11_Cube::ensureTextureExists(int mipLevels)
+{
+ // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
+ bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround ? (mipLevels == 1) && (mMipLevels > 1) : false;
+ ID3D11Texture2D **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 (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
+ if (*outputTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0)
{
ASSERT(mMipLevels > 0);
@@ -1132,7 +1635,7 @@ gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource)
D3D11_TEXTURE2D_DESC desc;
desc.Width = mTextureWidth;
desc.Height = mTextureHeight;
- desc.MipLevels = mMipLevels;
+ desc.MipLevels = mipLevels;
desc.ArraySize = CUBE_FACE_COUNT;
desc.Format = mTextureFormat;
desc.SampleDesc.Count = 1;
@@ -1142,7 +1645,7 @@ gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource)
desc.CPUAccessFlags = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
- HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+ HRESULT result = device->CreateTexture2D(&desc, NULL, outputTexture);
// this can happen from windows TDR
if (d3d11::isDeviceLostError(result))
@@ -1157,11 +1660,10 @@ gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource)
}
}
- *outResource = mTexture;
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT)
{
int faceIndex = index.layerIndex;
int level = index.mipIndex;
@@ -1181,14 +1683,53 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re
return error;
}
+ if (mUseLevelZeroTexture)
+ {
+ if (!mLevelZeroRenderTarget[faceIndex])
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ rtvDesc.Texture2DArray.ArraySize = 1;
+
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(mLevelZeroTexture, &rtvDesc, &rtv);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result);
+ }
+ ASSERT(SUCCEEDED(result));
+
+ mLevelZeroRenderTarget[faceIndex] = new TextureRenderTarget11(rtv, mLevelZeroTexture, NULL, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0);
+
+ // RenderTarget will take ownership of these resources
+ SafeRelease(rtv);
+ }
+
+ ASSERT(outRT);
+ *outRT = mLevelZeroRenderTarget[faceIndex];
+ return gl::Error(GL_NO_ERROR);
+ }
+
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = mShaderResourceFormat;
- srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
srvDesc.Texture2DArray.ArraySize = 1;
+ if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+ }
+ else
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
+ }
+
ID3D11ShaderResourceView *srv;
result = device->CreateShaderResourceView(texture, &srvDesc, &srv);
@@ -1285,8 +1826,30 @@ gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FO
srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
}
+ ID3D11Resource *srvTexture = texture;
+
+ if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
+ {
+ 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.
+ ASSERT(mLevelZeroTexture != NULL && texture == mLevelZeroTexture);
+ srvTexture = mLevelZeroTexture;
+ }
+ else
+ {
+ ASSERT(mipLevels == static_cast<int>(mMipLevels));
+ ASSERT(mTexture != NULL && texture == mTexture);
+ srvTexture = mTexture;
+ }
+ }
+
ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
+ HRESULT result = device->CreateShaderResourceView(srvTexture, &srvDesc, outSRV);
ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result));
if (FAILED(result))
@@ -1369,7 +1932,7 @@ gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11Rend
TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels)
- : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
+ : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget))
{
mTexture = NULL;
mSwizzleTexture = NULL;
@@ -1383,7 +1946,7 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalfo
mInternalFormat = internalformat;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel());
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
mDepthStencilFormat = formatInfo.dsvFormat;
@@ -1582,7 +2145,7 @@ gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORM
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT)
{
int mipLevel = index.mipIndex;
ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
@@ -1614,7 +2177,7 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
rtvDesc.Texture3D.FirstWSlice = 0;
- rtvDesc.Texture3D.WSize = -1;
+ rtvDesc.Texture3D.WSize = static_cast<UINT>(-1);
ID3D11RenderTargetView *rtv;
HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv);
@@ -1738,7 +2301,7 @@ gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11Render
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
rtvDesc.Texture3D.FirstWSlice = 0;
- rtvDesc.Texture3D.WSize = -1;
+ rtvDesc.Texture3D.WSize = static_cast<UINT>(-1);
HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
@@ -1755,7 +2318,7 @@ gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11Render
TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth, int levels)
- : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
+ : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget))
{
mTexture = NULL;
mSwizzleTexture = NULL;
@@ -1767,7 +2330,7 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum
mInternalFormat = internalformat;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel());
mTextureFormat = formatInfo.texFormat;
mShaderResourceFormat = formatInfo.srvFormat;
mDepthStencilFormat = formatInfo.dsvFormat;
@@ -1791,13 +2354,16 @@ TextureStorage11_2DArray::~TextureStorage11_2DArray()
{
for (ImageMap::iterator i = mAssociatedImages.begin(); i != mAssociatedImages.end(); i++)
{
- bool imageAssociationCorrect = i->second->isAssociatedStorageValid(this);
- ASSERT(imageAssociationCorrect);
-
- if (imageAssociationCorrect)
+ if (i->second)
{
- // We must let the Images recover their data before we delete it from the TextureStorage.
- i->second->recoverFromAssociatedStorage();
+ bool imageAssociationCorrect = i->second->isAssociatedStorageValid(this);
+ ASSERT(imageAssociationCorrect);
+
+ if (imageAssociationCorrect)
+ {
+ // We must let the Images recover their data before we delete it from the TextureStorage.
+ i->second->recoverFromAssociatedStorage();
+ }
}
}
mAssociatedImages.clear();
@@ -1875,8 +2441,6 @@ gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex
LevelLayerKey key(level, layerTarget);
- ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end());
-
if (mAssociatedImages.find(key) != mAssociatedImages.end())
{
if (mAssociatedImages[key] != NULL && mAssociatedImages[key] != incomingImage)
@@ -1966,7 +2530,7 @@ gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT)
{
ASSERT(index.hasLayer());
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
index 930300a63d..456e2660f9 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
@@ -7,12 +7,12 @@
// 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 LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_
-#define LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/Error.h"
-#include "libGLESv2/renderer/d3d/TextureStorage.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/d3d/TextureStorage.h"
#include <map>
@@ -23,7 +23,7 @@ struct ImageIndex;
namespace rx
{
-class RenderTarget;
+class RenderTargetD3D;
class RenderTarget11;
class Renderer11;
class SwapChain11;
@@ -36,13 +36,13 @@ class TextureStorage11 : public TextureStorage
static TextureStorage11 *makeTextureStorage11(TextureStorage *storage);
- static DWORD GetTextureBindFlags(GLenum internalFormat, bool renderTarget);
+ static DWORD GetTextureBindFlags(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel, bool renderTarget);
UINT getBindFlags() const;
virtual gl::Error getResource(ID3D11Resource **outResource) = 0;
virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV);
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0;
virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
@@ -50,7 +50,7 @@ class TextureStorage11 : public TextureStorage
virtual bool isRenderTarget() const;
virtual bool isManaged() const;
virtual int getLevelCount() const;
- UINT getSubresourceIndex(const gl::ImageIndex &index) const;
+ virtual UINT getSubresourceIndex(const gl::ImageIndex &index) const;
gl::Error generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha);
void invalidateSwizzleCacheLevel(int mipLevel);
@@ -68,7 +68,7 @@ class TextureStorage11 : public TextureStorage
virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) = 0;
virtual gl::Error copyToStorage(TextureStorage *destStorage);
- virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData);
protected:
@@ -77,6 +77,9 @@ class TextureStorage11 : public TextureStorage
int getLevelHeight(int mipLevel) const;
int getLevelDepth(int mipLevel) const;
+ // Some classes (e.g. TextureStorage11_2D) will override getMippedResource.
+ virtual gl::Error getMippedResource(ID3D11Resource **outResource) { return getResource(outResource); }
+
virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture) = 0;
virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) = 0;
gl::Error getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV);
@@ -118,8 +121,6 @@ class TextureStorage11 : public TextureStorage
SwizzleCacheValue mSwizzleCache[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage11);
-
const UINT mBindFlags;
struct SRVKey
@@ -142,32 +143,51 @@ class TextureStorage11_2D : public TextureStorage11
{
public:
TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain);
- TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
+ TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly = false);
virtual ~TextureStorage11_2D();
static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage);
virtual gl::Error getResource(ID3D11Resource **outResource);
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getMippedResource(ID3D11Resource **outResource);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
+
+ virtual gl::Error copyToStorage(TextureStorage *destStorage);
virtual void associateImage(Image11* image, const gl::ImageIndex &index);
virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage);
virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage);
+ virtual gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture);
+
protected:
virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
- private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D);
+ gl::Error ensureTextureExists(int mipLevels);
+ private:
virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
ID3D11ShaderResourceView **outSRV) const;
ID3D11Texture2D *mTexture;
RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+ // 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.
+ ID3D11Texture2D *mLevelZeroTexture;
+ RenderTarget11 *mLevelZeroRenderTarget;
+ bool mUseLevelZeroTexture;
+
+ // Swizzle-related variables
ID3D11Texture2D *mSwizzleTexture;
ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
@@ -177,26 +197,33 @@ class TextureStorage11_2D : public TextureStorage11
class TextureStorage11_Cube : public TextureStorage11
{
public:
- TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels);
+ TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
virtual ~TextureStorage11_Cube();
static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage);
+ virtual UINT getSubresourceIndex(const gl::ImageIndex &index) const;
+
virtual gl::Error getResource(ID3D11Resource **outResource);
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getMippedResource(ID3D11Resource **outResource);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
+
+ virtual gl::Error copyToStorage(TextureStorage *destStorage);
virtual void associateImage(Image11* image, const gl::ImageIndex &index);
virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage);
virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage);
+ virtual gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture);
+
protected:
virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture);
virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
- private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube);
+ gl::Error ensureTextureExists(int mipLevels);
+ private:
virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
ID3D11ShaderResourceView **outSRV) const;
@@ -205,6 +232,11 @@ class TextureStorage11_Cube : public TextureStorage11
ID3D11Texture2D *mTexture;
RenderTarget11 *mRenderTarget[CUBE_FACE_COUNT][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+ // Level-zero workaround members. See TextureStorage11_2D's workaround members for a description.
+ ID3D11Texture2D *mLevelZeroTexture;
+ RenderTarget11 *mLevelZeroRenderTarget[CUBE_FACE_COUNT];
+ bool mUseLevelZeroTexture;
+
ID3D11Texture2D *mSwizzleTexture;
ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
@@ -223,7 +255,7 @@ class TextureStorage11_3D : public TextureStorage11
virtual gl::Error getResource(ID3D11Resource **outResource);
// Handles both layer and non-layer RTs
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
virtual void associateImage(Image11* image, const gl::ImageIndex &index);
virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
@@ -235,8 +267,6 @@ class TextureStorage11_3D : public TextureStorage11
virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage11_3D);
-
virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
ID3D11ShaderResourceView **outSRV) const;
@@ -263,7 +293,7 @@ class TextureStorage11_2DArray : public TextureStorage11
static TextureStorage11_2DArray *makeTextureStorage11_2DArray(TextureStorage *storage);
virtual gl::Error getResource(ID3D11Resource **outResource);
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
virtual void associateImage(Image11* image, const gl::ImageIndex &index);
virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage);
@@ -275,8 +305,6 @@ class TextureStorage11_2DArray : public TextureStorage11
virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV);
private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2DArray);
-
virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture,
ID3D11ShaderResourceView **outSRV) const;
@@ -295,4 +323,4 @@ class TextureStorage11_2DArray : public TextureStorage11
}
-#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp
new file mode 100644
index 0000000000..213ce31817
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp
@@ -0,0 +1,95 @@
+//
+// Copyright (c) 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_STORE)
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::ApplicationModel;
+using namespace ABI::Windows::ApplicationModel::Core;
+#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_STORE)
+ ID3D11Device* device = mRenderer->getDevice();
+ // IDXGIDevice3 is only supported on Windows 8.1 and Windows Phone 8.1 and above.
+ IDXGIDevice3 *dxgiDevice3 = d3d11::DynamicCastComObject<IDXGIDevice3>(device);
+ if (dxgiDevice3)
+ {
+ dxgiDevice3->Trim();
+ }
+ SafeRelease(dxgiDevice3);
+#endif
+}
+
+bool Trim11::registerForRendererTrimRequest()
+{
+#if defined (ANGLE_ENABLE_WINDOWS_STORE)
+ 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_STORE)
+ 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
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h
new file mode 100644
index 0000000000..f232ad7e8e
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h
@@ -0,0 +1,43 @@
+//
+// Copyright (c) 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/angletypes.h"
+#include "libANGLE/Error.h"
+
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+typedef void* EventRegistrationToken;
+#else
+#include <EventToken.h>
+#endif
+
+namespace rx
+{
+class Renderer11;
+
+class Trim11 : angle::NonCopyable
+{
+ public:
+ explicit Trim11(Renderer11 *renderer);
+ ~Trim11();
+
+ private:
+ Renderer11 *mRenderer;
+ EventRegistrationToken mApplicationSuspendedEventToken;
+
+ void trim();
+ bool registerForRendererTrimRequest();
+ void unregisterForRendererTrimRequest();
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_TRIM11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
index 70bc3bb26f..78aad7d106 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
@@ -6,11 +6,11 @@
// VertexArray11.h: Defines the rx::VertexArray11 class which implements rx::VertexArrayImpl.
-#ifndef LIBGLESV2_RENDERER_VERTEXARRAY11_H_
-#define LIBGLESV2_RENDERER_VERTEXARRAY11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
-#include "libGLESv2/renderer/VertexArrayImpl.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/VertexArrayImpl.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
namespace rx
{
@@ -32,11 +32,9 @@ class VertexArray11 : public VertexArrayImpl
virtual void enableAttribute(size_t idx, bool enabledState) { }
private:
- DISALLOW_COPY_AND_ASSIGN(VertexArray11);
-
Renderer11 *mRenderer;
};
}
-#endif // LIBGLESV2_RENDERER_VERTEXARRAY11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
index a9d6fa2ca4..adc64cef5e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
@@ -6,12 +6,12 @@
// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation.
-#include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/VertexAttribute.h"
+#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/VertexAttribute.h"
namespace rx
{
@@ -21,10 +21,12 @@ VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
mBuffer = NULL;
mBufferSize = 0;
mDynamicUsage = false;
+ mMappedResourceData = NULL;
}
VertexBuffer11::~VertexBuffer11()
{
+ ASSERT(mMappedResourceData == NULL);
SafeRelease(mBuffer);
}
@@ -65,6 +67,37 @@ VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
return static_cast<VertexBuffer11*>(vetexBuffer);
}
+gl::Error VertexBuffer11::mapResource()
+{
+ if (mMappedResourceData == NULL)
+ {
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+
+ HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer, HRESULT: 0x%08x.", result);
+ }
+
+ mMappedResourceData = reinterpret_cast<uint8_t*>(mappedResource.pData);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+void VertexBuffer11::hintUnmapResource()
+{
+ if (mMappedResourceData != NULL)
+ {
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+ dxContext->Unmap(mBuffer, 0);
+
+ mMappedResourceData = NULL;
+ }
+}
+
gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
GLint start, GLsizei count, GLsizei instances, unsigned int offset)
{
@@ -75,24 +108,23 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri
gl::Buffer *buffer = attrib.buffer.get();
int inputStride = ComputeVertexAttributeStride(attrib);
- ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
- D3D11_MAPPED_SUBRESOURCE mappedResource;
- HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
- if (FAILED(result))
+ // This will map the resource if it isn't already mapped.
+ gl::Error error = mapResource();
+ if (error.isError())
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer, HRESULT: 0x%08x.", result);
+ return error;
}
- uint8_t *output = reinterpret_cast<uint8_t*>(mappedResource.pData) + offset;
+ uint8_t *output = mMappedResourceData + offset;
const uint8_t *input = NULL;
if (attrib.enabled)
{
if (buffer)
{
- BufferD3D *storage = BufferD3D::makeFromBuffer(buffer);
- gl::Error error = storage->getData(&input);
+ BufferD3D *storage = GetImplAs<BufferD3D>(buffer);
+ error = storage->getData(&input);
if (error.isError())
{
return error;
@@ -115,12 +147,10 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri
}
gl::VertexFormat vertexFormat(attrib, currentValue.Type);
- const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat);
+ const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mRenderer->getFeatureLevel());
ASSERT(vertexFormatInfo.copyFunction != NULL);
vertexFormatInfo.copyFunction(input, inputStride, count, output);
- dxContext->Unmap(mBuffer, 0);
-
return gl::Error(GL_NO_ERROR);
}
@@ -141,7 +171,7 @@ gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GL
}
gl::VertexFormat vertexFormat(attrib);
- const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat);
+ const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mRenderer->getFeatureLevel());
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(vertexFormatInfo.nativeFormat);
unsigned int elementSize = dxgiFormatInfo.pixelBytes;
if (elementSize <= std::numeric_limits<unsigned int>::max() / elementCount)
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
index a9bbac98fa..2450e8955c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
@@ -6,10 +6,12 @@
// VertexBuffer11.h: Defines the D3D11 VertexBuffer implementation.
-#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
-#define LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_
-#include "libGLESv2/renderer/d3d/VertexBuffer.h"
+#include <stdint.h>
+
+#include "libANGLE/renderer/d3d/VertexBuffer.h"
namespace rx
{
@@ -35,18 +37,22 @@ class VertexBuffer11 : public VertexBuffer
virtual gl::Error setBufferSize(unsigned int size);
virtual gl::Error discard();
+ virtual void hintUnmapResource();
+
ID3D11Buffer *getBuffer() const;
private:
- DISALLOW_COPY_AND_ASSIGN(VertexBuffer11);
+ gl::Error mapResource();
Renderer11 *const mRenderer;
ID3D11Buffer *mBuffer;
unsigned int mBufferSize;
bool mDynamicUsage;
+
+ uint8_t *mMappedResourceData;
};
}
-#endif // LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.h
new file mode 100644
index 0000000000..5501e361f1
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.h
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// copyvertex.h: Defines D3D11 vertex buffer copying and conversion functions
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_COPYVERTEX_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_COPYVERTEX_H_
+
+#include "common/mathutil.h"
+
+namespace rx
+{
+
+// 'alphaDefaultValueBits' gives the default value for the alpha channel (4th component)
+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);
+
+template <size_t inputComponentCount, size_t outputComponentCount>
+inline void Copy8SintTo16SintVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
+
+template <size_t componentCount>
+inline void Copy8SnormTo16SnormVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
+
+template <size_t inputComponentCount, size_t outputComponentCount>
+inline 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>
+inline void CopyTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
+
+template <bool isSigned, bool normalized, bool toFloat>
+inline void CopyXYZ10W2ToXYZW32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
+
+}
+
+#include "copyvertex.inl"
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_COPYVERTEX_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.inl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl
index 7eef17b22b..60678d7b9f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.inl
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2014-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.
//
@@ -7,40 +7,111 @@
namespace rx
{
-template <typename T, size_t componentCount, uint32_t widenDefaultValueBits>
+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)* componentCount;
- const T defaultValue = gl::bitCast<T>(widenDefaultValueBits);
- const bool widen = (widenDefaultValueBits != 0);
+ const size_t attribSize = sizeof(T)* inputComponentCount;
- if (attribSize == stride && !widen)
+ if (attribSize == stride && inputComponentCount == outputComponentCount)
{
memcpy(output, input, count * attribSize);
}
else
{
- size_t outputStride = widen ? 4 : componentCount;
+ 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 *offsetOutput = reinterpret_cast<T*>(output) + i * outputStride;
+ T *offsetOutput = reinterpret_cast<T*>(output) + i * outputComponentCount;
- for (size_t j = 0; j < componentCount; j++)
+ for (size_t j = 0; j < inputComponentCount; j++)
{
offsetOutput[j] = offsetInput[j];
}
- if (widen)
+ for (size_t j = inputComponentCount; j < lastNonAlphaOutputComponent; j++)
{
- offsetOutput[3] = defaultValue;
+ // Set the remaining G/B channels to 0.
+ offsetOutput[j] = 0;
}
+
+ 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 componentCount>
+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);
@@ -48,16 +119,25 @@ inline void Copy32FixedTo32FVertexData(const uint8_t *input, size_t stride, size
for (size_t i = 0; i < count; i++)
{
const GLfixed* offsetInput = reinterpret_cast<const GLfixed*>(input + (stride * i));
- float* offsetOutput = reinterpret_cast<float*>(output) + i * componentCount;
+ float* offsetOutput = reinterpret_cast<float*>(output) + i * outputComponentCount;
- for (size_t j = 0; j < componentCount; j++)
+ for (size_t j = 0; j < inputComponentCount; j++)
{
offsetOutput[j] = static_cast<float>(offsetInput[j]) * 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 componentCount, bool normalized>
+template <typename T, size_t inputComponentCount, size_t outputComponentCount, bool normalized>
inline void CopyTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output)
{
typedef std::numeric_limits<T> NL;
@@ -65,9 +145,9 @@ inline void CopyTo32FVertexData(const uint8_t *input, size_t stride, size_t coun
for (size_t i = 0; i < count; i++)
{
const T *offsetInput = reinterpret_cast<const T*>(input + (stride * i));
- float *offsetOutput = reinterpret_cast<float*>(output) + i * componentCount;
+ float *offsetOutput = reinterpret_cast<float*>(output) + i * outputComponentCount;
- for (size_t j = 0; j < componentCount; j++)
+ for (size_t j = 0; j < inputComponentCount; j++)
{
if (normalized)
{
@@ -86,6 +166,15 @@ inline void CopyTo32FVertexData(const uint8_t *input, size_t stride, size_t coun
offsetOutput[j] = static_cast<float>(offsetInput[j]);
}
}
+
+ // This would require special padding.
+ 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;
+ }
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp
index 90a879e170..2f81d6d608 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp
@@ -7,12 +7,14 @@
// formatutils11.cpp: Queries for GL image formats and their translations to D3D11
// formats.
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/generatemip.h"
-#include "libGLESv2/renderer/loadimage.h"
-#include "libGLESv2/renderer/copyimage.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/copyvertex.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/Renderer.h"
+#include "libANGLE/renderer/d3d/copyimage.h"
+#include "libANGLE/renderer/d3d/generatemip.h"
+#include "libANGLE/renderer/d3d/loadimage.h"
+#include "libANGLE/renderer/d3d/d3d11/copyvertex.h"
namespace rx
{
@@ -127,6 +129,90 @@ static D3D11FastCopyMap BuildFastCopyMap()
return map;
}
+struct DXGIColorFormatInfo
+{
+ size_t redBits;
+ size_t greenBits;
+ size_t blueBits;
+
+ size_t luminanceBits;
+
+ size_t alphaBits;
+ size_t sharedBits;
+};
+
+typedef std::map<DXGI_FORMAT, DXGIColorFormatInfo> ColorFormatInfoMap;
+typedef std::pair<DXGI_FORMAT, DXGIColorFormatInfo> ColorFormatInfoPair;
+
+static inline void InsertDXGIColorFormatInfo(ColorFormatInfoMap *map, DXGI_FORMAT format, size_t redBits, size_t greenBits,
+ size_t blueBits, size_t alphaBits, size_t sharedBits)
+{
+ DXGIColorFormatInfo info;
+ info.redBits = redBits;
+ info.greenBits = greenBits;
+ info.blueBits = blueBits;
+ info.alphaBits = alphaBits;
+ info.sharedBits = sharedBits;
+
+ map->insert(std::make_pair(format, info));
+}
+
+static ColorFormatInfoMap BuildColorFormatInfoMap()
+{
+ ColorFormatInfoMap map;
+
+ // | DXGI format | R | G | B | A | S |
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_A8_UNORM, 0, 0, 0, 8, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_UNORM, 8, 0, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_UNORM, 8, 8, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_UNORM, 8, 8, 8, 8, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 8, 8, 8, 8, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B8G8R8A8_UNORM, 8, 8, 8, 8, 0);
+
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_SNORM, 8, 0, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_SNORM, 8, 8, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0);
+
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_UINT, 8, 0, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_UINT, 16, 0, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_UINT, 32, 0, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_UINT, 8, 8, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_UINT, 16, 16, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32_UINT, 32, 32, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32_UINT, 32, 32, 32, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_UINT, 8, 8, 8, 8, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_UINT, 16, 16, 16, 16, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_UINT, 32, 32, 32, 32, 0);
+
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_SINT, 8, 0, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_SINT, 16, 0, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_SINT, 32, 0, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_SINT, 8, 8, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_SINT, 16, 16, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32_SINT, 32, 32, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32_SINT, 32, 32, 32, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_SINT, 8, 8, 8, 8, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_SINT, 16, 16, 16, 16, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_SINT, 32, 32, 32, 32, 0);
+
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R10G10B10A2_UNORM, 10, 10, 10, 2, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R10G10B10A2_UINT, 10, 10, 10, 2, 0);
+
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_FLOAT, 16, 0, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_FLOAT, 16, 16, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, 16, 16, 16, 16, 0);
+
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_FLOAT, 32, 0, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32_FLOAT, 32, 32, 0, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32_FLOAT, 32, 32, 32, 0, 0);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, 32, 32, 32, 32, 0);
+
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 9, 9, 9, 0, 5);
+ InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R11G11B10_FLOAT, 11, 11, 10, 0, 0);
+
+ return map;
+}
+
struct DXGIDepthStencilInfo
{
unsigned int depthBits;
@@ -179,6 +265,11 @@ DXGIFormat::DXGIFormat()
: pixelBytes(0),
blockWidth(0),
blockHeight(0),
+ redBits(0),
+ greenBits(0),
+ blueBits(0),
+ alphaBits(0),
+ sharedBits(0),
depthBits(0),
depthOffset(0),
stencilBits(0),
@@ -205,21 +296,27 @@ void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelB
info.blockWidth = blockWidth;
info.blockHeight = blockHeight;
+ static const ColorFormatInfoMap colorInfoMap = BuildColorFormatInfoMap();
+ ColorFormatInfoMap::const_iterator colorInfoIter = colorInfoMap.find(dxgiFormat);
+ if (colorInfoIter != colorInfoMap.end())
+ {
+ const DXGIColorFormatInfo &colorInfo = colorInfoIter->second;
+ info.redBits = colorInfo.redBits;
+ info.greenBits = colorInfo.greenBits;
+ info.blueBits = colorInfo.blueBits;
+ info.alphaBits = colorInfo.alphaBits;
+ info.sharedBits = colorInfo.sharedBits;
+ }
+
static const DepthStencilInfoMap dsInfoMap = BuildDepthStencilInfoMap();
DepthStencilInfoMap::const_iterator dsInfoIter = dsInfoMap.find(dxgiFormat);
if (dsInfoIter != dsInfoMap.end())
{
- info.depthBits = dsInfoIter->second.depthBits;
- info.depthOffset = dsInfoIter->second.depthOffset;
- info.stencilBits = dsInfoIter->second.stencilBits;
- info.stencilOffset = dsInfoIter->second.stencilOffset;
- }
- else
- {
- info.depthBits = 0;
- info.depthOffset = 0;
- info.stencilBits = 0;
- info.stencilOffset = 0;
+ const DXGIDepthStencilInfo &dsInfo = dsInfoIter->second;
+ info.depthBits = dsInfo.depthBits;
+ info.depthOffset = dsInfo.depthOffset;
+ info.stencilBits = dsInfo.stencilBits;
+ info.stencilOffset = dsInfo.stencilOffset;
}
static const DXGIToESFormatMap dxgiToESMap = BuildDXGIToESFormatMap();
@@ -452,7 +549,28 @@ static inline void InsertLoadFunction(D3D11LoadFunctionMap *map, GLenum internal
(*map)[internalFormat].push_back(TypeLoadFunctionPair(type, loadFunc));
}
-D3D11LoadFunctionMap BuildD3D11LoadFunctionMap()
+D3D11LoadFunctionMap BuildD3D11_FL9_3_LoadFunctionMap()
+{
+ D3D11LoadFunctionMap map;
+
+ // From GL_EXT_texture_storage. Also used by GL_ALPHA8
+ // On feature level 9_3, A8_UNORM doesn't support mipmaps, so we must use RGBA8 instead
+ InsertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadA8ToRGBA8);
+
+ return map;
+}
+
+D3D11LoadFunctionMap BuildD3D11_FL10_0Plus_LoadFunctionMap()
+{
+ D3D11LoadFunctionMap map;
+
+ // From GL_EXT_texture_storage. Also used by GL_ALPHA8
+ InsertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 1>);
+
+ return map;
+}
+
+D3D11LoadFunctionMap BuildBaseD3D11LoadFunctionMap()
{
D3D11LoadFunctionMap map;
@@ -557,7 +675,7 @@ D3D11LoadFunctionMap BuildD3D11LoadFunctionMap()
InsertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT_OES, LoadA16FToRGBA16F );
// From GL_EXT_texture_storage
- InsertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadA8ToRGBA8 );
+ // GL_ALPHA8_EXT GL_UNSIGNED_BYTE is in the feature-level-specific load function maps, due to differences between 9_3 and 10_0+
InsertLoadFunction(&map, GL_LUMINANCE8_EXT, GL_UNSIGNED_BYTE, LoadL8ToRGBA8 );
InsertLoadFunction(&map, GL_LUMINANCE8_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadLA8ToRGBA8 );
InsertLoadFunction(&map, GL_ALPHA32F_EXT, GL_FLOAT, LoadA32FToRGBA32F );
@@ -627,8 +745,8 @@ TextureFormat::TextureFormat()
{
}
-static inline void InsertD3D11FormatInfo(D3D11ES3FormatMap *map, GLenum internalFormat, DXGI_FORMAT texFormat,
- DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat)
+static inline void InsertD3D11FormatInfoBase(D3D11ES3FormatMap *formatMap, const D3D11LoadFunctionMap &flLoadFunctions, GLenum internalFormat, DXGI_FORMAT texFormat,
+ DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat)
{
TextureFormat info;
info.texFormat = texFormat;
@@ -712,8 +830,8 @@ static inline void InsertD3D11FormatInfo(D3D11ES3FormatMap *map, GLenum internal
InternalFormatInitializerMap::const_iterator initializerIter = initializerMap.find(internalFormat);
info.dataInitializerFunction = (initializerIter != initializerMap.end()) ? initializerIter->second : NULL;
- // Gather all the load functions for this internal format
- static const D3D11LoadFunctionMap loadFunctions = BuildD3D11LoadFunctionMap();
+ // Gather all the load functions for this internal format from the base list
+ static const D3D11LoadFunctionMap loadFunctions = BuildBaseD3D11LoadFunctionMap();
D3D11LoadFunctionMap::const_iterator loadFunctionIter = loadFunctions.find(internalFormat);
if (loadFunctionIter != loadFunctions.end())
{
@@ -726,7 +844,57 @@ static inline void InsertD3D11FormatInfo(D3D11ES3FormatMap *map, GLenum internal
}
}
- map->insert(std::make_pair(internalFormat, info));
+ // Gather load functions for this internal format from the feature-level-specific list
+ D3D11LoadFunctionMap::const_iterator flLoadFunctionIter = flLoadFunctions.find(internalFormat);
+ if (flLoadFunctionIter != flLoadFunctions.end())
+ {
+ const std::vector<TypeLoadFunctionPair> &flLoadFunctionVector = flLoadFunctionIter->second;
+ for (size_t i = 0; i < flLoadFunctionVector.size(); i++)
+ {
+ GLenum type = flLoadFunctionVector[i].first;
+ LoadImageFunction function = flLoadFunctionVector[i].second;
+ info.loadFunctions.insert(std::make_pair(type, function));
+ }
+ }
+
+ formatMap->insert(std::make_pair(internalFormat, info));
+}
+
+static inline void InsertD3D11_FL9_3_FormatInfo(D3D11ES3FormatMap *map, GLenum internalFormat, DXGI_FORMAT texFormat,
+ DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat)
+{
+ static const D3D11LoadFunctionMap flLoadFunctions = BuildD3D11_FL9_3_LoadFunctionMap();
+ InsertD3D11FormatInfoBase(map, flLoadFunctions, internalFormat, texFormat, srvFormat, rtvFormat, dsvFormat);
+}
+
+static inline void InsertD3D11FormatInfo(D3D11ES3FormatMap *map, GLenum internalFormat, DXGI_FORMAT texFormat,
+ DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat)
+{
+ static const D3D11LoadFunctionMap flLoadFunctions = BuildD3D11_FL10_0Plus_LoadFunctionMap();
+ InsertD3D11FormatInfoBase(map, flLoadFunctions, internalFormat, texFormat, srvFormat, rtvFormat, dsvFormat);
+}
+
+static D3D11ES3FormatMap BuildD3D11_FL9_3FormatOverrideMap()
+{
+ // D3D11 Feature Level 9_3 doesn't support as many texture formats as Feature Level 10_0+.
+ // In particular, it doesn't support:
+ // - mipmaps on DXGI_FORMAT_A8_NORM
+ // - *_TYPELESS formats
+ // - DXGI_FORMAT_D32_FLOAT_S8X24_UINT or DXGI_FORMAT_D32_FLOAT
+
+ D3D11ES3FormatMap map;
+
+ // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format
+ InsertD3D11_FL9_3_FormatInfo(&map, GL_ALPHA, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
+ InsertD3D11_FL9_3_FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN);
+ InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH_COMPONENT16, DXGI_FORMAT_D16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM);
+ InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH_COMPONENT24, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT);
+ InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH_COMPONENT32F, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+ InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH24_STENCIL8, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT);
+ InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH32F_STENCIL8, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN);
+ InsertD3D11_FL9_3_FormatInfo(&map, GL_STENCIL_INDEX8, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT);
+
+ return map;
}
static D3D11ES3FormatMap BuildD3D11FormatMap()
@@ -795,7 +963,7 @@ static D3D11ES3FormatMap BuildD3D11FormatMap()
// From GL_EXT_texture_storage
// | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format |
- InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
+ InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_LUMINANCE8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
InsertD3D11FormatInfo(&map, GL_LUMINANCE32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
@@ -846,9 +1014,21 @@ static D3D11ES3FormatMap BuildD3D11FormatMap()
return map;
}
-const TextureFormat &GetTextureFormatInfo(GLenum internalFormat)
+const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel)
{
static const D3D11ES3FormatMap formatMap = BuildD3D11FormatMap();
+ static const D3D11ES3FormatMap formatMapFL9_3Override = BuildD3D11_FL9_3FormatOverrideMap();
+
+ if (featureLevel == D3D_FEATURE_LEVEL_9_3)
+ {
+ // First see if the internalFormat has a special map for FL9_3
+ D3D11ES3FormatMap::const_iterator fl9_3Iter = formatMapFL9_3Override.find(internalFormat);
+ if (fl9_3Iter != formatMapFL9_3Override.end())
+ {
+ return fl9_3Iter->second;
+ }
+ }
+
D3D11ES3FormatMap::const_iterator iter = formatMap.find(internalFormat);
if (iter != formatMap.end())
{
@@ -897,6 +1077,68 @@ static void AddIntegerVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inp
map->insert(D3D11VertexFormatPair(inputFormat, info));
}
+static D3D11VertexFormatInfoMap BuildD3D11_FL9_3VertexFormatInfoOverrideMap()
+{
+ // 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
+
+ D3D11VertexFormatInfoMap map;
+
+ // GL_BYTE -- unnormalized
+ AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 1, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, &Copy8SintTo16SintVertexData<1, 2>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 2, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, &Copy8SintTo16SintVertexData<2, 2>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &Copy8SintTo16SintVertexData<3, 4>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 4, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &Copy8SintTo16SintVertexData<4, 4>);
+
+ // GL_BYTE -- normalized
+ AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, &Copy8SnormTo16SnormVertexData<1, 2>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, &Copy8SnormTo16SnormVertexData<2, 2>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &Copy8SnormTo16SnormVertexData<3, 4>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &Copy8SnormTo16SnormVertexData<4, 4>);
+
+ // GL_UNSIGNED_BYTE -- unnormalized
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 1, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 1, 4, 1>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 2, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 2, 4, 1>);
+ // NOTE: 3 and 4 component unnormalized GL_UNSIGNED_BYTE should use the default format table.
+
+ // GL_UNSIGNED_BYTE -- normalized
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 1, 4, UINT8_MAX>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 2, 4, UINT8_MAX>);
+ // NOTE: 3 and 4 component normalized GL_UNSIGNED_BYTE should use the default format table.
+
+ // GL_SHORT -- unnormalized
+ AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 1, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 1, 2, 0>);
+ // NOTE: 2, 3 and 4 component unnormalized GL_SHORT should use the default format table.
+
+ // GL_SHORT -- normalized
+ AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, &CopyNativeVertexData<GLshort, 1, 2, 0>);
+ // NOTE: 2, 3 and 4 component normalized GL_SHORT should use the default format table.
+
+ // GL_UNSIGNED_SHORT -- unnormalized
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLushort, 1, 2, false>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLushort, 2, 2, false>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLushort, 3, 3, false>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLushort, 4, 4, false>);
+
+ // GL_UNSIGNED_SHORT -- normalized
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLushort, 1, 2, true>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLushort, 2, 2, true>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLushort, 3, 3, true>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLushort, 4, 4, true>);
+
+ // GL_FIXED
+ // TODO: Add test to verify that this works correctly.
+ AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &Copy32FixedTo32FVertexData<1, 2>);
+ // NOTE: 2, 3 and 4 component GL_FIXED should use the default format table.
+
+ // GL_FLOAT
+ // TODO: Add test to verify that this works correctly.
+ AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyNativeVertexData<GLfloat, 1, 2, 0>);
+ // NOTE: 2, 3 and 4 component GL_FLOAT should use the default format table.
+
+ return map;
+}
+
static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap()
{
D3D11VertexFormatInfoMap map;
@@ -908,94 +1150,94 @@ static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap()
//
// GL_BYTE -- un-normalized
- AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 0>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 0>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 1>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 4, 0>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 4, 1>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 4, 4, 0>);
// GL_BYTE -- normalized
- AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, &CopyNativeVertexData<GLbyte, 1, 0>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, &CopyNativeVertexData<GLbyte, 2, 0>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<GLbyte, 3, INT8_MAX>);
- AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<GLbyte, 4, 0>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, &CopyNativeVertexData<GLbyte, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, &CopyNativeVertexData<GLbyte, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<GLbyte, 3, 4, INT8_MAX>);
+ AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData<GLbyte, 4, 4, 0>);
// GL_UNSIGNED_BYTE -- un-normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 1>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 4, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 4, 1>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 4, 4, 0>);
// GL_UNSIGNED_BYTE -- normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, &CopyNativeVertexData<GLubyte, 1, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, &CopyNativeVertexData<GLubyte, 2, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 3, UINT8_MAX>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 4, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, &CopyNativeVertexData<GLubyte, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, &CopyNativeVertexData<GLubyte, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 3, 4, UINT8_MAX>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData<GLubyte, 4, 4, 0>);
// GL_SHORT -- un-normalized
- AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 0>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 0>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 1>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 0>);
+ AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 3, 4, 1>);
+ AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 4, 0>);
// GL_SHORT -- normalized
- AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, &CopyNativeVertexData<GLshort, 1, 0>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, &CopyNativeVertexData<GLshort, 2, 0>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 3, INT16_MAX>);
- AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 4, 0>);
+ AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, &CopyNativeVertexData<GLshort, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, &CopyNativeVertexData<GLshort, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 3, 4, INT16_MAX>);
+ AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData<GLshort, 4, 4, 0>);
// GL_UNSIGNED_SHORT -- un-normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 1>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 4, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 4, 1>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 4, 4, 0>);
// GL_UNSIGNED_SHORT -- normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, &CopyNativeVertexData<GLushort, 1, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, &CopyNativeVertexData<GLushort, 2, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 3, UINT16_MAX>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 4, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, &CopyNativeVertexData<GLushort, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, &CopyNativeVertexData<GLushort, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 3, 4, UINT16_MAX>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData<GLushort, 4, 4, 0>);
// GL_INT -- un-normalized
- AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 0>);
- AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 0>);
- AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 0>);
- AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLint, 4, 0>);
+ AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 3, 0>);
+ AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLint, 4, 4, 0>);
// GL_INT -- normalized
- AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLint, 1, true>);
- AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLint, 2, true>);
- AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLint, 3, true>);
- AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLint, 4, true>);
+ AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLint, 1, 1, true>);
+ AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLint, 2, 2, true>);
+ AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLint, 3, 3, true>);
+ AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLint, 4, 4, true>);
// GL_UNSIGNED_INT -- un-normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, &CopyNativeVertexData<GLuint, 1, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, &CopyNativeVertexData<GLuint, 2, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, &CopyNativeVertexData<GLuint, 3, 0>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, &CopyNativeVertexData<GLuint, 4, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, &CopyNativeVertexData<GLuint, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, &CopyNativeVertexData<GLuint, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, &CopyNativeVertexData<GLuint, 3, 3, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, &CopyNativeVertexData<GLuint, 4, 4, 0>);
// GL_UNSIGNED_INT -- normalized
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLuint, 1, true>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLuint, 2, true>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLuint, 3, true>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLuint, 4, true>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData<GLuint, 1, 1, true>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData<GLuint, 2, 2, true>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData<GLuint, 3, 3, true>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData<GLuint, 4, 4, true>);
// GL_FIXED
- AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &Copy32FixedTo32FVertexData<1>);
- AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &Copy32FixedTo32FVertexData<2>);
- AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &Copy32FixedTo32FVertexData<3>);
- AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &Copy32FixedTo32FVertexData<4>);
+ AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &Copy32FixedTo32FVertexData<1, 1>);
+ AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &Copy32FixedTo32FVertexData<2, 2>);
+ AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &Copy32FixedTo32FVertexData<3, 3>);
+ AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &Copy32FixedTo32FVertexData<4, 4>);
// GL_HALF_FLOAT
- AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, &CopyNativeVertexData<GLhalf, 1, 0>);
- AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, &CopyNativeVertexData<GLhalf, 2, 0>);
- AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 3, gl::Float16One>);
- AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 4, 0>);
+ AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, &CopyNativeVertexData<GLhalf, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, &CopyNativeVertexData<GLhalf, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 3, 4, gl::Float16One>);
+ AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData<GLhalf, 4, 4, 0>);
// GL_FLOAT
- AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyNativeVertexData<GLfloat, 1, 0>);
- AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyNativeVertexData<GLfloat, 2, 0>);
- AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, &CopyNativeVertexData<GLfloat, 3, 0>);
- AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyNativeVertexData<GLfloat, 4, 0>);
+ AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyNativeVertexData<GLfloat, 1, 1, 0>);
+ AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyNativeVertexData<GLfloat, 2, 2, 0>);
+ AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, &CopyNativeVertexData<GLfloat, 3, 3, 0>);
+ AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyNativeVertexData<GLfloat, 4, 4, 0>);
// GL_INT_2_10_10_10_REV
AddVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<true, false, true>);
@@ -1003,60 +1245,71 @@ static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap()
// GL_UNSIGNED_INT_2_10_10_10_REV
AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData<false, false, true>);
- AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, &CopyNativeVertexData<GLuint, 1, 0>);
+ AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, &CopyNativeVertexData<GLuint, 1, 1, 0>);
//
// Integer Formats
//
// GL_BYTE
- AddIntegerVertexFormatInfo(&map, GL_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 1>);
- AddIntegerVertexFormatInfo(&map, GL_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 4, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData<GLbyte, 1, 1, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData<GLbyte, 2, 2, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 3, 4, 1>);
+ AddIntegerVertexFormatInfo(&map, GL_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData<GLbyte, 4, 4, 0>);
// GL_UNSIGNED_BYTE
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 1>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 4, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData<GLubyte, 1, 1, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData<GLubyte, 2, 2, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 3, 4, 1>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData<GLubyte, 4, 4, 0>);
// GL_SHORT
- AddIntegerVertexFormatInfo(&map, GL_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 3, 1>);
- AddIntegerVertexFormatInfo(&map, GL_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData<GLshort, 1, 1, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData<GLshort, 2, 2, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 3, 4, 1>);
+ AddIntegerVertexFormatInfo(&map, GL_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData<GLshort, 4, 4, 0>);
// GL_UNSIGNED_SHORT
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 1>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 4, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData<GLushort, 1, 1, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData<GLushort, 2, 2, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 3, 4, 1>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData<GLushort, 4, 4, 0>);
// GL_INT
- AddIntegerVertexFormatInfo(&map, GL_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 0>);
- AddIntegerVertexFormatInfo(&map, GL_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLint, 4, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLint, 1, 1, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLint, 2, 2, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLint, 3, 3, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLint, 4, 4, 0>);
// GL_UNSIGNED_INT
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLuint, 1, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLuint, 2, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLuint, 3, 0>);
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLuint, 4, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData<GLuint, 1, 1, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData<GLuint, 2, 2, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData<GLuint, 3, 3, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData<GLuint, 4, 4, 0>);
// GL_INT_2_10_10_10_REV
AddIntegerVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyXYZ10W2ToXYZW32FVertexData<true, true, false>);
// GL_UNSIGNED_INT_2_10_10_10_REV
- AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, &CopyNativeVertexData<GLuint, 1, 0>);
+ AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, &CopyNativeVertexData<GLuint, 1, 1, 0>);
return map;
}
-const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat)
+const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat, D3D_FEATURE_LEVEL featureLevel)
{
static const D3D11VertexFormatInfoMap vertexFormatMap = BuildD3D11VertexFormatInfoMap();
+ static const D3D11VertexFormatInfoMap vertexFormatMapFL9_3Override = BuildD3D11_FL9_3VertexFormatInfoOverrideMap();
+
+ if (featureLevel == D3D_FEATURE_LEVEL_9_3)
+ {
+ // First see if the format has a special mapping for FL9_3
+ D3D11VertexFormatInfoMap::const_iterator iter = vertexFormatMapFL9_3Override.find(vertexFormat);
+ if (iter != vertexFormatMapFL9_3Override.end())
+ {
+ return iter->second;
+ }
+ }
D3D11VertexFormatInfoMap::const_iterator iter = vertexFormatMap.find(vertexFormat);
if (iter != vertexFormatMap.end())
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h
index ea11aaa74c..33fe29dc39 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h
@@ -7,10 +7,13 @@
// formatutils11.h: Queries for GL image formats and their translations to D3D11
// formats.
-#ifndef LIBGLESV2_RENDERER_FORMATUTILS11_H_
-#define LIBGLESV2_RENDERER_FORMATUTILS11_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_
-#include "libGLESv2/formatutils.h"
+#include "libANGLE/renderer/d3d/formatutilsD3D.h"
+#include "libANGLE/angletypes.h"
+
+#include "common/platform.h"
#include <map>
@@ -30,6 +33,12 @@ struct DXGIFormat
GLuint blockWidth;
GLuint blockHeight;
+ GLuint redBits;
+ GLuint greenBits;
+ GLuint blueBits;
+ GLuint alphaBits;
+ GLuint sharedBits;
+
GLuint depthBits;
GLuint depthOffset;
GLuint stencilBits;
@@ -65,7 +74,7 @@ struct TextureFormat
typedef std::map<GLenum, LoadImageFunction> LoadFunctionMap;
LoadFunctionMap loadFunctions;
};
-const TextureFormat &GetTextureFormatInfo(GLenum internalFormat);
+const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel);
struct VertexFormat
{
@@ -75,10 +84,10 @@ struct VertexFormat
DXGI_FORMAT nativeFormat;
VertexCopyFunction copyFunction;
};
-const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat);
+const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat, D3D_FEATURE_LEVEL featureLevel);
}
}
-#endif // LIBGLESV2_RENDERER_FORMATUTILS11_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
index 121aa3bbad..63085f497f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -7,12 +7,14 @@
// renderer11_utils.cpp: Conversion functions and other utility routines
// specific to the D3D11 renderer.
-#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
-#include "libGLESv2/renderer/Workarounds.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/Framebuffer.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/Workarounds.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Framebuffer.h"
#include "common/debug.h"
@@ -96,6 +98,9 @@
#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT
# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32
#endif
+#if defined(ANGLE_MINGW32_COMPAT)
+static const IID WKPDID_D3DDebugObjectName = { 0x429b8c22, 0x9188, 0x4b0c, 0x87, 0x42, 0xac, 0xb0, 0xbf, 0x85, 0xc2, 0x00 };
+#endif
namespace rx
{
@@ -305,25 +310,47 @@ D3D11_QUERY ConvertQueryType(GLenum queryType)
namespace d3d11_gl
{
-static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, ID3D11Device *device)
+GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
+#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return 3;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1: return 2;
+
+ default: UNREACHABLE(); return 0;
+ }
+}
+
+static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum internalFormat, ID3D11Device *device)
{
gl::TextureCaps textureCaps;
- const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
+ const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, device->GetFeatureLevel());
UINT formatSupport;
if (SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &formatSupport)))
{
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
- if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
+ if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0)
{
textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0);
}
else
{
- textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0) &&
- ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE) != 0) &&
- ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE3D) != 0);
+ UINT formatSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE;
+ if (maxClientVersion > 2)
+ {
+ formatSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
+ }
+ textureCaps.texturable = ((formatSupport & formatSupportMask) == formatSupportMask);
}
}
@@ -355,7 +382,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -365,7 +392,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
// 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 true; // Provided that mipmaps & wrap modes are not used
+ case D3D_FEATURE_LEVEL_9_1: return false;
default: UNREACHABLE(); return false;
}
@@ -375,7 +402,7 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY;
@@ -397,7 +424,7 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -419,7 +446,7 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -439,12 +466,18 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
- case D3D_FEATURE_LEVEL_10_0:
+ 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:
@@ -454,6 +487,44 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
}
}
+static bool GetFramebufferMultisampleSupport(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
+#endif
+ 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;
+ }
+}
+
+static bool GetFramebufferBlitSupport(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
+#endif
+ 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;
+ }
+}
+
static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
{
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588.aspx states that shader model
@@ -464,7 +535,7 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -478,13 +549,32 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
}
}
+static bool GetShaderTextureLODSupport(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
+#endif
+ 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;
+ }
+}
+
static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel)
{
// From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateInputLayout
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
@@ -504,7 +594,7 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
@@ -524,7 +614,7 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION;
@@ -544,7 +634,7 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
@@ -564,7 +654,7 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
@@ -584,7 +674,7 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX;
@@ -592,7 +682,7 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_VIEWPORT_BOUNDS_MAX;
- // No constants for D3D9 viewport size limits, use the maximum texture sizes
+ // 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;
@@ -605,12 +695,12 @@ static size_t 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
- META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
- META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
+ 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)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -629,12 +719,12 @@ static size_t 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
- META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
- META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
+ 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)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -653,7 +743,7 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT;
@@ -675,7 +765,7 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
@@ -702,7 +792,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
@@ -710,7 +800,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
- // Uniform blocks not supported in D3D9 feature levels
+ // 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;
@@ -719,30 +809,55 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
}
}
-static size_t GetReservedVertexOutputVectors()
+static size_t GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
{
- // We potentially reserve varyings for gl_Position, dx_Position, gl_FragCoord and gl_PointSize
- return 4;
+ // 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.
+#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
+#endif
+ 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;
+ }
+
+ return 1;
}
static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
{
- META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
+ static_assert(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT, "Unexpected D3D11 constant value.");
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
+ 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();
- case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
+ 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 D3D9 SM3 and SM2 limits
- case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors();
+ // 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();
+ case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(featureLevel);
default: UNREACHABLE(); return 0;
}
@@ -752,7 +867,7 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
@@ -760,7 +875,7 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
- // Vertex textures not supported in D3D9 feature levels according to
+ // 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:
@@ -776,7 +891,7 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
// TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
@@ -803,7 +918,7 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
@@ -811,7 +926,7 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
- // Uniform blocks not supported in D3D9 feature levels
+ // 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;
@@ -824,18 +939,18 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
+ 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();
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
- // Use D3D9 SM3 and SM2 limits
- case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors();
+ // 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();
+ case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(featureLevel);
default: UNREACHABLE(); return 0;
}
@@ -845,7 +960,7 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
@@ -866,7 +981,7 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
@@ -887,7 +1002,7 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
@@ -912,7 +1027,7 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
@@ -933,7 +1048,7 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT;
@@ -953,7 +1068,7 @@ static size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL feat
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0:
@@ -973,7 +1088,7 @@ static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL feature
{
switch (featureLevel)
{
-#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+#if defined(ANGLE_ENABLE_D3D11_1)
case D3D_FEATURE_LEVEL_11_1:
#endif
case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponents(featureLevel) /
@@ -992,13 +1107,15 @@ static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL feature
}
}
-void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions)
+void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions)
{
+ D3D_FEATURE_LEVEL featureLevel = device->GetFeatureLevel();
+
GLuint maxSamples = 0;
const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat)
{
- gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, device);
+ gl::TextureCaps textureCaps = GenerateTextureFormatCaps(GetMaximumClientVersion(featureLevel), *internalFormat, device);
textureCapsMap->insert(*internalFormat, textureCaps);
maxSamples = std::max(maxSamples, textureCaps.getMaxSamples());
@@ -1009,8 +1126,6 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text
}
}
- D3D_FEATURE_LEVEL featureLevel = device->GetFeatureLevel();
-
// GL core feature limits
caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel);
@@ -1048,6 +1163,21 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text
// 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;
@@ -1074,6 +1204,24 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text
// Setting a large alignment forces uniform buffers to bind with zero offset
caps->uniformBufferOffsetAlignment = static_cast<GLuint>(std::numeric_limits<GLint>::max());
+#if defined(ANGLE_ENABLE_D3D11_1)
+ ID3D11DeviceContext1 *deviceContext1 = d3d11::DynamicCastComObject<ID3D11DeviceContext1>(deviceContext);
+
+ if (deviceContext1)
+ {
+ D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options;
+ device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
+
+ if (d3d11Options.ConstantBufferOffsetting)
+ {
+ // 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
+ caps->uniformBufferOffsetAlignment = 256;
+ }
+
+ SafeRelease(deviceContext1);
+ }
+#endif
caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks;
caps->maxCombinedVertexUniformComponents = (static_cast<GLint64>(caps->maxVertexUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) +
@@ -1109,13 +1257,13 @@ void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *text
extensions->timerQuery = false; // Unimplemented
extensions->robustness = true;
extensions->blendMinMax = true;
- extensions->framebufferBlit = true;
- extensions->framebufferMultisample = true;
+ extensions->framebufferBlit = GetFramebufferBlitSupport(featureLevel);
+ extensions->framebufferMultisample = GetFramebufferMultisampleSupport(featureLevel);
extensions->maxSamples = maxSamples;
extensions->instancedArrays = GetInstancingSupport(featureLevel);
extensions->packReverseRowOrder = true;
extensions->standardDerivatives = GetDerivativeInstructionSupport(featureLevel);
- extensions->shaderTextureLOD = true;
+ extensions->shaderTextureLOD = GetShaderTextureLODSupport(featureLevel);
extensions->fragDepth = true;
extensions->textureUsage = true; // This could be false since it has no effect in D3D11
extensions->translatedShaderSource = true;
@@ -1145,11 +1293,11 @@ void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsi
*levelOffset = upsampleCount;
}
-void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint height, GLuint depth,
+void GenerateInitialTextureData(GLint internalFormat, D3D_FEATURE_LEVEL featureLevel, GLuint width, GLuint height, GLuint depth,
GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
std::vector< std::vector<BYTE> > *outData)
{
- const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat);
+ const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat, featureLevel);
ASSERT(d3dFormatInfo.dataInitializerFunction != NULL);
const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3dFormatInfo.texFormat);
@@ -1196,16 +1344,16 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo
HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
{
-#if defined(_DEBUG) && !defined(__MINGW32__)
+#if defined(_DEBUG)
return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
#else
return S_OK;
#endif
}
-gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT)
+gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget11 **outRT)
{
- RenderTarget *renderTarget = NULL;
+ RenderTargetD3D *renderTarget = NULL;
gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
if (error.isError())
{
@@ -1215,11 +1363,13 @@ gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, Rende
return gl::Error(GL_NO_ERROR);
}
-Workarounds GenerateWorkarounds()
+Workarounds GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel)
{
Workarounds workarounds;
workarounds.mrtPerfWorkaround = true;
workarounds.setDataFasterThanImageUpload = true;
+ workarounds.zeroMaxLodWorkaround = (featureLevel <= D3D_FEATURE_LEVEL_9_3);
+ workarounds.useInstancedPointSpriteEmulation = (featureLevel <= D3D_FEATURE_LEVEL_9_3);
return workarounds;
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
index 9df9c95763..207e6b5404 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
@@ -7,12 +7,12 @@
// renderer11_utils.h: Conversion functions and other utility routines
// specific to the D3D11 renderer.
-#ifndef LIBGLESV2_RENDERER_RENDERER11_UTILS_H
-#define LIBGLESV2_RENDERER_RENDERER11_UTILS_H
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/Caps.h"
-#include "libGLESv2/Error.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Error.h"
#include <vector>
@@ -50,7 +50,8 @@ D3D11_QUERY ConvertQueryType(GLenum queryType);
namespace d3d11_gl
{
-void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions);
+GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel);
+void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions);
}
@@ -59,7 +60,7 @@ namespace d3d11
void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
-void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint height, GLuint depth,
+void GenerateInitialTextureData(GLint internalFormat, D3D_FEATURE_LEVEL featureLevel, GLuint width, GLuint height, GLuint depth,
GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
std::vector< std::vector<BYTE> > *outData);
@@ -178,12 +179,12 @@ inline void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBu
context->Unmap(constantBuffer, 0);
}
-gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget11 **outRT);
+gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget11 **outRT);
-Workarounds GenerateWorkarounds();
+Workarounds GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel);
}
}
-#endif // LIBGLESV2_RENDERER_RENDERER11_UTILS_H
+#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/BufferToTexture11.hlsl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/BufferToTexture11.hlsl
index 20e6623a30..c43734f6a3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/BufferToTexture11.hlsl
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/BufferToTexture11.hlsl
@@ -26,6 +26,7 @@ cbuffer BufferCopyParams : register(b0)
float2 PositionScale;
int2 TexLocationOffset;
int2 TexLocationScale;
+ uint FirstSlice;
}
void ComputePositionAndIndex(uint vertexID, out VS_OUTPUT outVertex)
@@ -42,7 +43,7 @@ void ComputePositionAndIndex(uint vertexID, out VS_OUTPUT outVertex)
outVertex.position = float4(PositionOffset + PositionScale * coords, 0.0f, 1.0f);
outVertex.index = FirstPixelOffset + slice * SliceStride + row * RowStride + col;
- outVertex.slice = slice;
+ outVertex.slice = FirstSlice + slice;
}
void VS_BufferToTexture(in uint vertexID : SV_VertexID, out VS_OUTPUT outVertex)
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Clear11.hlsl
index b4cf38076e..2b3e1ebe4c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Clear11.hlsl
@@ -13,12 +13,10 @@ struct PS_OutputFloat
float4 color1 : SV_TARGET1;
float4 color2 : SV_TARGET2;
float4 color3 : SV_TARGET3;
-#if SM4
float4 color4 : SV_TARGET4;
float4 color5 : SV_TARGET5;
float4 color6 : SV_TARGET6;
float4 color7 : SV_TARGET7;
-#endif
};
PS_OutputFloat PS_ClearFloat(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR)
@@ -28,15 +26,30 @@ PS_OutputFloat PS_ClearFloat(in float4 inPosition : SV_POSITION, in float4 inCol
outColor.color1 = inColor;
outColor.color2 = inColor;
outColor.color3 = inColor;
-#if SM4
outColor.color4 = inColor;
outColor.color5 = inColor;
outColor.color6 = inColor;
outColor.color7 = inColor;
-#endif
return outColor;
}
+struct PS_OutputFloat_FL9
+{
+ float4 color0 : SV_TARGET0;
+ float4 color1 : SV_TARGET1;
+ float4 color2 : SV_TARGET2;
+ float4 color3 : SV_TARGET3;
+};
+
+PS_OutputFloat_FL9 PS_ClearFloat_FL9(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR)
+{
+ PS_OutputFloat_FL9 outColor;
+ outColor.color0 = inColor;
+ outColor.color1 = inColor;
+ outColor.color2 = inColor;
+ outColor.color3 = inColor;
+ return outColor;
+}
void VS_ClearUint( in float3 inPosition : POSITION, in uint4 inColor : COLOR,
out float4 outPosition : SV_POSITION, out uint4 outColor : COLOR)
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl
index 8671c39fb7..8671c39fb7 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Passthrough3D11.hlsl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough3D11.hlsl
index c23c9032ec..c23c9032ec 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Passthrough3D11.hlsl
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough3D11.hlsl
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Swizzle11.hlsl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Swizzle11.hlsl
index 505e222137..505e222137 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Swizzle11.hlsl
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Swizzle11.hlsl
diff --git a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp
index 46082a2e28..9d8f0bb96c 100644
--- a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp
@@ -6,17 +6,14 @@
// NativeWindow.cpp: Handler for managing HWND native window types.
-#include "common/NativeWindow.h"
+#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h"
+
#include "common/debug.h"
namespace rx
{
-bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
-{
- return (IsWindow(window) == TRUE);
-}
-NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display) : mWindow(window), mDisplay(display)
+NativeWindow::NativeWindow(EGLNativeWindowType window) : mWindow(window)
{
}
@@ -35,7 +32,12 @@ bool NativeWindow::isIconic()
return IsIconic(mWindow) == TRUE;
}
-HRESULT NativeWindow::createSwapChain(NativeWindow::Device* device, DXGIFactory* factory,
+bool NativeWindow::isValidNativeWindow(EGLNativeWindowType window)
+{
+ return IsWindow(window) == TRUE;
+}
+
+HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory,
DXGI_FORMAT format, unsigned int width, unsigned int height,
DXGISwapChain** swapChain)
{
diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
index 9b65c15625..350526c867 100644
--- a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
@@ -6,25 +6,22 @@
// CoreWindowNativeWindow.cpp: NativeWindow for managing ICoreWindow native window types.
-#include <algorithm>
-#include "common/winrt/CoreWindowNativeWindow.h"
+#include "libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h"
+
using namespace ABI::Windows::Foundation::Collections;
namespace rx
{
-
-typedef ITypedEventHandler<ABI::Windows::UI::Core::CoreWindow *, ABI::Windows::UI::Core::WindowSizeChangedEventArgs *> SizeChangedHandler;
-
CoreWindowNativeWindow::~CoreWindowNativeWindow()
{
unregisterForSizeChangeEvents();
}
-bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
+bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet)
{
+ mOrientationChangedEventToken.value = 0;
ComPtr<IPropertySet> props = propertySet;
ComPtr<IInspectable> win = window;
- ComPtr<IInspectable> displayInformation = display;
SIZE swapChainSize = {};
bool swapChainSizeSpecified = false;
HRESULT result = S_OK;
@@ -51,29 +48,6 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDis
if (SUCCEEDED(result))
{
- result = displayInformation.As(&mDisplayInformation);
- }
-
- if (SUCCEEDED(result))
- {
-#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation2> displayInformation2;
- result = mDisplayInformation.As(&displayInformation2);
- ASSERT(SUCCEEDED(result));
-
- result = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor);
- ASSERT(SUCCEEDED(result));
-#else
- ABI::Windows::Graphics::Display::ResolutionScale resolutionScale;
- result = mDisplayInformation->get_ResolutionScale(&resolutionScale);
- ASSERT(SUCCEEDED(result));
-
- mScaleFactor = DOUBLE(resolutionScale) / 100.0;
-#endif
- }
-
- if (SUCCEEDED(result))
- {
// If a swapchain size is specfied, then the automatic resize
// behaviors implemented by the host should be disabled. The swapchain
// will be still be scaled when being rendered to fit the bounds
@@ -87,14 +61,17 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDis
}
else
{
- ABI::Windows::Foundation::Rect rect;
- HRESULT result = mCoreWindow->get_Bounds(&rect);
- if (SUCCEEDED(result))
- {
- LONG width = std::floor(rect.Width * mScaleFactor + 0.5);
- LONG height = std::floor(rect.Height * mScaleFactor + 0.5);
- mClientRect = { 0, 0, width, height };
- }
+ result = GetCoreWindowSizeInPixels(mCoreWindow, &mClientRect);
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ ComPtr<ABI::Windows::Graphics::Display::IDisplayInformationStatics> displayInformation;
+ result = GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), &displayInformation);
+ if (SUCCEEDED(result))
+ {
+ result = displayInformation->GetForCurrentView(&mDisplayInformation);
}
}
@@ -110,8 +87,21 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDis
bool CoreWindowNativeWindow::registerForSizeChangeEvents()
{
- HRESULT result = mCoreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &CoreWindowNativeWindow::onSizeChanged).Get(),
- &mSizeChangedEventToken);
+ ComPtr<IWindowSizeChangedEventHandler> sizeChangedHandler;
+ HRESULT result = Microsoft::WRL::MakeAndInitialize<CoreWindowSizeChangedHandler>(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this());
+ if (SUCCEEDED(result))
+ {
+ result = mCoreWindow->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken);
+ }
+
+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ ComPtr<IDisplayOrientationEventHandler> orientationChangedHandler;
+ result = sizeChangedHandler.As(&orientationChangedHandler);
+ if (SUCCEEDED(result))
+ {
+ result = mDisplayInformation->add_OrientationChanged(orientationChangedHandler.Get(), &mOrientationChangedEventToken);
+ }
+#endif
if (SUCCEEDED(result))
{
@@ -127,7 +117,14 @@ void CoreWindowNativeWindow::unregisterForSizeChangeEvents()
{
(void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken);
}
+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ if (mDisplayInformation)
+ {
+ (void)mDisplayInformation->remove_OrientationChanged(mOrientationChangedEventToken);
+ }
+#endif
mSizeChangedEventToken.value = 0;
+ mOrientationChangedEventToken.value = 0;
}
HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
@@ -156,7 +153,7 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor
if (SUCCEEDED(result))
{
-#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // This block is disabled for Qt applications, as the resize events are expected
+#if 0 //(WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // Qt: allow Windows Phone to resize, but don't modify the backing texture in the swap chain.
// Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On
// other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed
// (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations.
@@ -182,19 +179,36 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor
return result;
}
-// Basically, this shouldn't be used on Phone
-HRESULT CoreWindowNativeWindow::onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *e)
+HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize)
{
- ABI::Windows::Foundation::Size size;
- if (SUCCEEDED(e->get_Size(&size)))
+ ABI::Windows::Foundation::Rect bounds;
+ HRESULT result = coreWindow->get_Bounds(&bounds);
+ if (SUCCEEDED(result))
{
- SIZE windowSizeInPixels = {
- std::floor(size.Width * mScaleFactor + 0.5),
- std::floor(size.Height * mScaleFactor + 0.5)
- };
- setNewClientSize(windowSizeInPixels);
+ *windowSize = { 0, 0, ConvertDipsToPixels(bounds.Width), ConvertDipsToPixels(bounds.Height) };
}
- return S_OK;
+ return result;
+}
+
+static float GetLogicalDpi()
+{
+ ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
+ float dpi = 96.0f;
+
+ if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
+ {
+ if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
+ {
+ return dpi;
+ }
+ }
+ return dpi;
+}
+
+long ConvertDipsToPixels(float dips)
+{
+ static const float dipsPerInch = 96.0f;
+ return lround((dips * GetLogicalDpi() / dipsPerInch));
}
}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
new file mode 100644
index 0000000000..59df9d5a6c
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
@@ -0,0 +1,110 @@
+//
+// Copyright (c) 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.
+//
+
+// CoreWindowNativeWindow.h: NativeWindow for managing ICoreWindow native window types.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_WINRT_COREWINDOWNATIVEWINDOW_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_WINRT_COREWINDOWNATIVEWINDOW_H_
+
+#include "libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h"
+
+#include <memory>
+#include <windows.graphics.display.h>
+
+typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t IWindowSizeChangedEventHandler;
+typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_t IDisplayOrientationEventHandler;
+
+namespace rx
+{
+long ConvertDipsToPixels(float dips);
+
+class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
+{
+ public:
+ ~CoreWindowNativeWindow();
+
+ bool initialize(EGLNativeWindowType window, IPropertySet *propertySet);
+ bool registerForSizeChangeEvents();
+ void unregisterForSizeChangeEvents();
+ HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
+
+ private:
+ ComPtr<ABI::Windows::UI::Core::ICoreWindow> mCoreWindow;
+ ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
+ ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation> mDisplayInformation;
+ EventRegistrationToken mOrientationChangedEventToken;
+};
+
+[uuid(7F924F66-EBAE-40E5-A10B-B8F35E245190)]
+class CoreWindowSizeChangedHandler :
+ public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWindowSizeChangedEventHandler, IDisplayOrientationEventHandler>
+{
+ public:
+ CoreWindowSizeChangedHandler() { }
+ HRESULT RuntimeClassInitialize(std::shared_ptr<InspectableNativeWindow> host)
+ {
+ if (!host)
+ {
+ return E_INVALIDARG;
+ }
+
+ mHost = host;
+ return S_OK;
+ }
+
+ // IWindowSizeChangedEventHandler
+ IFACEMETHOD(Invoke)(ABI::Windows::UI::Core::ICoreWindow *sender, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *sizeChangedEventArgs)
+ {
+ std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
+ if (host)
+ {
+ ABI::Windows::Foundation::Size windowSize;
+ if (SUCCEEDED(sizeChangedEventArgs->get_Size(&windowSize)))
+ {
+ SIZE windowSizeInPixels = { ConvertDipsToPixels(windowSize.Width), ConvertDipsToPixels(windowSize.Height) };
+ host->setNewClientSize(windowSizeInPixels);
+ }
+ }
+
+ return S_OK;
+ }
+
+ IFACEMETHOD(Invoke)(ABI::Windows::Graphics::Display::IDisplayInformation *displayInformation, IInspectable *)
+ {
+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ NativeWindow::RotationFlags flags = NativeWindow::RotateNone;
+ ABI::Windows::Graphics::Display::DisplayOrientations orientation;
+ if (SUCCEEDED(displayInformation->get_CurrentOrientation(&orientation)))
+ {
+ switch (orientation)
+ {
+ case ABI::Windows::Graphics::Display::DisplayOrientations_Landscape:
+ flags = NativeWindow::RotateLeft;
+ break;
+ case ABI::Windows::Graphics::Display::DisplayOrientations_LandscapeFlipped:
+ flags = NativeWindow::RotateRight;
+ break;
+ default:
+ break;
+ }
+ }
+ std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
+ if (host)
+ {
+ host->setRotationFlags(flags);
+ }
+#endif
+ return S_OK;
+ }
+
+ private:
+ std::weak_ptr<InspectableNativeWindow> mHost;
+};
+
+HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize);
+}
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_COREWINDOWNATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
index 0589f6dce5..2bf48c5d94 100644
--- a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
@@ -6,14 +6,14 @@
// InspectableNativeWindow.cpp: NativeWindow base class for managing IInspectable native window types.
-#include "common/winrt/CoreWindowNativeWindow.h"
-#include "common/winrt/SwapChainPanelNativeWindow.h"
+#include "libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h"
+#include "libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h"
namespace rx
{
-NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display)
- : mWindow(window), mDisplay(display)
+NativeWindow::NativeWindow(EGLNativeWindowType window)
{
+ mWindow = window;
}
bool NativeWindow::initialize()
@@ -40,7 +40,7 @@ bool NativeWindow::initialize()
mImpl = std::make_shared<CoreWindowNativeWindow>();
if (mImpl)
{
- return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
+ return mImpl->initialize(mWindow, propertySet.Get());
}
}
else if (IsSwapChainPanel(mWindow, &swapChainPanel))
@@ -48,7 +48,7 @@ bool NativeWindow::initialize()
mImpl = std::make_shared<SwapChainPanelNativeWindow>();
if (mImpl)
{
- return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
+ return mImpl->initialize(mWindow, propertySet.Get());
}
}
else
@@ -69,11 +69,28 @@ bool NativeWindow::getClientRect(RECT *rect)
return false;
}
+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+NativeWindow::RotationFlags NativeWindow::rotationFlags() const
+{
+ if (mImpl)
+ {
+ return mImpl->rotationFlags();
+ }
+
+ return NativeWindow::RotateNone;
+}
+#endif
+
bool NativeWindow::isIconic()
{
return false;
}
+bool NativeWindow::isValidNativeWindow(EGLNativeWindowType window)
+{
+ return IsValidEGLNativeWindowType(window);
+}
+
HRESULT NativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
{
if (mImpl)
diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
index 402941a788..575bdf8a58 100644
--- a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
@@ -7,11 +7,13 @@
// InspectableNativeWindow.h: Host specific implementation interface for
// managing IInspectable native window types.
-#ifndef COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
-#define COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_
+
+#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h"
#include "common/platform.h"
-#include "common/NativeWindow.h"
+
#include "angle_windowsstore.h"
#include <windows.ui.xaml.h>
@@ -33,13 +35,13 @@ class InspectableNativeWindow
mClientRectChanged(false),
mClientRect({0,0,0,0}),
mNewClientRect({0,0,0,0}),
- mScaleFactor(1.0)
+ mRotationFlags(NativeWindow::RotateNone)
{
mSizeChangedEventToken.value = 0;
}
virtual ~InspectableNativeWindow(){}
- virtual bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) = 0;
+ virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0;
virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
virtual bool registerForSizeChangeEvents() = 0;
virtual void unregisterForSizeChangeEvents() = 0;
@@ -50,7 +52,6 @@ class InspectableNativeWindow
if (mClientRectChanged && mSupportsSwapChainResize)
{
mClientRect = mNewClientRect;
- mClientRectChanged = false;
}
*rect = mClientRect;
@@ -72,20 +73,33 @@ class InspectableNativeWindow
}
}
+ NativeWindow::RotationFlags rotationFlags() const
+ {
+ return mRotationFlags;
+ }
+
+ void setRotationFlags(NativeWindow::RotationFlags flags)
+ {
+ mRotationFlags = flags;
+ }
+
protected:
bool mSupportsSwapChainResize;
bool mRequiresSwapChainScaling;
RECT mClientRect;
RECT mNewClientRect;
bool mClientRectChanged;
- DOUBLE mScaleFactor;
+ NativeWindow::RotationFlags mRotationFlags;
EventRegistrationToken mSizeChangedEventToken;
};
+bool IsValidEGLNativeWindowType(EGLNativeWindowType window);
bool IsCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr);
bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel = nullptr);
bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr);
HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists);
+
}
-#endif // COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
index 268dfbd8f0..53899dbb30 100644
--- a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
@@ -6,9 +6,11 @@
// SwapChainPanelNativeWindow.cpp: NativeWindow for managing ISwapChainPanel native window types.
-#include "common/winrt/SwapChainPanelNativeWindow.h"
+#include "libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h"
+
#include <algorithm>
#include <math.h>
+
using namespace ABI::Windows::Foundation::Collections;
namespace rx
@@ -18,7 +20,7 @@ SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow()
unregisterForSizeChangeEvents();
}
-bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
+bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet)
{
ComPtr<IPropertySet> props = propertySet;
ComPtr<IInspectable> win = window;
diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
index 5bbf274e64..caf327d913 100644
--- a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
@@ -6,10 +6,10 @@
// SwapChainPanelNativeWindow.h: NativeWindow for managing ISwapChainPanel native window types.
-#ifndef COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
-#define COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
-#include "common/winrt/InspectableNativeWindow.h"
+#include "libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h"
namespace rx
{
@@ -18,7 +18,7 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e
public:
~SwapChainPanelNativeWindow();
- bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
+ bool initialize(EGLNativeWindowType window, IPropertySet *propertySet);
bool registerForSizeChangeEvents();
void unregisterForSizeChangeEvents();
HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
@@ -76,4 +76,4 @@ class SwapChainPanelSizeChangedHandler :
HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize);
}
-#endif // COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
index 2ca7a9cf8a..a0bc2960b7 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
@@ -6,41 +6,41 @@
// Blit9.cpp: Surface copy utility class.
-#include "libGLESv2/renderer/d3d/d3d9/Blit9.h"
-#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h"
-#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/d3d9/Blit9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
namespace
{
// Precompiled shaders
-#include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/standardvs.h"
-#include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/flipyvs.h"
-#include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/passthroughps.h"
-#include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/luminanceps.h"
-#include "libGLESv2/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/flipyvs.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h"
const BYTE* const g_shaderCode[] =
{
- g_vs20_VS_standard,
- g_vs20_VS_flipy,
- g_ps20_PS_passthrough,
- g_ps20_PS_luminance,
- g_ps20_PS_componentmask
+ g_vs20_standardvs,
+ g_vs20_flipyvs,
+ g_ps20_passthroughps,
+ g_ps20_luminanceps,
+ g_ps20_componentmaskps
};
const size_t g_shaderSize[] =
{
- sizeof(g_vs20_VS_standard),
- sizeof(g_vs20_VS_flipy),
- sizeof(g_ps20_PS_passthrough),
- sizeof(g_ps20_PS_luminance),
- sizeof(g_ps20_PS_componentmask)
+ sizeof(g_vs20_standardvs),
+ sizeof(g_vs20_flipyvs),
+ sizeof(g_ps20_passthroughps),
+ sizeof(g_ps20_luminanceps),
+ sizeof(g_ps20_componentmaskps)
};
}
@@ -217,7 +217,7 @@ gl::Error Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- setViewport(getSurfaceRect(dest), 0, 0);
+ setViewport(getSurfaceRect(dest), gl::Offset(0, 0, 0));
render();
@@ -228,7 +228,7 @@ gl::Error Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
return gl::Error(GL_NO_ERROR);
}
-gl::Error Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
+gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLint level)
{
gl::Error error = initialize();
if (error.isError())
@@ -259,7 +259,7 @@ gl::Error Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GL
}
ASSERT(destSurface);
- gl::Error result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
+ gl::Error result = copy(source, sourceRect, destFormat, destOffset, destSurface);
SafeRelease(destSurface);
SafeRelease(source);
@@ -267,7 +267,7 @@ gl::Error Blit9::copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GL
return result;
}
-gl::Error Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
+gl::Error Blit9::copyCube(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level)
{
gl::Error error = initialize();
if (error.isError())
@@ -298,7 +298,7 @@ gl::Error Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect,
}
ASSERT(destSurface);
- gl::Error result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
+ gl::Error result = copy(source, sourceRect, destFormat, destOffset, destSurface);
SafeRelease(destSurface);
SafeRelease(source);
@@ -306,7 +306,7 @@ gl::Error Blit9::copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect,
return result;
}
-gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
+gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest)
{
ASSERT(source != NULL && dest != NULL);
@@ -320,7 +320,7 @@ gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum
if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET &&
d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect
{
- RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)};
+ 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);
if (FAILED(result))
@@ -333,11 +333,11 @@ gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum
}
else
{
- return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
+ return formatConvert(source, sourceRect, destFormat, destOffset, dest);
}
}
-gl::Error Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
+gl::Error Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest)
{
gl::Error error = initialize();
if (error.isError())
@@ -359,7 +359,7 @@ gl::Error Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect
device->SetTexture(0, texture);
device->SetRenderTarget(0, dest);
- setViewport(sourceRect, xoffset, yoffset);
+ setViewport(sourceRect, destOffset);
setCommonBlitState();
@@ -548,13 +548,13 @@ gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &so
return gl::Error(GL_NO_ERROR);
}
-void Blit9::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset)
+void Blit9::setViewport(const RECT &sourceRect, const gl::Offset &offset)
{
IDirect3DDevice9 *device = mRenderer->getDevice();
D3DVIEWPORT9 vp;
- vp.X = xoffset;
- vp.Y = yoffset;
+ vp.X = offset.x;
+ vp.Y = offset.y;
vp.Width = sourceRect.right - sourceRect.left;
vp.Height = sourceRect.bottom - sourceRect.top;
vp.MinZ = 0.0f;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h
index 5c7a76ce05..586abd2580 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h
@@ -6,17 +6,18 @@
// Blit9.cpp: Surface copy utility class.
-#ifndef LIBGLESV2_BLIT9_H_
-#define LIBGLESV2_BLIT9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_
#include "common/angleutils.h"
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
#include <GLES2/gl2.h>
namespace gl
{
class Framebuffer;
+struct Offset;
}
namespace rx
@@ -24,7 +25,7 @@ namespace rx
class Renderer9;
class TextureStorage;
-class Blit9
+class Blit9 : angle::NonCopyable
{
public:
explicit Blit9(Renderer9 *renderer);
@@ -34,13 +35,13 @@ class Blit9
// Copy from source surface to dest surface.
// sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
- gl::Error copy2D(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
- gl::Error copyCube(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
+ gl::Error copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLint level);
+ gl::Error copyCube(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level);
// Copy from source surface 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.
- gl::Error formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
+ gl::Error formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest);
// 2x2 box filter sample from source to dest.
// Requires that source is RGB(A) and dest has the same format as source.
@@ -55,9 +56,9 @@ class Blit9
gl::Error setFormatConvertShaders(GLenum destFormat);
- gl::Error copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
+ gl::Error copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest);
gl::Error copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture);
- void setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset);
+ void setViewport(const RECT &sourceRect, const gl::Offset &offset);
void setCommonBlitState();
RECT getSurfaceRect(IDirect3DSurface9 *surface) const;
@@ -89,9 +90,8 @@ class Blit9
IDirect3DStateBlock9 *mSavedStateBlock;
IDirect3DSurface9 *mSavedRenderTarget;
IDirect3DSurface9 *mSavedDepthStencil;
-
- DISALLOW_COPY_AND_ASSIGN(Blit9);
};
+
}
-#endif // LIBGLESV2_BLIT9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
index 430fe81e50..b051c81aa8 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
@@ -6,15 +6,14 @@
// Buffer9.cpp Defines the Buffer9 class.
-#include "libGLESv2/renderer/d3d/d3d9/Buffer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/d3d9/Buffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
namespace rx
{
Buffer9::Buffer9(Renderer9 *renderer)
- : BufferD3D(),
+ : BufferD3D(renderer),
mRenderer(renderer),
mSize(0)
{}
@@ -114,9 +113,4 @@ void Buffer9::markTransformFeedbackUsage()
UNREACHABLE();
}
-RendererD3D *Buffer9::getRenderer()
-{
- return mRenderer;
-}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
index c80b009738..c1984146fc 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
@@ -6,12 +6,12 @@
// Buffer9.h: Defines the rx::Buffer9 class which implements rx::BufferImpl via rx::BufferD3D.
-#ifndef LIBGLESV2_RENDERER_BUFFER9_H_
-#define LIBGLESV2_RENDERER_BUFFER9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_
-#include "libGLESv2/renderer/d3d/BufferD3D.h"
-#include "libGLESv2/renderer/d3d/MemoryBuffer.h"
-#include "libGLESv2/angletypes.h"
+#include "common/MemoryBuffer.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
namespace rx
{
@@ -28,7 +28,6 @@ class Buffer9 : public BufferD3D
// BufferD3D implementation
virtual size_t getSize() const { return mSize; }
virtual bool supportsDirectBinding() const { return false; }
- RendererD3D *getRenderer() override;
// BufferImpl implementation
virtual gl::Error setData(const void* data, size_t size, GLenum usage);
@@ -40,8 +39,6 @@ class Buffer9 : public BufferD3D
virtual void markTransformFeedbackUsage();
private:
- DISALLOW_COPY_AND_ASSIGN(Buffer9);
-
Renderer9 *mRenderer;
MemoryBuffer mMemory;
size_t mSize;
@@ -49,4 +46,4 @@ class Buffer9 : public BufferD3D
}
-#endif // LIBGLESV2_RENDERER_BUFFER9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp
new file mode 100644
index 0000000000..09b229bcb1
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp
@@ -0,0 +1,36 @@
+//
+// 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(const std::wstring &eventName)
+{
+ D3DPERF_BeginEvent(0, eventName.c_str());
+}
+
+void DebugAnnotator9::endEvent()
+{
+ D3DPERF_EndEvent();
+}
+
+void DebugAnnotator9::setMarker(const std::wstring &markerName)
+{
+ D3DPERF_SetMarker(0, markerName.c_str());
+}
+
+bool DebugAnnotator9::getStatus()
+{
+ return !!D3DPERF_GetStatus();
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h
new file mode 100644
index 0000000000..02956f7183
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h
@@ -0,0 +1,29 @@
+//
+// 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 "common/debug.h"
+
+namespace rx
+{
+
+class DebugAnnotator9 : public gl::DebugAnnotator
+{
+ public:
+ DebugAnnotator9() {}
+ void beginEvent(const std::wstring &eventName) override;
+ void endEvent() override;
+ void setMarker(const std::wstring &markerName) override;
+ bool getStatus() override;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_DEBUGANNOTATOR9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp
index 66263fe110..27c265e28d 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp
@@ -6,10 +6,9 @@
// Fence9.cpp: Defines the rx::FenceNV9 class.
-#include "libGLESv2/renderer/d3d/d3d9/Fence9.h"
-#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/d3d9/Fence9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
namespace rx
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h
index d7873d5264..4b86747396 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h
@@ -6,10 +6,11 @@
// Fence9.h: Defines the rx::FenceNV9 class which implements rx::FenceNVImpl.
-#ifndef LIBGLESV2_RENDERER_FENCE9_H_
-#define LIBGLESV2_RENDERER_FENCE9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_FENCE9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_FENCE9_H_
-#include "libGLESv2/renderer/FenceImpl.h"
+#include "libANGLE/renderer/FenceNVImpl.h"
+#include "libANGLE/renderer/FenceSyncImpl.h"
namespace rx
{
@@ -26,12 +27,10 @@ class FenceNV9 : public FenceNVImpl
gl::Error finishFence(GLboolean *outFinished);
private:
- DISALLOW_COPY_AND_ASSIGN(FenceNV9);
-
Renderer9 *mRenderer;
IDirect3DQuery9 *mQuery;
};
}
-#endif // LIBGLESV2_RENDERER_FENCE9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_FENCE9_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
new file mode 100644
index 0000000000..dbdfc6d6de
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.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.
+//
+
+// Framebuffer9.cpp: Implements the Framebuffer9 class.
+
+#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Texture.h"
+
+namespace rx
+{
+
+Framebuffer9::Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer)
+ : FramebufferD3D(data, renderer),
+ mRenderer(renderer)
+{
+ ASSERT(mRenderer != nullptr);
+}
+
+Framebuffer9::~Framebuffer9()
+{
+}
+
+gl::Error Framebuffer9::clear(const gl::State &state, const ClearParameters &clearParams)
+{
+ const gl::FramebufferAttachment *colorAttachment = mData.mColorAttachments[0];
+ const gl::FramebufferAttachment *depthStencilAttachment = mData.getDepthOrStencilAttachment();
+
+ gl::Error error = mRenderer->applyRenderTarget(colorAttachment, depthStencilAttachment);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ float nearZ, farZ;
+ state.getDepthRange(&nearZ, &farZ);
+ mRenderer->setViewport(state.getViewport(), nearZ, farZ, GL_TRIANGLES, state.getRasterizerState().frontFace, true);
+
+ mRenderer->setScissorRectangle(state.getScissor(), state.isScissorTestEnabled());
+
+ return mRenderer->clear(clearParams, colorAttachment, depthStencilAttachment);
+}
+
+gl::Error Framebuffer9::readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) const
+{
+ ASSERT(pack.pixelBuffer.get() == NULL);
+
+ const gl::FramebufferAttachment *colorbuffer = mData.mColorAttachments[0];
+ ASSERT(colorbuffer);
+
+ RenderTarget9 *renderTarget = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(renderTarget);
+
+ IDirect3DSurface9 *surface = renderTarget->getSurface();
+ ASSERT(surface);
+
+ D3DSURFACE_DESC desc;
+ surface->GetDesc(&desc);
+
+ if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
+ {
+ UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target
+ SafeRelease(surface);
+ return gl::Error(GL_OUT_OF_MEMORY, "ReadPixels is unimplemented for multisampled framebuffer attachments.");
+ }
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ ASSERT(device);
+
+ HRESULT result;
+ IDirect3DSurface9 *systemSurface = NULL;
+ 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, NULL);
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ SafeRelease(surface);
+ return gl::Error(GL_OUT_OF_MEMORY, "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();
+ }
+
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to read internal render target data.");
+ }
+
+ if (directToPixels)
+ {
+ SafeRelease(systemSurface);
+ return gl::Error(GL_NO_ERROR);
+ }
+
+ 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);
+
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal render target.");
+ }
+
+ uint8_t *source;
+ int inputPitch;
+ if (pack.reverseRowOrder)
+ {
+ source = reinterpret_cast<uint8_t*>(lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1);
+ inputPitch = -lock.Pitch;
+ }
+ else
+ {
+ source = reinterpret_cast<uint8_t*>(lock.pBits);
+ inputPitch = lock.Pitch;
+ }
+
+ const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
+ const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3dFormatInfo.internalFormat);
+ if (sourceFormatInfo.format == format && sourceFormatInfo.type == type)
+ {
+ // Direct copy possible
+ for (int y = 0; y < rect.bottom - rect.top; y++)
+ {
+ memcpy(pixels + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourceFormatInfo.pixelBytes);
+ }
+ }
+ else
+ {
+ const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
+ ColorCopyFunction fastCopyFunc = sourceD3DFormatInfo.getFastCopyFunction(format, type);
+
+ GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(format, type);
+ const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat);
+
+ if (fastCopyFunc)
+ {
+ // Fast copy is possible through some special function
+ for (int y = 0; y < rect.bottom - rect.top; y++)
+ {
+ for (int x = 0; x < rect.right - rect.left; x++)
+ {
+ uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes;
+ const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
+
+ fastCopyFunc(src, dest);
+ }
+ }
+ }
+ else
+ {
+ ColorReadFunction colorReadFunction = sourceD3DFormatInfo.colorReadFunction;
+ ColorWriteFunction colorWriteFunction = GetColorWriteFunction(format, type);
+
+ uint8_t temp[sizeof(gl::ColorF)];
+ for (int y = 0; y < rect.bottom - rect.top; y++)
+ {
+ for (int x = 0; x < rect.right - rect.left; x++)
+ {
+ uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes;
+ const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
+
+ // readFunc and writeFunc will be using the same type of color, CopyTexImage
+ // will not allow the copy otherwise.
+ colorReadFunction(src, temp);
+ colorWriteFunction(temp, dest);
+ }
+ }
+ }
+ }
+
+ systemSurface->UnlockRect();
+ SafeRelease(systemSurface);
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Framebuffer9::blit(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();
+
+ if (blitRenderTarget)
+ {
+ const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getColorbuffer(0);
+ ASSERT(readBuffer);
+
+ RenderTarget9 *readRenderTarget = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(readRenderTarget);
+
+ const gl::FramebufferAttachment *drawBuffer = mData.mColorAttachments[0];
+ ASSERT(drawBuffer);
+
+ RenderTarget9 *drawRenderTarget = NULL;
+ error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+ 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);
+
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
+ }
+ }
+
+ if (blitDepth || blitStencil)
+ {
+ const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getDepthOrStencilbuffer();
+ ASSERT(readBuffer);
+
+ RenderTarget9 *readDepthStencil = NULL;
+ gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readDepthStencil);
+ if (error.isError())
+ {
+ return error;
+ }
+ ASSERT(readDepthStencil);
+
+ const gl::FramebufferAttachment *drawBuffer = mData.getDepthOrStencilAttachment();
+ ASSERT(drawBuffer);
+
+ RenderTarget9 *drawDepthStencil = NULL;
+ error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawDepthStencil);
+ if (error.isError())
+ {
+ return error;
+ }
+ 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, NULL, drawSurface, NULL, D3DTEXF_NONE);
+
+ SafeRelease(readSurface);
+ SafeRelease(drawSurface);
+
+ if (FAILED(result))
+ {
+ return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
+ }
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+GLenum Framebuffer9::getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const
+{
+ RenderTarget9 *renderTarget9 = RenderTarget9::makeRenderTarget9(renderTarget);
+ const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(renderTarget9->getD3DFormat());
+ return d3dFormatInfo.internalFormat;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
new file mode 100644
index 0000000000..292118e6db
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
@@ -0,0 +1,41 @@
+//
+// 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/d3d/FramebufferD3D.h"
+
+namespace rx
+{
+class Renderer9;
+
+class Framebuffer9 : public FramebufferD3D
+{
+ public:
+ Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer);
+ virtual ~Framebuffer9();
+
+ private:
+ gl::Error clear(const gl::State &state, const ClearParameters &clearParams) override;
+
+ gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch,
+ const gl::PixelPackState &pack, uint8_t *pixels) const override;
+
+ gl::Error blit(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;
+
+ GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override;
+
+ Renderer9 *const mRenderer;
+};
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
index 2a06d12942..d149f7a806 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
@@ -7,28 +7,30 @@
// Image9.cpp: Implements the rx::Image9 class, which acts as the interface to
// the actual underlying surfaces of a Texture.
-#include "libGLESv2/renderer/d3d/d3d9/Image9.h"
-#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
-#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/Renderbuffer.h"
+#include "libANGLE/renderer/d3d/d3d9/Image9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Renderbuffer.h"
#include "common/utilities.h"
namespace rx
{
-Image9::Image9()
+Image9::Image9(Renderer9 *renderer)
{
mSurface = NULL;
mRenderer = NULL;
mD3DPool = D3DPOOL_SYSTEMMEM;
mD3DFormat = D3DFMT_UNKNOWN;
+
+ mRenderer = renderer;
}
Image9::~Image9()
@@ -92,7 +94,7 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9
return gl::Error(GL_NO_ERROR);
}
-Image9 *Image9::makeImage9(Image *img)
+Image9 *Image9::makeImage9(ImageD3D *img)
{
ASSERT(HAS_DYNAMIC_TYPE(Image9*, img));
return static_cast<Image9*>(img);
@@ -168,32 +170,28 @@ gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface
return gl::Error(GL_NO_ERROR);
}
-bool Image9::redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease)
+bool Image9::redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease)
{
// 3D textures are not supported by the D3D9 backend.
- ASSERT(depth <= 1);
+ ASSERT(size.depth <= 1);
// Only 2D and cube texture are supported by the D3D9 backend.
ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP);
- if (mWidth != width ||
- mHeight != height ||
- mDepth != depth ||
+ if (mWidth != size.width ||
+ mHeight != size.height ||
+ mDepth != size.depth ||
mInternalFormat != internalformat ||
forceRelease)
{
- mRenderer = Renderer9::makeRenderer9(renderer);
-
- mWidth = width;
- mHeight = height;
- mDepth = depth;
+ mWidth = size.width;
+ mHeight = size.height;
+ mDepth = size.depth;
mInternalFormat = internalformat;
// compute the d3d format that will be used
const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalformat);
- const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat);
mD3DFormat = d3d9FormatInfo.texFormat;
- mActualFormat = d3dFormatInfo.internalFormat;
mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN);
SafeRelease(mSurface);
@@ -397,7 +395,7 @@ gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &i
if (index.type == GL_TEXTURE_2D)
{
TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage);
- gl::Error error = storage9->getSurfaceLevel(index.mipIndex, true, &destSurface);
+ error = storage9->getSurfaceLevel(index.mipIndex, true, &destSurface);
if (error.isError())
{
return error;
@@ -405,23 +403,23 @@ gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &i
}
else
{
- ASSERT(gl::IsCubemapTextureTarget(index.type));
+ ASSERT(gl::IsCubeMapTextureTarget(index.type));
TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage);
- gl::Error error = storage9->getCubeMapSurface(index.type, index.mipIndex, true, &destSurface);
+ error = storage9->getCubeMapSurface(index.type, index.mipIndex, true, &destSurface);
if (error.isError())
{
return error;
}
}
- error = copyToSurface(destSurface, region.x, region.y, region.width, region.height);
+ error = copyToSurface(destSurface, region);
SafeRelease(destSurface);
return error;
}
-gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, const gl::Box &area)
{
- ASSERT(width > 0 && height > 0);
+ ASSERT(area.width > 0 && area.height > 0 && area.depth == 1);
ASSERT(destSurface);
IDirect3DSurface9 *sourceSurface = NULL;
@@ -434,10 +432,10 @@ gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, G
ASSERT(sourceSurface && sourceSurface != destSurface);
RECT rect;
- rect.left = xoffset;
- rect.top = yoffset;
- rect.right = xoffset + width;
- rect.bottom = yoffset + height;
+ 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};
@@ -480,22 +478,21 @@ gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, GLint xoffset, G
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the target pixel rectangle.
-gl::Error Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input)
+gl::Error Image9::loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input)
{
// 3D textures are not supported by the D3D9 backend.
- ASSERT(zoffset == 0 && depth == 1);
+ ASSERT(area.z == 0 && area.depth == 1);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
- GLsizei inputRowPitch = formatInfo.computeRowPitch(type, width, unpackAlignment);
+ GLsizei inputRowPitch = formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength);
const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
ASSERT(d3dFormatInfo.loadFunction != NULL);
RECT lockRect =
{
- xoffset, yoffset,
- xoffset + width, yoffset + height
+ area.x, area.y,
+ area.x + area.width, area.y + area.height
};
D3DLOCKED_RECT locked;
@@ -505,7 +502,7 @@ gl::Error Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei
return error;
}
- d3dFormatInfo.loadFunction(width, height, depth,
+ d3dFormatInfo.loadFunction(area.width, area.height, area.depth,
reinterpret_cast<const uint8_t*>(input), inputRowPitch, 0,
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
@@ -514,27 +511,26 @@ gl::Error Image9::loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei
return gl::Error(GL_NO_ERROR);
}
-gl::Error Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input)
+gl::Error Image9::loadCompressedData(const gl::Box &area, const void *input)
{
// 3D textures are not supported by the D3D9 backend.
- ASSERT(zoffset == 0 && depth == 1);
+ ASSERT(area.z == 0 && area.depth == 1);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat);
- GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, width, 1);
- GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, width, height, 1);
+ GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0);
+ GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0);
const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
- ASSERT(xoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0);
- ASSERT(yoffset % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0);
+ ASSERT(area.x % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0);
+ ASSERT(area.y % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0);
ASSERT(d3d9FormatInfo.loadFunction != NULL);
RECT lockRect =
{
- xoffset, yoffset,
- xoffset + width, yoffset + height
+ area.x, area.y,
+ area.x + area.width, area.y + area.height
};
D3DLOCKED_RECT locked;
@@ -544,7 +540,7 @@ gl::Error Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset
return error;
}
- d3d9FormatInfo.loadFunction(width, height, depth,
+ d3d9FormatInfo.loadFunction(area.width, area.height, area.depth,
reinterpret_cast<const uint8_t*>(input), inputRowPitch, inputDepthPitch,
reinterpret_cast<uint8_t*>(locked.pBits), locked.Pitch, 0);
@@ -554,12 +550,12 @@ gl::Error Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset
}
// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
-gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source)
+gl::Error Image9::copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source)
{
ASSERT(source);
// ES3.0 only behaviour to copy into a 3d texture
- ASSERT(zoffset == 0);
+ ASSERT(destOffset.z == 0);
RenderTarget9 *renderTarget = RenderTarget9::makeRenderTarget9(source);
@@ -593,7 +589,7 @@ gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Re
int height = sourceArea.height;
RECT sourceRect = { sourceArea.x, sourceArea.y, sourceArea.x + width, sourceArea.y + height };
- RECT destRect = { xoffset, yoffset, xoffset + width, yoffset + height };
+ RECT destRect = { destOffset.x, destOffset.y, destOffset.x + width, destOffset.y + height };
D3DLOCKED_RECT sourceLock = {0};
result = renderTargetData->LockRect(&sourceLock, &sourceRect, 0);
@@ -782,7 +778,7 @@ gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Re
return gl::Error(GL_NO_ERROR);
}
-gl::Error Image9::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, const gl::ImageIndex &srcIndex, TextureStorage *srcStorage)
+gl::Error Image9::copy(const gl::Offset &destOffset, const gl::Box &area, const gl::ImageIndex &srcIndex, TextureStorage *srcStorage)
{
// Currently unreachable, due to only being used in a D3D11-only workaround
UNIMPLEMENTED();
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h
index 8cc2258859..8cbfbbebf6 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h
@@ -7,10 +7,10 @@
// Image9.h: Defines the rx::Image9 class, which acts as the interface to
// the actual underlying surfaces of a Texture.
-#ifndef LIBGLESV2_RENDERER_IMAGE9_H_
-#define LIBGLESV2_RENDERER_IMAGE9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_IMAGE9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_IMAGE9_H_
-#include "libGLESv2/renderer/d3d/ImageD3D.h"
+#include "libANGLE/renderer/d3d/ImageD3D.h"
#include "common/debug.h"
namespace gl
@@ -25,16 +25,16 @@ class Renderer9;
class Image9 : public ImageD3D
{
public:
- Image9();
+ Image9(Renderer9 *renderer);
~Image9();
- static Image9 *makeImage9(Image *img);
+ static Image9 *makeImage9(ImageD3D *img);
static gl::Error generateMipmap(Image9 *dest, Image9 *source);
static gl::Error generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface);
static gl::Error copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source);
- bool redefine(RendererD3D *renderer, GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, bool forceRelease) override;
+ bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) override;
D3DFORMAT getD3DFormat() const;
@@ -44,23 +44,19 @@ class Image9 : public ImageD3D
virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level);
virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region);
- virtual gl::Error loadData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- GLint unpackAlignment, GLenum type, const void *input);
- virtual gl::Error loadCompressedData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
- const void *input);
+ virtual gl::Error loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input);
+ virtual gl::Error loadCompressedData(const gl::Box &area, const void *input);
- virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea, RenderTarget *source);
- virtual gl::Error copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &sourceArea,
+ virtual gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source);
+ virtual gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea,
const gl::ImageIndex &sourceIndex, TextureStorage *source);
private:
- DISALLOW_COPY_AND_ASSIGN(Image9);
-
gl::Error getSurface(IDirect3DSurface9 **outSurface);
gl::Error createSurface();
gl::Error setManagedSurface(IDirect3DSurface9 *surface);
- gl::Error copyToSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+ gl::Error copyToSurface(IDirect3DSurface9 *dest, const gl::Box &area);
gl::Error lock(D3DLOCKED_RECT *lockedRect, const RECT &rect);
void unlock();
@@ -74,4 +70,4 @@ class Image9 : public ImageD3D
};
}
-#endif // LIBGLESV2_RENDERER_IMAGE9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_IMAGE9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp
index 1c51b9e985..c5d72e6a50 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp
@@ -6,8 +6,8 @@
// Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation.
-#include "libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
namespace rx
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h
index 2375fcf4b0..61f8b11566 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h
@@ -6,10 +6,10 @@
// Indexffer9.h: Defines the D3D9 IndexBuffer implementation.
-#ifndef LIBGLESV2_RENDERER_INDEXBUFFER9_H_
-#define LIBGLESV2_RENDERER_INDEXBUFFER9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_INDEXBUFFER9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_INDEXBUFFER9_H_
-#include "libGLESv2/renderer/d3d/IndexBuffer.h"
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
namespace rx
{
@@ -38,8 +38,6 @@ class IndexBuffer9 : public IndexBuffer
IDirect3DIndexBuffer9 *getBuffer() const;
private:
- DISALLOW_COPY_AND_ASSIGN(IndexBuffer9);
-
Renderer9 *const mRenderer;
IDirect3DIndexBuffer9 *mIndexBuffer;
@@ -50,4 +48,4 @@ class IndexBuffer9 : public IndexBuffer
}
-#endif // LIBGLESV2_RENDERER_INDEXBUFFER9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_INDEXBUFFER9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp
index a3cab578be..96f12d7868 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp
@@ -6,10 +6,9 @@
// Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl.
-#include "libGLESv2/renderer/d3d/d3d9/Query9.h"
-#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/d3d9/Query9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
#include <GLES2/gl2ext.h>
@@ -132,8 +131,9 @@ gl::Error Query9::testQuery()
mRenderer->notifyDeviceLost();
return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost.");
}
- else if (mRenderer->testDeviceLost(true))
+ else if (mRenderer->testDeviceLost())
{
+ mRenderer->notifyDeviceLost();
return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost.");
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h
index 36851c6c6c..399da2ed83 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h
@@ -6,10 +6,10 @@
// Query9.h: Defines the rx::Query9 class which implements rx::QueryImpl.
-#ifndef LIBGLESV2_RENDERER_QUERY9_H_
-#define LIBGLESV2_RENDERER_QUERY9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_QUERY9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_QUERY9_H_
-#include "libGLESv2/renderer/QueryImpl.h"
+#include "libANGLE/renderer/QueryImpl.h"
namespace rx
{
@@ -27,8 +27,6 @@ class Query9 : public QueryImpl
virtual gl::Error isResultAvailable(GLuint *available);
private:
- DISALLOW_COPY_AND_ASSIGN(Query9);
-
gl::Error testQuery();
GLuint mResult;
@@ -40,4 +38,4 @@ class Query9 : public QueryImpl
}
-#endif // LIBGLESV2_RENDERER_QUERY9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_QUERY9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp
index 53d1f752fa..412c0109f5 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp
@@ -7,27 +7,21 @@
// RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9
// pointers retained by renderbuffers.
-#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
namespace rx
{
-RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target)
+RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTargetD3D *target)
{
ASSERT(HAS_DYNAMIC_TYPE(RenderTarget9*, target));
return static_cast<RenderTarget9*>(target);
}
-void RenderTarget9::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
-{
- // Currently a no-op
-}
-
// TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given.
TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
GLsizei samples)
@@ -35,7 +29,7 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in
mHeight(height),
mDepth(depth),
mInternalFormat(internalFormat),
- mActualFormat(internalFormat),
+ mD3DFormat(D3DFMT_UNKNOWN),
mSamples(samples),
mRenderTarget(surface)
{
@@ -45,9 +39,7 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in
{
D3DSURFACE_DESC description;
mRenderTarget->GetDesc(&description);
-
- const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(description.Format);
- mActualFormat = d3dFormatInfo.internalFormat;
+ mD3DFormat = description.Format;
}
}
@@ -76,11 +68,6 @@ GLenum TextureRenderTarget9::getInternalFormat() const
return mInternalFormat;
}
-GLenum TextureRenderTarget9::getActualFormat() const
-{
- return mActualFormat;
-}
-
GLsizei TextureRenderTarget9::getSamples() const
{
return mSamples;
@@ -98,6 +85,10 @@ IDirect3DSurface9 *TextureRenderTarget9::getSurface()
return mRenderTarget;
}
+D3DFORMAT TextureRenderTarget9::getD3DFormat() const
+{
+ return mD3DFormat;
+}
SurfaceRenderTarget9::SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth)
: mSwapChain(swapChain),
@@ -129,11 +120,6 @@ GLenum SurfaceRenderTarget9::getInternalFormat() const
return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat());
}
-GLenum SurfaceRenderTarget9::getActualFormat() const
-{
- return d3d9::GetD3DFormatInfo(d3d9::GetTextureFormatInfo(getInternalFormat()).texFormat).internalFormat;
-}
-
GLsizei SurfaceRenderTarget9::getSamples() const
{
// Our EGL surfaces do not support multisampling.
@@ -145,4 +131,9 @@ IDirect3DSurface9 *SurfaceRenderTarget9::getSurface()
return (mDepth ? mSwapChain->getDepthStencil() : mSwapChain->getRenderTarget());
}
+D3DFORMAT SurfaceRenderTarget9::getD3DFormat() const
+{
+ return d3d9::GetTextureFormatInfo(getInternalFormat()).texFormat;
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h
index 4585697f4c..32c7dfa09c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h
@@ -7,30 +7,27 @@
// RenderTarget9.h: Defines a D3D9-specific wrapper for IDirect3DSurface9 pointers
// retained by Renderbuffers.
-#ifndef LIBGLESV2_RENDERER_RENDERTARGET9_H_
-#define LIBGLESV2_RENDERER_RENDERTARGET9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERTARGET9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_RENDERTARGET9_H_
-#include "libGLESv2/renderer/RenderTarget.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
namespace rx
{
class Renderer9;
class SwapChain9;
-class RenderTarget9 : public RenderTarget
+class RenderTarget9 : public RenderTargetD3D
{
public:
RenderTarget9() { }
virtual ~RenderTarget9() { }
- static RenderTarget9 *makeRenderTarget9(RenderTarget *renderTarget);
-
- void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) override;
+ static RenderTarget9 *makeRenderTarget9(RenderTargetD3D *renderTarget);
virtual IDirect3DSurface9 *getSurface() = 0;
- private:
- DISALLOW_COPY_AND_ASSIGN(RenderTarget9);
+ virtual D3DFORMAT getD3DFormat() const = 0;
};
class TextureRenderTarget9 : public RenderTarget9
@@ -44,19 +41,18 @@ class TextureRenderTarget9 : public RenderTarget9
GLsizei getHeight() const override;
GLsizei getDepth() const override;
GLenum getInternalFormat() const override;
- GLenum getActualFormat() const override;
GLsizei getSamples() const override;
IDirect3DSurface9 *getSurface() override;
- private:
- DISALLOW_COPY_AND_ASSIGN(TextureRenderTarget9);
+ D3DFORMAT getD3DFormat() const override;
+ private:
GLsizei mWidth;
GLsizei mHeight;
GLsizei mDepth;
GLenum mInternalFormat;
- GLenum mActualFormat;
+ D3DFORMAT mD3DFormat;
GLsizei mSamples;
IDirect3DSurface9 *mRenderTarget;
@@ -72,18 +68,17 @@ class SurfaceRenderTarget9 : public RenderTarget9
GLsizei getHeight() const override;
GLsizei getDepth() const override;
GLenum getInternalFormat() const override;
- GLenum getActualFormat() const override;
GLsizei getSamples() const override;
IDirect3DSurface9 *getSurface() override;
- private:
- DISALLOW_COPY_AND_ASSIGN(SurfaceRenderTarget9);
+ D3DFORMAT getD3DFormat() const override;
+ private:
SwapChain9 *mSwapChain;
bool mDepth;
};
}
-#endif // LIBGLESV2_RENDERER_RENDERTARGET9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERTARGET9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index 18e6e2d7f0..bf1c367693 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -6,79 +6,64 @@
// Renderer9.cpp: Implements a back-end specific class for the D3D9 renderer.
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.h"
-#include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h"
-#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Image9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Blit9.h"
-#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
-#include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Buffer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Query9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Fence9.h"
-#include "libGLESv2/renderer/d3d/d3d9/VertexArray9.h"
-#include "libGLESv2/renderer/d3d/IndexDataManager.h"
-#include "libGLESv2/renderer/d3d/ProgramD3D.h"
-#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
-#include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
-#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/State.h"
-#include "libGLESv2/angletypes.h"
-
-#include "libEGL/Display.h"
-
-#include "common/features.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+
#include "common/utilities.h"
+#include "libANGLE/Buffer.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/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/TransformFeedbackD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/Blit9.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/Image9.h"
+#include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.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/renderer9_utils.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+
+#include "third_party/trace_event/trace_event.h"
#include <sstream>
-// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
-#define REF_RAST 0
+#include <EGL/eglext.h>
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
-const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z')));
-const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L')));
+// 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
{
-static const D3DFORMAT RenderTargetFormats[] =
- {
- D3DFMT_A1R5G5B5,
- // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
- D3DFMT_A8R8G8B8,
- D3DFMT_R5G6B5,
- // D3DFMT_X1R5G5B5, // Has no compatible OpenGL ES renderbuffer format
- D3DFMT_X8R8G8B8
- };
-
-static const D3DFORMAT DepthStencilFormats[] =
- {
- D3DFMT_UNKNOWN,
- // D3DFMT_D16_LOCKABLE,
- D3DFMT_D32,
- // D3DFMT_D15S1,
- D3DFMT_D24S8,
- D3DFMT_D24X8,
- // D3DFMT_D24X4S4,
- D3DFMT_D16,
- // D3DFMT_D32F_LOCKABLE,
- // D3DFMT_D24FS8
- };
enum
{
@@ -91,10 +76,12 @@ enum
MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4
};
-Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes)
- : RendererD3D(display),
- mDc(hDc)
+Renderer9::Renderer9(egl::Display *display)
+ : RendererD3D(display)
{
+ // Initialize global annotator
+ gl::InitializeDebugAnnotations(&mAnnotator);
+
mD3d9Module = NULL;
mD3d9 = NULL;
@@ -106,13 +93,26 @@ Renderer9::Renderer9(egl::Display *display, EGLNativeDisplayType hDc, const egl:
mAdapter = D3DADAPTER_DEFAULT;
- #if REF_RAST == 1 || defined(FORCE_REF_RAST)
- mDeviceType = D3DDEVTYPE_REF;
- #else
+ const egl::AttributeMap &attributes = display->getAttributeMap();
+ EGLint requestedDeviceType = 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;
- #endif
+ break;
- mDeviceLost = false;
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE:
+ mDeviceType = D3DDEVTYPE_REF;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
+ mDeviceType = D3DDEVTYPE_NULLREF;
+ break;
+
+ default:
+ UNREACHABLE();
+ }
mMaskedClearSavedState = NULL;
@@ -140,20 +140,21 @@ Renderer9::~Renderer9()
if (mDevice)
{
// If the device is lost, reset it first to prevent leaving the driver in an unstable state
- if (testDeviceLost(false))
+ if (testDeviceLost())
{
resetDevice();
}
}
release();
+
+ gl::UninitializeDebugAnnotations();
}
void Renderer9::release()
{
RendererD3D::cleanup();
- releaseShaderCompiler();
releaseDeviceResources();
SafeRelease(mDevice);
@@ -178,19 +179,21 @@ Renderer9 *Renderer9::makeRenderer9(Renderer *renderer)
return static_cast<Renderer9*>(renderer);
}
-EGLint Renderer9::initialize()
+egl::Error Renderer9::initialize()
{
if (!mCompiler.initialize())
{
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D9_INIT_COMPILER_ERROR,
+ "Compiler failed to initialize.");
}
+ TRACE_EVENT0("gpu", "GetModuleHandle_d3d9");
mD3d9Module = GetModuleHandle(TEXT("d3d9.dll"));
if (mD3d9Module == NULL)
{
- ERR("No D3D9 module found - aborting!\n");
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED, D3D9_INIT_MISSING_DEP, "No D3D9 module found.");
}
typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
@@ -201,22 +204,23 @@ EGLint Renderer9::initialize()
// 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)))
{
+ TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface");
ASSERT(mD3d9Ex);
mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
ASSERT(mD3d9);
}
else
{
+ TRACE_EVENT0("gpu", "Direct3DCreate9");
mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
}
if (!mD3d9)
{
- ERR("Could not create D3D9 device - aborting!\n");
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED, D3D9_INIT_MISSING_DEP, "Could not create D3D9 device.");
}
- if (mDc != NULL)
+ if (mDisplay->getNativeDisplayId() != nullptr)
{
// UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to
}
@@ -225,6 +229,7 @@ EGLint Renderer9::initialize()
// Give up on getting device caps after about one second.
{
+ TRACE_EVENT0("gpu", "GetDeviceCaps");
for (int i = 0; i < 10; ++i)
{
result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
@@ -238,99 +243,83 @@ EGLint Renderer9::initialize()
}
else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from
{
- ERR("failed to get device caps (0x%x)\n", result);
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D9_INIT_OTHER_ERROR,
+ "Failed to get device caps: Error code 0x%x\n", result);
}
}
}
- if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
+#if ANGLE_SUPPORT_SHADER_MODEL_2
+ size_t minShaderModel = 2;
+#else
+ size_t minShaderModel = 3;
+#endif
+
+ if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(minShaderModel, 0))
{
- ERR("Renderer does not support PS 2.0. aborting!\n");
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D9_INIT_UNSUPPORTED_VERSION,
+ "Renderer does not support PS %u.%u.aborting!", minShaderModel, 0);
}
// 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)
{
- ERR("Renderer does not support stretctrect from textures!\n");
- return EGL_NOT_INITIALIZED;
+ return egl::Error(EGL_NOT_INITIALIZED,
+ D3D9_INIT_UNSUPPORTED_STRETCHRECT,
+ "Renderer does not support StretctRect from textures.");
}
{
+ TRACE_EVENT0("gpu", "GetAdapterIdentifier");
mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier);
}
- mMinSwapInterval = 4;
- mMaxSwapInterval = 0;
-
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE)
- {
- mMinSwapInterval = std::min(mMinSwapInterval, 0);
- mMaxSwapInterval = std::max(mMaxSwapInterval, 0);
- }
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE)
- {
- mMinSwapInterval = std::min(mMinSwapInterval, 1);
- mMaxSwapInterval = std::max(mMaxSwapInterval, 1);
- }
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)
- {
- mMinSwapInterval = std::min(mMinSwapInterval, 2);
- mMaxSwapInterval = std::max(mMaxSwapInterval, 2);
- }
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE)
- {
- mMinSwapInterval = std::min(mMinSwapInterval, 3);
- mMaxSwapInterval = std::max(mMaxSwapInterval, 3);
- }
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR)
- {
- mMinSwapInterval = std::min(mMinSwapInterval, 4);
- mMaxSwapInterval = std::max(mMaxSwapInterval, 4);
- }
-
static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
static const TCHAR className[] = TEXT("STATIC");
{
+ TRACE_EVENT0("gpu", "CreateWindowEx");
mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
}
D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
- DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
-
- static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED");
- if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1"))
- behaviorFlags |= D3DCREATE_MULTITHREADED;
+ DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED;
{
+ TRACE_EVENT0("gpu", "D3d9_CreateDevice");
result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
}
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
{
- return EGL_BAD_ALLOC;
+ return egl::Error(EGL_BAD_ALLOC, D3D9_INIT_OUT_OF_MEMORY,
+ "CreateDevice failed: device lost of out of memory");
}
if (FAILED(result))
{
+ TRACE_EVENT0("gpu", "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_BAD_ALLOC;
+ return egl::Error(EGL_BAD_ALLOC, D3D9_INIT_OUT_OF_MEMORY,
+ "CreateDevice2 failed: device lost, not available, or of out of memory");
}
}
if (mD3d9Ex)
{
+ TRACE_EVENT0("gpu", "mDevice_QueryInterface");
result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**)&mDeviceEx);
ASSERT(SUCCEEDED(result));
}
{
+ TRACE_EVENT0("gpu", "ShaderCache initialize");
mVertexShaderCache.initialize(mDevice);
mPixelShaderCache.initialize(mDevice);
}
@@ -347,7 +336,7 @@ EGLint Renderer9::initialize()
initializeDevice();
- return EGL_SUCCESS;
+ return egl::Error(EGL_SUCCESS);
}
// do any one-time device initialization
@@ -389,7 +378,7 @@ void Renderer9::initializeDevice()
ASSERT(!mVertexDataManager && !mIndexDataManager);
mVertexDataManager = new VertexDataManager(this);
- mIndexDataManager = new IndexDataManager(this);
+ mIndexDataManager = new IndexDataManager(this, getRendererClass());
}
D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters()
@@ -414,47 +403,124 @@ D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters()
return presentParameters;
}
-int Renderer9::generateConfigs(ConfigDesc **configDescList)
+egl::ConfigSet Renderer9::generateConfigs() const
{
+ 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 = getRendererCaps();
+ const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps();
+
D3DDISPLAYMODE currentDisplayMode;
mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
- unsigned int numRenderFormats = ArraySize(RenderTargetFormats);
- unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
- (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
- int numConfigs = 0;
+ // 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);
+ }
- for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
+ egl::ConfigSet configs;
+ for (size_t formatIndex = 0; formatIndex < ArraySize(colorBufferFormats); formatIndex++)
{
- const d3d9::D3DFormat &renderTargetFormatInfo = d3d9::GetD3DFormatInfo(RenderTargetFormats[formatIndex]);
- const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat);
- if (renderTargetFormatCaps.renderable)
+ GLenum colorBufferInternalFormat = colorBufferFormats[formatIndex];
+ const gl::TextureCaps &colorBufferFormatCaps = rendererTextureCaps.get(colorBufferInternalFormat);
+ if (colorBufferFormatCaps.renderable)
{
- for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
+ for (size_t depthStencilIndex = 0; depthStencilIndex < ArraySize(depthStencilBufferFormats); depthStencilIndex++)
{
- const d3d9::D3DFormat &depthStencilFormatInfo = d3d9::GetD3DFormatInfo(DepthStencilFormats[depthStencilIndex]);
- const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat);
- if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == D3DFMT_UNKNOWN)
+ GLenum depthStencilBufferInternalFormat = depthStencilBufferFormats[depthStencilIndex];
+ const gl::TextureCaps &depthStencilBufferFormatCaps = rendererTextureCaps.get(depthStencilBufferInternalFormat);
+ if (depthStencilBufferFormatCaps.renderable || depthStencilBufferInternalFormat == GL_NONE)
{
- ConfigDesc newConfig;
- newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat;
- newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat;
- newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
- newConfig.fastConfig = (currentDisplayMode.Format == RenderTargetFormats[formatIndex]);
- newConfig.es3Capable = false;
-
- (*configDescList)[numConfigs++] = newConfig;
+ const gl::InternalFormat &colorBufferFormatInfo = gl::GetInternalFormatInfo(colorBufferInternalFormat);
+ const gl::InternalFormat &depthStencilBufferFormatInfo = gl::GetInternalFormatInfo(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;
+
+ configs.add(config);
}
}
}
}
- return numConfigs;
-}
-
-void Renderer9::deleteConfigs(ConfigDesc *configDescList)
-{
- delete [] (configDescList);
+ ASSERT(configs.size() > 0);
+ return configs;
}
void Renderer9::startScene()
@@ -481,7 +547,39 @@ void Renderer9::endScene()
}
}
-gl::Error Renderer9::sync(bool block)
+gl::Error Renderer9::flush()
+{
+ IDirect3DQuery9* query = NULL;
+ gl::Error error = allocateEventQuery(&query);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ HRESULT result = query->Issue(D3DISSUE_END);
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to issue event query, result: 0x%X.", result);
+ }
+
+ // Grab the query data once
+ result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
+ freeEventQuery(query);
+ if (FAILED(result))
+ {
+ if (d3d9::isDeviceLostError(result))
+ {
+ notifyDeviceLost();
+ }
+
+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result);
+ }
+
+ return gl::Error(GL_NO_ERROR);
+}
+
+gl::Error Renderer9::finish()
{
IDirect3DQuery9* query = NULL;
gl::Error error = allocateEventQuery(&query);
@@ -497,7 +595,7 @@ gl::Error Renderer9::sync(bool block)
return gl::Error(GL_OUT_OF_MEMORY, "Failed to issue event query, result: 0x%X.", result);
}
- // Grab the query data once in blocking and non-blocking case
+ // Grab the query data once
result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
if (FAILED(result))
{
@@ -510,8 +608,8 @@ gl::Error Renderer9::sync(bool block)
return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result);
}
- // If blocking, loop until the query completes
- while (block && result == S_FALSE)
+ // Loop until the query completes
+ while (result == S_FALSE)
{
// Keep polling, but allow other threads to do something useful first
Sleep(0);
@@ -521,7 +619,7 @@ gl::Error Renderer9::sync(bool block)
// 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
- if (result == S_FALSE && testDeviceLost(false))
+ if (result == S_FALSE && testDeviceLost())
{
result = D3DERR_DEVICELOST;
}
@@ -544,7 +642,7 @@ gl::Error Renderer9::sync(bool block)
return gl::Error(GL_NO_ERROR);
}
-SwapChain *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
{
return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
}
@@ -651,7 +749,7 @@ bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const
return false;
}
-gl::Error Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+gl::Error Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, 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.
@@ -677,8 +775,19 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Textur
int d3dSampler = index + d3dSamplerOffset;
// Make sure to add the level offset for our tiny compressed texture workaround
- TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
- DWORD baseLevel = samplerState.baseLevel + textureD3D->getNativeTexture()->getTopLevel();
+ TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
+
+ TextureStorage *storage = nullptr;
+ gl::Error error = textureD3D->getNativeTexture(&storage);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ // Storage should exist, texture should be complete
+ ASSERT(storage);
+
+ DWORD baseLevel = samplerState.baseLevel + storage->getTopLevel();
mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS));
mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT));
@@ -713,19 +822,25 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te
if (texture)
{
- TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
+ TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
- TextureStorage *texStorage = textureImpl->getNativeTexture();
- if (texStorage)
+ TextureStorage *texStorage = nullptr;
+ gl::Error error = textureImpl->getNativeTexture(&texStorage);
+ if (error.isError())
{
- TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage);
+ return error;
+ }
- gl::Error error = storage9->getBaseTexture(&d3dTexture);
- if (error.isError())
- {
- return error;
- }
+ // Texture should be complete and have a storage
+ ASSERT(texStorage);
+
+ TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage);
+ error = storage9->getBaseTexture(&d3dTexture);
+ if (error.isError())
+ {
+ return error;
}
+
// 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 != NULL);
@@ -745,7 +860,9 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::setUniformBuffers(const gl::Buffer* /*vertexUniformBuffers*/[], const gl::Buffer* /*fragmentUniformBuffers*/[])
+gl::Error Renderer9::setUniformBuffers(const gl::Data &/*data*/,
+ const GLint /*vertexUniformBuffers*/[],
+ const GLint /*fragmentUniformBuffers*/[])
{
// No effect in ES2/D3D9
return gl::Error(GL_NO_ERROR);
@@ -850,7 +967,7 @@ gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer, const gl:
GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE;
// Set the color mask
- bool zeroColorMaskAllowed = getAdapterVendor() != VENDOR_ID_AMD;
+ bool zeroColorMaskAllowed = getVendorId() != VENDOR_ID_AMD;
// 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
@@ -1096,7 +1213,7 @@ void Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zF
mForceSetViewport = false;
}
-bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count)
+bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize)
{
switch (mode)
{
@@ -1137,7 +1254,7 @@ bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count)
}
-gl::Error Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, gl::FramebufferAttachment **outColorBuffer)
+gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbuffer, const gl::FramebufferAttachment **outColorBuffer)
{
ASSERT(depthbuffer);
@@ -1158,7 +1275,7 @@ gl::Error Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer,
}
gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0);
- gl::Error error = nullRenderbuffer->setStorage(width, height, GL_NONE, 0);
+ gl::Error error = nullRenderbuffer->setStorage(GL_NONE, width, height);
if (error.isError())
{
SafeDelete(nullRenderbuffer);
@@ -1187,28 +1304,31 @@ gl::Error Renderer9::getNullColorbuffer(gl::FramebufferAttachment *depthbuffer,
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
+gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer)
{
// 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.
- gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(0);
- if (!attachment)
+ if (!colorBuffer)
{
- gl::Error error = getNullColorbuffer(framebuffer->getDepthbuffer(), &attachment);
+ gl::Error error = getNullColorbuffer(depthStencilBuffer, &colorBuffer);
if (error.isError())
{
return error;
}
}
- ASSERT(attachment);
+ ASSERT(colorBuffer);
+
+ size_t renderTargetWidth = 0;
+ size_t renderTargetHeight = 0;
+ D3DFORMAT renderTargetFormat = D3DFMT_UNKNOWN;
bool renderTargetChanged = false;
- unsigned int renderTargetSerial = GetAttachmentSerial(attachment);
+ unsigned int renderTargetSerial = GetAttachmentSerial(colorBuffer);
if (renderTargetSerial != mAppliedRenderTargetSerial)
{
// Apply the render target on the device
RenderTarget9 *renderTarget = NULL;
- gl::Error error = d3d9::GetAttachmentRenderTarget(attachment, &renderTarget);
+ gl::Error error = d3d9::GetAttachmentRenderTarget(colorBuffer, &renderTarget);
if (error.isError())
{
return error;
@@ -1221,35 +1341,25 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
mDevice->SetRenderTarget(0, renderTargetSurface);
SafeRelease(renderTargetSurface);
+ renderTargetWidth = renderTarget->getWidth();
+ renderTargetHeight = renderTarget->getHeight();
+ renderTargetFormat = renderTarget->getD3DFormat();
+
mAppliedRenderTargetSerial = renderTargetSerial;
renderTargetChanged = true;
}
- gl::FramebufferAttachment *depthStencil = framebuffer->getDepthbuffer();
- unsigned int depthbufferSerial = 0;
- unsigned int stencilbufferSerial = 0;
- if (depthStencil)
- {
- depthbufferSerial = GetAttachmentSerial(depthStencil);
- }
- else if (framebuffer->getStencilbuffer())
- {
- depthStencil = framebuffer->getStencilbuffer();
- stencilbufferSerial = GetAttachmentSerial(depthStencil);
- }
-
- if (depthbufferSerial != mAppliedDepthbufferSerial ||
- stencilbufferSerial != mAppliedStencilbufferSerial ||
- !mDepthStencilInitialized)
+ unsigned int depthStencilSerial = (depthStencilBuffer != nullptr) ? GetAttachmentSerial(depthStencilBuffer) : 0;
+ if (depthStencilSerial != mAppliedDepthStencilSerial || !mDepthStencilInitialized)
{
unsigned int depthSize = 0;
unsigned int stencilSize = 0;
// Apply the depth stencil on the device
- if (depthStencil)
+ if (depthStencilBuffer)
{
RenderTarget9 *depthStencilRenderTarget = NULL;
- gl::Error error = d3d9::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget);
+ gl::Error error = d3d9::GetAttachmentRenderTarget(depthStencilBuffer, &depthStencilRenderTarget);
if (error.isError())
{
return error;
@@ -1262,8 +1372,8 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
mDevice->SetDepthStencilSurface(depthStencilSurface);
SafeRelease(depthStencilSurface);
- depthSize = depthStencil->getDepthSize();
- stencilSize = depthStencil->getStencilSize();
+ depthSize = depthStencilBuffer->getDepthSize();
+ stencilSize = depthStencilBuffer->getStencilSize();
}
else
{
@@ -1282,8 +1392,7 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
mForceSetDepthStencilState = true;
}
- mAppliedDepthbufferSerial = depthbufferSerial;
- mAppliedStencilbufferSerial = stencilbufferSerial;
+ mAppliedDepthStencilSerial = depthStencilSerial;
mDepthStencilInitialized = true;
}
@@ -1293,16 +1402,21 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
mForceSetViewport = true;
mForceSetBlendState = true;
- mRenderTargetDesc.width = attachment->getWidth();
- mRenderTargetDesc.height = attachment->getHeight();
- mRenderTargetDesc.format = attachment->getActualFormat();
+ mRenderTargetDesc.width = renderTargetWidth;
+ mRenderTargetDesc.height = renderTargetHeight;
+ mRenderTargetDesc.format = renderTargetFormat;
mRenderTargetDescInitialized = true;
}
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances)
+gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer)
+{
+ return applyRenderTarget(framebuffer->getColorbuffer(0), framebuffer->getDepthOrStencilbuffer());
+}
+
+gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances);
@@ -1311,7 +1425,7 @@ gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLint first, GLsi
return error;
}
- return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getCurrentProgramBinary(), instances, &mRepeatDraw);
+ return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getProgram(), instances, &mRepeatDraw);
}
// Applies the indices and element array bindings to the Direct3D 9 device
@@ -1339,12 +1453,12 @@ gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *element
void Renderer9::applyTransformFeedbackBuffers(const gl::State& state)
{
- UNREACHABLE();
+ ASSERT(!state.isTransformFeedbackActiveUnpaused());
}
-gl::Error Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive)
+gl::Error Renderer9::drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize)
{
- ASSERT(!transformFeedbackActive);
+ ASSERT(!data.state->isTransformFeedbackActiveUnpaused());
startScene();
@@ -1414,7 +1528,7 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi
// Get the raw indices for an indexed draw
if (type != GL_NONE && elementArrayBuffer)
{
- BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
+ BufferD3D *storage = GetImplAs<BufferD3D>(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
const uint8_t *bufferData = NULL;
gl::Error error = storage->getData(&bufferData);
@@ -1616,7 +1730,7 @@ gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid
if (elementArrayBuffer)
{
- BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
+ BufferD3D *storage = GetImplAs<BufferD3D>(elementArrayBuffer);
intptr_t offset = reinterpret_cast<intptr_t>(indices);
const uint8_t *bufferData = NULL;
@@ -1710,22 +1824,22 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou
return gl::Error(GL_NO_ERROR);
}
-gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+gl::Error Renderer9::applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive)
{
ASSERT(!transformFeedbackActive);
ASSERT(!rasterizerDiscard);
- ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
- ShaderExecutable *vertexExe = NULL;
- gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe);
+ ShaderExecutableD3D *vertexExe = NULL;
+ gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr);
if (error.isError())
{
return error;
}
- ShaderExecutable *pixelExe = NULL;
+ ShaderExecutableD3D *pixelExe = NULL;
error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe);
if (error.isError())
{
@@ -1752,7 +1866,7 @@ gl::Error Renderer9::applyShaders(gl::ProgramBinary *programBinary, const gl::Ve
// 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 = programBinary->getSerial();
+ unsigned int programSerial = programD3D->getSerial();
if (programSerial != mAppliedProgramSerial)
{
programD3D->dirtyAllUniforms();
@@ -1862,7 +1976,9 @@ void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v
applyUniformnfv(targetUniform, (GLfloat*)vector);
}
-gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer)
+gl::Error Renderer9::clear(const ClearParameters &clearParams,
+ const gl::FramebufferAttachment *colorBuffer,
+ const gl::FramebufferAttachment *depthStencilBuffer)
{
if (clearParams.colorClearType != GL_FLOAT)
{
@@ -1886,10 +2002,20 @@ gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Fra
DWORD stencil = clearParams.stencilClearValue & 0x000000FF;
unsigned int stencilUnmasked = 0x0;
- if (clearParams.clearStencil && frameBuffer->hasStencil())
+ if (clearParams.clearStencil && depthStencilBuffer->getStencilSize() > 0)
{
- unsigned int stencilSize = gl::GetInternalFormatInfo((frameBuffer->getStencilbuffer()->getActualFormat())).stencilBits;
- stencilUnmasked = (0x1 << stencilSize) - 1;
+ RenderTargetD3D *stencilRenderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(depthStencilBuffer, &stencilRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ RenderTarget9 *stencilRenderTarget9 = RenderTarget9::makeRenderTarget9(stencilRenderTarget);
+ ASSERT(stencilRenderTarget9);
+
+ const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(stencilRenderTarget9->getD3DFormat());
+ stencilUnmasked = (0x1 << d3dFormatInfo.stencilBits) - 1;
}
const bool needMaskedStencilClear = clearParams.clearStencil &&
@@ -1899,14 +2025,23 @@ gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Fra
D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0);
if (clearColor)
{
- const gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer();
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
- const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
+ RenderTargetD3D *colorRenderTarget = NULL;
+ gl::Error error = GetAttachmentRenderTarget(colorBuffer, &colorRenderTarget);
+ if (error.isError())
+ {
+ return error;
+ }
- color = D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && actualFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha),
- gl::unorm<8>((formatInfo.redBits == 0 && actualFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red),
- gl::unorm<8>((formatInfo.greenBits == 0 && actualFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green),
- gl::unorm<8>((formatInfo.blueBits == 0 && actualFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue));
+ RenderTarget9 *colorRenderTarget9 = RenderTarget9::makeRenderTarget9(colorRenderTarget);
+ ASSERT(colorRenderTarget9);
+
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(colorBuffer->getInternalFormat());
+ const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(colorRenderTarget9->getD3DFormat());
+
+ color = D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && d3dFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha),
+ gl::unorm<8>((formatInfo.redBits == 0 && d3dFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red),
+ gl::unorm<8>((formatInfo.greenBits == 0 && d3dFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green),
+ gl::unorm<8>((formatInfo.blueBits == 0 && d3dFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue));
if ((formatInfo.redBits > 0 && !clearParams.colorMaskRed) ||
(formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) ||
@@ -2082,8 +2217,7 @@ gl::Error Renderer9::clear(const gl::ClearParameters &clearParams, const gl::Fra
void Renderer9::markAllStateDirty()
{
mAppliedRenderTargetSerial = 0;
- mAppliedDepthbufferSerial = 0;
- mAppliedStencilbufferSerial = 0;
+ mAppliedDepthStencilSerial = 0;
mDepthStencilInitialized = false;
mRenderTargetDescInitialized = false;
@@ -2141,19 +2275,8 @@ void Renderer9::releaseDeviceResources()
}
}
-void Renderer9::notifyDeviceLost()
-{
- mDeviceLost = true;
- mDisplay->notifyDeviceLost();
-}
-
-bool Renderer9::isDeviceLost()
-{
- return mDeviceLost;
-}
-
// set notify to true to broadcast a message to all contexts of the device loss
-bool Renderer9::testDeviceLost(bool notify)
+bool Renderer9::testDeviceLost()
{
HRESULT status = getDeviceStatusCode();
bool isLost = FAILED(status);
@@ -2166,10 +2289,6 @@ bool Renderer9::testDeviceLost(bool notify)
// Note that we don't want to clear the device loss status here
// -- this needs to be done by resetDevice
mDeviceLost = true;
- if (notify)
- {
- notifyDeviceLost();
- }
}
return isLost;
@@ -2217,7 +2336,7 @@ bool Renderer9::resetDevice()
D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
HRESULT result = D3D_OK;
- bool lost = testDeviceLost(false);
+ bool lost = testDeviceLost();
bool removedDevice = (getDeviceStatusCode() == D3DERR_DEVICEREMOVED);
// Device Removed is a feature which is only present with D3D9Ex
@@ -2237,7 +2356,7 @@ bool Renderer9::resetDevice()
{
Sleep(500); // Give the graphics driver some CPU time
result = mDeviceEx->ResetEx(&presentParameters, NULL);
- lost = testDeviceLost(false);
+ lost = testDeviceLost();
}
else
{
@@ -2252,7 +2371,7 @@ bool Renderer9::resetDevice()
{
result = mDevice->Reset(&presentParameters);
}
- lost = testDeviceLost(false);
+ lost = testDeviceLost();
}
}
@@ -2311,12 +2430,12 @@ bool Renderer9::resetRemovedDevice()
// 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() == EGL_SUCCESS);
+ return !initialize().isError();
}
-DWORD Renderer9::getAdapterVendor() const
+VendorID Renderer9::getVendorId() const
{
- return mAdapterIdentifier.VendorId;
+ return static_cast<VendorID>(mAdapterIdentifier.VendorId);
}
std::string Renderer9::getRendererDescription() const
@@ -2367,7 +2486,7 @@ unsigned int Renderer9::getReservedFragmentUniformBuffers() const
bool Renderer9::getShareHandleSupport() const
{
// PIX doesn't seem to support using share handles, so disable them.
- return (mD3d9Ex != NULL) && !gl::perfActive();
+ return (mD3d9Ex != NULL) && !gl::DebugAnnotationsActive();
}
bool Renderer9::getPostSubBufferSupport() const
@@ -2380,19 +2499,19 @@ int Renderer9::getMajorShaderModel() const
return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion);
}
-DWORD Renderer9::getCapsDeclTypes() const
+int Renderer9::getMinorShaderModel() const
{
- return mDeviceCaps.DeclTypes;
+ return D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion);
}
-int Renderer9::getMinSwapInterval() const
+std::string Renderer9::getShaderModelSuffix() const
{
- return mMinSwapInterval;
+ return "";
}
-int Renderer9::getMaxSwapInterval() const
+DWORD Renderer9::getCapsDeclTypes() const
{
- return mMaxSwapInterval;
+ return mDeviceCaps.DeclTypes;
}
D3DPOOL Renderer9::getBufferPool(DWORD usage) const
@@ -2412,8 +2531,8 @@ D3DPOOL Renderer9::getBufferPool(DWORD usage) const
return D3DPOOL_DEFAULT;
}
-gl::Error Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level)
+gl::Error Renderer9::copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level)
{
RECT rect;
rect.left = sourceRect.x;
@@ -2421,11 +2540,11 @@ gl::Error Renderer9::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectang
rect.right = sourceRect.x + sourceRect.width;
rect.bottom = sourceRect.y + sourceRect.height;
- return mBlit->copy2D(framebuffer, rect, destFormat, xoffset, yoffset, storage, level);
+ return mBlit->copy2D(framebuffer, rect, destFormat, destOffset, storage, level);
}
-gl::Error Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level)
+gl::Error Renderer9::copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level)
{
RECT rect;
rect.left = sourceRect.x;
@@ -2433,385 +2552,26 @@ gl::Error Renderer9::copyImageCube(gl::Framebuffer *framebuffer, const gl::Recta
rect.right = sourceRect.x + sourceRect.width;
rect.bottom = sourceRect.y + sourceRect.height;
- return mBlit->copyCube(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level);
+ return mBlit->copyCube(framebuffer, rect, destFormat, destOffset, storage, target, level);
}
-gl::Error Renderer9::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer9::copyImage3D(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.
UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION);
}
-gl::Error Renderer9::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level)
+gl::Error Renderer9::copyImage2DArray(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.
UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION);
}
-gl::Error Renderer9::blitRect(const gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect,
- const gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget,
- bool blitDepth, bool blitStencil, GLenum filter)
-{
- ASSERT(filter == GL_NEAREST);
-
- endScene();
-
- if (blitRenderTarget)
- {
- gl::FramebufferAttachment *readBuffer = readFramebuffer->getColorbuffer(0);
- ASSERT(readBuffer);
-
- RenderTarget9 *readRenderTarget = NULL;
- gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
- if (error.isError())
- {
- return error;
- }
- ASSERT(readRenderTarget);
-
- gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getColorbuffer(0);
- ASSERT(drawBuffer);
-
- RenderTarget9 *drawRenderTarget = NULL;
- error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
- if (error.isError())
- {
- return error;
- }
- 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 = readRect.x;
- srcRect.right = readRect.x + readRect.width;
- srcRect.top = readRect.y;
- srcRect.bottom = readRect.y + readRect.height;
-
- RECT dstRect;
- dstRect.left = drawRect.x;
- dstRect.right = drawRect.x + drawRect.width;
- dstRect.top = drawRect.y;
- dstRect.bottom = drawRect.y + drawRect.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 = mDevice->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE);
-
- SafeRelease(readSurface);
- SafeRelease(drawSurface);
-
- if (FAILED(result))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
- }
- }
-
- if (blitDepth || blitStencil)
- {
- gl::FramebufferAttachment *readBuffer = readFramebuffer->getDepthOrStencilbuffer();
- ASSERT(readBuffer);
-
- RenderTarget9 *readDepthStencil = NULL;
- gl::Error error = d3d9::GetAttachmentRenderTarget(readBuffer, &readDepthStencil);
- if (error.isError())
- {
- return error;
- }
- ASSERT(readDepthStencil);
-
- gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer();
- ASSERT(drawBuffer);
-
- RenderTarget9 *drawDepthStencil = NULL;
- error = d3d9::GetAttachmentRenderTarget(drawBuffer, &drawDepthStencil);
- if (error.isError())
- {
- return error;
- }
- 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 = mDevice->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE);
-
- SafeRelease(readSurface);
- SafeRelease(drawSurface);
-
- if (FAILED(result))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result);
- }
- }
-
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error Renderer9::readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
- GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
-{
- ASSERT(pack.pixelBuffer.get() == NULL);
-
- gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
- ASSERT(colorbuffer);
-
- RenderTarget9 *renderTarget = NULL;
- gl::Error error = d3d9::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
- if (error.isError())
- {
- return error;
- }
- ASSERT(renderTarget);
-
- IDirect3DSurface9 *surface = renderTarget->getSurface();
- ASSERT(surface);
-
- D3DSURFACE_DESC desc;
- surface->GetDesc(&desc);
-
- if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
- {
- UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target
- SafeRelease(surface);
- return gl::Error(GL_OUT_OF_MEMORY, "ReadPixels is unimplemented for multisampled framebuffer attachments.");
- }
-
- HRESULT result;
- IDirect3DSurface9 *systemSurface = NULL;
- bool directToPixels = !pack.reverseRowOrder && pack.alignment <= 4 && getShareHandleSupport() &&
- x == 0 && y == 0 && UINT(width) == desc.Width && UINT(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 = mDevice->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 = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
- D3DPOOL_SYSTEMMEM, &systemSurface, NULL);
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- SafeRelease(surface);
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for ReadPixels.");
- }
- }
-
- result = mDevice->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))
- {
- notifyDeviceLost();
- }
- else
- {
- UNREACHABLE();
- }
-
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to read internal render target data.");
- }
-
- if (directToPixels)
- {
- SafeRelease(systemSurface);
- return gl::Error(GL_NO_ERROR);
- }
-
- RECT rect;
- rect.left = gl::clamp(x, 0L, static_cast<LONG>(desc.Width));
- rect.top = gl::clamp(y, 0L, static_cast<LONG>(desc.Height));
- rect.right = gl::clamp(x + width, 0L, static_cast<LONG>(desc.Width));
- rect.bottom = gl::clamp(y + height, 0L, static_cast<LONG>(desc.Height));
-
- D3DLOCKED_RECT lock;
- result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY);
-
- if (FAILED(result))
- {
- UNREACHABLE();
- SafeRelease(systemSurface);
-
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal render target.");
- }
-
- uint8_t *source;
- int inputPitch;
- if (pack.reverseRowOrder)
- {
- source = reinterpret_cast<uint8_t*>(lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1);
- inputPitch = -lock.Pitch;
- }
- else
- {
- source = reinterpret_cast<uint8_t*>(lock.pBits);
- inputPitch = lock.Pitch;
- }
-
- const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
- const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3dFormatInfo.internalFormat);
- if (sourceFormatInfo.format == format && sourceFormatInfo.type == type)
- {
- // Direct copy possible
- for (int y = 0; y < rect.bottom - rect.top; y++)
- {
- memcpy(pixels + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourceFormatInfo.pixelBytes);
- }
- }
- else
- {
- const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
- ColorCopyFunction fastCopyFunc = sourceD3DFormatInfo.getFastCopyFunction(format, type);
-
- const gl::FormatType &destFormatTypeInfo = gl::GetFormatTypeInfo(format, type);
- const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat);
-
- if (fastCopyFunc)
- {
- // Fast copy is possible through some special function
- for (int y = 0; y < rect.bottom - rect.top; y++)
- {
- for (int x = 0; x < rect.right - rect.left; x++)
- {
- uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes;
- const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
-
- fastCopyFunc(src, dest);
- }
- }
- }
- else
- {
- uint8_t temp[sizeof(gl::ColorF)];
- for (int y = 0; y < rect.bottom - rect.top; y++)
- {
- for (int x = 0; x < rect.right - rect.left; x++)
- {
- uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes;
- const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
-
- // readFunc and writeFunc will be using the same type of color, CopyTexImage
- // will not allow the copy otherwise.
- sourceD3DFormatInfo.colorReadFunction(src, temp);
- destFormatTypeInfo.colorWriteFunction(temp, dest);
- }
- }
- }
- }
-
- systemSurface->UnlockRect();
- SafeRelease(systemSurface);
-
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error Renderer9::createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT)
-{
- SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain);
- *outRT = new SurfaceRenderTarget9(swapChain9, depth);
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT)
+gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT)
{
const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format);
@@ -2862,24 +2622,34 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL
return gl::Error(GL_NO_ERROR);
}
-ShaderImpl *Renderer9::createShader(const gl::Data &data, GLenum type)
+FramebufferImpl *Renderer9::createDefaultFramebuffer(const gl::Framebuffer::Data &data)
{
- return new ShaderD3D(data, type, this);
+ return createFramebuffer(data);
}
-ProgramImpl *Renderer9::createProgram()
+FramebufferImpl *Renderer9::createFramebuffer(const gl::Framebuffer::Data &data)
{
- return new ProgramD3D(this);
+ return new Framebuffer9(data, this);
+}
+
+CompilerImpl *Renderer9::createCompiler(const gl::Data &data)
+{
+ return new CompilerD3D(data, SH_HLSL9_OUTPUT);
}
-void Renderer9::releaseShaderCompiler()
+ShaderImpl *Renderer9::createShader(GLenum type)
{
- ShaderD3D::releaseCompiler();
+ return new ShaderD3D(type);
+}
+
+ProgramImpl *Renderer9::createProgram()
+{
+ return new ProgramD3D(this);
}
gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, ShaderExecutable **outExecutable)
+ bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable)
{
// Transform feedback is not supported in ES2 or D3D9
ASSERT(transformFeedbackVaryings.size() == 0);
@@ -2918,8 +2688,8 @@ gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderT
gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround,
- ShaderExecutable **outExectuable)
+ bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds,
+ ShaderExecutableD3D **outExectuable)
{
// Transform feedback is not supported in ES2 or D3D9
ASSERT(transformFeedbackVaryings.size() == 0);
@@ -2943,17 +2713,16 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string
UINT flags = ANGLE_COMPILE_OPTIMIZATION_LEVEL;
- if (workaround == ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION)
+ if (workarounds.skipOptimization)
{
flags = D3DCOMPILE_SKIP_OPTIMIZATION;
}
- else if (workaround == ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION)
+ else if (workarounds.useMaxOptimization)
{
flags = D3DCOMPILE_OPTIMIZATION_LEVEL3;
}
- else ASSERT(workaround == ANGLE_D3D_WORKAROUND_NONE);
- if (gl::perfActive())
+ if (gl::DebugAnnotationsActive())
{
#ifndef NDEBUG
flags = D3DCOMPILE_SKIP_OPTIMIZATION;
@@ -3002,9 +2771,9 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string
return gl::Error(GL_NO_ERROR);
}
-UniformStorage *Renderer9::createUniformStorage(size_t storageSize)
+UniformStorageD3D *Renderer9::createUniformStorage(size_t storageSize)
{
- return new UniformStorage(storageSize);
+ return new UniformStorageD3D(storageSize);
}
gl::Error Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
@@ -3065,32 +2834,32 @@ gl::Error Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurfac
return gl::Error(GL_NO_ERROR);
}
-Image *Renderer9::createImage()
+ImageD3D *Renderer9::createImage()
{
- return new Image9();
+ return new Image9(this);
}
-gl::Error Renderer9::generateMipmap(Image *dest, Image *src)
+gl::Error Renderer9::generateMipmap(ImageD3D *dest, ImageD3D *src)
{
Image9 *src9 = Image9::makeImage9(src);
Image9 *dst9 = Image9::makeImage9(dest);
return Image9::generateMipmap(dst9, src9);
}
-TextureStorage *Renderer9::createTextureStorage2D(SwapChain *swapChain)
+TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain)
{
SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain);
return new TextureStorage9_2D(this, swapChain9);
}
-TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
+TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly)
{
return new TextureStorage9_2D(this, internalformat, renderTarget, width, height, levels);
}
-TextureStorage *Renderer9::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels)
+TextureStorage *Renderer9::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly)
{
- return new TextureStorage9_Cube(this, internalformat, renderTarget, size, levels);
+ return new TextureStorage9_Cube(this, internalformat, renderTarget, size, levels, hintLevelZeroOnly);
}
TextureStorage *Renderer9::createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels)
@@ -3127,13 +2896,6 @@ RenderbufferImpl *Renderer9::createRenderbuffer()
return renderbuffer;
}
-RenderbufferImpl *Renderer9::createRenderbuffer(SwapChain *swapChain, bool depth)
-{
- RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
- renderbuffer->setStorage(swapChain, depth);
- return renderbuffer;
-}
-
bool Renderer9::getLUID(LUID *adapterLuid) const
{
adapterLuid->HighPart = 0;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
index 10d2fb11e8..19bea3eb35 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
@@ -6,16 +6,17 @@
// Renderer9.h: Defines a back-end specific class for the D3D9 renderer.
-#ifndef LIBGLESV2_RENDERER_RENDERER9_H_
-#define LIBGLESV2_RENDERER_RENDERER9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_
#include "common/angleutils.h"
#include "common/mathutil.h"
-#include "libGLESv2/renderer/d3d/d3d9/ShaderCache.h"
-#include "libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h"
-#include "libGLESv2/renderer/d3d/HLSLCompiler.h"
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
-#include "libGLESv2/renderer/RenderTarget.h"
+#include "libANGLE/renderer/d3d/HLSLCompiler.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h"
+#include "libANGLE/renderer/d3d/d3d9/ShaderCache.h"
+#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h"
namespace gl
{
@@ -29,33 +30,54 @@ class AttributeMap;
namespace rx
{
-class VertexDataManager;
+class Blit9;
class IndexDataManager;
class StreamingIndexBufferInterface;
class StaticIndexBufferInterface;
+class VertexDataManager;
+struct ClearParameters;
struct TranslatedAttribute;
-class Blit9;
+
+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
+};
class Renderer9 : public RendererD3D
{
public:
- Renderer9(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes);
+ explicit Renderer9(egl::Display *display);
virtual ~Renderer9();
static Renderer9 *makeRenderer9(Renderer *renderer);
- virtual EGLint initialize();
+ egl::Error initialize() override;
virtual bool resetDevice();
- virtual int generateConfigs(ConfigDesc **configDescList);
- virtual void deleteConfigs(ConfigDesc *configDescList);
+ egl::ConfigSet generateConfigs() const override;
void startScene();
void endScene();
- virtual gl::Error sync(bool block);
+ gl::Error flush() override;
+ gl::Error finish() override;
- virtual SwapChain *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
gl::Error allocateEventQuery(IDirect3DQuery9 **outQuery);
void freeEventQuery(IDirect3DQuery9* query);
@@ -69,7 +91,9 @@ class Renderer9 : public RendererD3D
virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler);
virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture);
- virtual gl::Error setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]);
+ gl::Error setUniformBuffers(const gl::Data &data,
+ const GLint vertexUniformBuffers[],
+ const GLint fragmentUniformBuffers[]) override;
virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState);
gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
@@ -82,30 +106,31 @@ class Renderer9 : public RendererD3D
bool ignoreViewport);
gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override;
- virtual gl::Error applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
+ gl::Error applyRenderTarget(const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer);
+ virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
bool rasterizerDiscard, bool transformFeedbackActive);
virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray);
- virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
- virtual gl::Error applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances);
+ virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize);
+ virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances);
virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
- virtual void applyTransformFeedbackBuffers(const gl::State& state);
+ void applyTransformFeedbackBuffers(const gl::State &state) override;
- virtual gl::Error drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive);
+ gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) override;
virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
- gl::Error clear(const gl::ClearParameters &clearParams, const gl::Framebuffer *frameBuffer) override;
+ gl::Error clear(const ClearParameters &clearParams,
+ const gl::FramebufferAttachment *colorBuffer,
+ const gl::FramebufferAttachment *depthStencilBuffer);
virtual void markAllStateDirty();
// lost device
- void notifyDeviceLost() override;
- bool isDeviceLost() override;
- bool testDeviceLost(bool notify) override;
+ bool testDeviceLost() override;
bool testDeviceResettable() override;
- DWORD getAdapterVendor() const override;
+ VendorID getVendorId() const override;
std::string getRendererDescription() const override;
GUID getAdapterIdentifier() const override;
@@ -119,53 +144,49 @@ class Renderer9 : public RendererD3D
virtual bool getPostSubBufferSupport() const;
virtual int getMajorShaderModel() const;
+ int getMinorShaderModel() const override;
+ std::string getShaderModelSuffix() const override;
+
DWORD getCapsDeclTypes() const;
- virtual int getMinSwapInterval() const;
- virtual int getMaxSwapInterval() const;
// Pixel operations
- virtual gl::Error copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level);
- virtual gl::Error copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level);
- virtual gl::Error copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
- virtual gl::Error copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
- GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level);
-
- gl::Error blitRect(const gl::Framebuffer *readTarget, const gl::Rectangle &readRect,
- const gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
- const gl::Rectangle *scissor, bool blitRenderTarget,
- bool blitDepth, bool blitStencil, GLenum filter) override;
-
- virtual gl::Error readPixels(const gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
- GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels);
+ virtual gl::Error copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level);
+ virtual gl::Error copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level);
+ virtual gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ const gl::Offset &destOffset, TextureStorage *storage, GLint level);
// RenderTarget creation
- virtual gl::Error createRenderTarget(SwapChain *swapChain, bool depth, RenderTarget **outRT);
- virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTarget **outRT);
+ virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT);
+
+ // Framebuffer creation
+ FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override;
+ FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override;
// Shader creation
- virtual ShaderImpl *createShader(const gl::Data &data, GLenum type);
+ virtual CompilerImpl *createCompiler(const gl::Data &data);
+ virtual ShaderImpl *createShader(GLenum type);
virtual ProgramImpl *createProgram();
// Shader operations
- void releaseShaderCompiler() override;
virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, ShaderExecutable **outExecutable);
+ bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable);
virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
- bool separatedOutputBuffers, D3DWorkaroundType workaround,
- ShaderExecutable **outExectuable);
- virtual UniformStorage *createUniformStorage(size_t storageSize);
+ bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds,
+ ShaderExecutableD3D **outExectuable);
+ virtual UniformStorageD3D *createUniformStorage(size_t storageSize);
// Image operations
- virtual Image *createImage();
- gl::Error generateMipmap(Image *dest, Image *source) override;
- virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
- virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels);
- virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels);
+ virtual ImageD3D *createImage();
+ gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override;
+ virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain);
+ virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly);
+ virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels);
@@ -174,7 +195,6 @@ class Renderer9 : public RendererD3D
// Renderbuffer creation
virtual RenderbufferImpl *createRenderbuffer();
- virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth);
// Buffer creation
virtual BufferImpl *createBuffer();
@@ -194,7 +214,7 @@ class Renderer9 : public RendererD3D
// Buffer-to-texture and Texture-to-buffer copies
virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const;
- virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
+ virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea);
// D3D9-renderer specific methods
@@ -202,15 +222,17 @@ class Renderer9 : public RendererD3D
D3DPOOL getTexturePool(DWORD usage) const;
- virtual bool getLUID(LUID *adapterLuid) const;
+ bool getLUID(LUID *adapterLuid) const override;
virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const;
virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const;
gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
- private:
- DISALLOW_COPY_AND_ASSIGN(Renderer9);
+ RendererClass getRendererClass() const override { return RENDERER_D3D9; }
+
+ D3DDEVTYPE getD3D9DeviceType() const { return mDeviceType; }
+ private:
void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override;
Workarounds generateWorkarounds() const override;
@@ -225,12 +247,11 @@ class Renderer9 : public RendererD3D
gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB);
- gl::Error getNullColorbuffer(gl::FramebufferAttachment *depthbuffer, gl::FramebufferAttachment **outColorBuffer);
+ gl::Error getNullColorbuffer(const gl::FramebufferAttachment *depthbuffer, const gl::FramebufferAttachment **outColorBuffer);
D3DPOOL getBufferPool(DWORD usage) const;
HMODULE mD3d9Module;
- HDC mDc;
void initializeDevice();
D3DPRESENT_PARAMETERS getDefaultPresentParameters();
@@ -253,7 +274,6 @@ class Renderer9 : public RendererD3D
HWND mDeviceWindow;
- bool mDeviceLost;
D3DCAPS9 mDeviceCaps;
D3DADAPTER_IDENTIFIER9 mAdapterIdentifier;
@@ -262,21 +282,25 @@ class Renderer9 : public RendererD3D
GLsizei mRepeatDraw;
bool mSceneStarted;
- int mMinSwapInterval;
- int mMaxSwapInterval;
bool mVertexTextureSupport;
// current render target states
unsigned int mAppliedRenderTargetSerial;
- unsigned int mAppliedDepthbufferSerial;
- unsigned int mAppliedStencilbufferSerial;
+ unsigned int mAppliedDepthStencilSerial;
bool mDepthStencilInitialized;
bool mRenderTargetDescInitialized;
- RenderTarget::Desc mRenderTargetDesc;
unsigned int mCurStencilSize;
unsigned int mCurDepthSize;
+ struct RenderTargetDesc
+ {
+ size_t width;
+ size_t height;
+ D3DFORMAT format;
+ };
+ RenderTargetDesc mRenderTargetDesc;
+
IDirect3DStateBlock9 *mMaskedClearSavedState;
// previously set render states
@@ -346,7 +370,8 @@ class Renderer9 : public RendererD3D
} mNullColorbufferCache[NUM_NULL_COLORBUFFER_CACHE_ENTRIES];
UINT mMaxNullColorbufferLRU;
+ DebugAnnotator9 mAnnotator;
};
}
-#endif // LIBGLESV2_RENDERER_RENDERER9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h
index 6d7d2d648f..cf831c62fa 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h
@@ -7,10 +7,10 @@
// ShaderCache: Defines rx::ShaderCache, a cache of Direct3D shader objects
// keyed by their byte code.
-#ifndef LIBGLESV2_RENDERER_SHADER_CACHE_H_
-#define LIBGLESV2_RENDERER_SHADER_CACHE_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_SHADERCACHE_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_SHADERCACHE_H_
-#include "libGLESv2/Error.h"
+#include "libANGLE/Error.h"
#include "common/debug.h"
@@ -21,7 +21,7 @@
namespace rx
{
template <typename ShaderObject>
-class ShaderCache
+class ShaderCache : angle::NonCopyable
{
public:
ShaderCache() : mDevice(NULL)
@@ -82,8 +82,6 @@ class ShaderCache
}
private:
- DISALLOW_COPY_AND_ASSIGN(ShaderCache);
-
const static size_t kMaxMapSize = 100;
HRESULT createShader(const DWORD *function, IDirect3DVertexShader9 **shader)
@@ -107,4 +105,4 @@ typedef ShaderCache<IDirect3DPixelShader9> PixelShaderCache;
}
-#endif // LIBGLESV2_RENDERER_SHADER_CACHE_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_SHADERCACHE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp
index bc7120461b..280e80930b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp
@@ -7,7 +7,7 @@
// ShaderExecutable9.cpp: Implements a D3D9-specific class to contain shader
// executable implementation details.
-#include "libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.h"
+#include "libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h"
#include "common/debug.h"
@@ -15,14 +15,14 @@ namespace rx
{
ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable)
- : ShaderExecutable(function, length)
+ : ShaderExecutableD3D(function, length)
{
mPixelExecutable = executable;
mVertexExecutable = NULL;
}
ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable)
- : ShaderExecutable(function, length)
+ : ShaderExecutableD3D(function, length)
{
mVertexExecutable = executable;
mPixelExecutable = NULL;
@@ -34,7 +34,7 @@ ShaderExecutable9::~ShaderExecutable9()
SafeRelease(mPixelExecutable);
}
-ShaderExecutable9 *ShaderExecutable9::makeShaderExecutable9(ShaderExecutable *executable)
+ShaderExecutable9 *ShaderExecutable9::makeShaderExecutable9(ShaderExecutableD3D *executable)
{
ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable9*, executable));
return static_cast<ShaderExecutable9*>(executable);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h
index fa1e6c2844..561f7defc8 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h
@@ -7,33 +7,31 @@
// ShaderExecutable9.h: Defines a D3D9-specific class to contain shader
// executable implementation details.
-#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_
-#define LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_SHADEREXECUTABLE9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_SHADEREXECUTABLE9_H_
-#include "libGLESv2/renderer/ShaderExecutable.h"
+#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
namespace rx
{
-class ShaderExecutable9 : public ShaderExecutable
+class ShaderExecutable9 : public ShaderExecutableD3D
{
public:
ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable);
ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable);
virtual ~ShaderExecutable9();
- static ShaderExecutable9 *makeShaderExecutable9(ShaderExecutable *executable);
+ static ShaderExecutable9 *makeShaderExecutable9(ShaderExecutableD3D *executable);
IDirect3DPixelShader9 *getPixelShader() const;
IDirect3DVertexShader9 *getVertexShader() const;
private:
- DISALLOW_COPY_AND_ASSIGN(ShaderExecutable9);
-
IDirect3DPixelShader9 *mPixelExecutable;
IDirect3DVertexShader9 *mVertexExecutable;
};
}
-#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_ \ No newline at end of file
+#endif // LIBANGLE_RENDERER_D3D_D3D9_SHADEREXECUTABLE9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
index 95eb1a4371..1620668166 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
@@ -6,12 +6,11 @@
// SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain.
-#include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h"
-#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-
-#include "common/features.h"
+#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/features.h"
namespace rx
{
@@ -19,7 +18,9 @@ namespace rx
SwapChain9::SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat)
: mRenderer(renderer),
- SwapChain(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat)
+ SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat),
+ mColorRenderTarget(this, false),
+ mDepthStencilRenderTarget(this, true)
{
mSwapChain = NULL;
mBackBuffer = NULL;
@@ -155,8 +156,10 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
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)
+ if (window && deviceType != D3DDEVTYPE_NULLREF)
{
D3DPRESENT_PARAMETERS presentParameters = {0};
presentParameters.AutoDepthStencilFormat = depthBufferd3dFormatInfo.renderFormat;
@@ -181,7 +184,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
//
// 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 (mRenderer->getAdapterVendor() == VENDOR_ID_INTEL)
+ if (mRenderer->getVendorId() == VENDOR_ID_INTEL)
{
presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64;
}
@@ -381,7 +384,7 @@ IDirect3DTexture9 *SwapChain9::getOffscreenTexture()
return mOffscreenTexture;
}
-SwapChain9 *SwapChain9::makeSwapChain9(SwapChain *swapChain)
+SwapChain9 *SwapChain9::makeSwapChain9(SwapChainD3D *swapChain)
{
ASSERT(HAS_DYNAMIC_TYPE(SwapChain9*, swapChain));
return static_cast<SwapChain9*>(swapChain);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h
index cb33bfbc0c..81ac08ca7b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h
@@ -6,17 +6,18 @@
// SwapChain9.h: Defines a back-end specific class for the D3D9 swap chain.
-#ifndef LIBGLESV2_RENDERER_SWAPCHAIN9_H_
-#define LIBGLESV2_RENDERER_SWAPCHAIN9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_SWAPCHAIN9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_SWAPCHAIN9_H_
#include "common/angleutils.h"
-#include "libGLESv2/renderer/SwapChain.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
namespace rx
{
class Renderer9;
-class SwapChain9 : public SwapChain
+class SwapChain9 : public SwapChainD3D
{
public:
SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle,
@@ -28,6 +29,9 @@ class SwapChain9 : public SwapChain
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
virtual void recreate();
+ RenderTargetD3D *getColorRenderTarget() override { return &mColorRenderTarget; }
+ RenderTargetD3D *getDepthStencilRenderTarget() override { return &mDepthStencilRenderTarget; }
+
virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil();
virtual IDirect3DTexture9 *getOffscreenTexture();
@@ -35,11 +39,9 @@ class SwapChain9 : public SwapChain
EGLint getWidth() const { return mWidth; }
EGLint getHeight() const { return mHeight; }
- static SwapChain9 *makeSwapChain9(SwapChain *swapChain);
+ static SwapChain9 *makeSwapChain9(SwapChainD3D *swapChain);
private:
- DISALLOW_COPY_AND_ASSIGN(SwapChain9);
-
void release();
Renderer9 *mRenderer;
@@ -52,7 +54,10 @@ class SwapChain9 : public SwapChain
IDirect3DSurface9 *mRenderTarget;
IDirect3DSurface9 *mDepthStencil;
IDirect3DTexture9* mOffscreenTexture;
+
+ SurfaceRenderTarget9 mColorRenderTarget;
+ SurfaceRenderTarget9 mDepthStencilRenderTarget;
};
}
-#endif // LIBGLESV2_RENDERER_SWAPCHAIN9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_SWAPCHAIN9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp
index 0ff4fd3b0f..139cb3eb08 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp
@@ -8,15 +8,15 @@
// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
// D3D9 texture.
-#include "libGLESv2/renderer/d3d/d3d9/TextureStorage9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/SwapChain9.h"
-#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
-#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/main.h"
+#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Texture.h"
namespace rx
{
@@ -92,7 +92,7 @@ int TextureStorage9::getLevelCount() const
return mMipLevels - mTopLevel;
}
-gl::Error TextureStorage9::setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+gl::Error TextureStorage9::setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData)
{
UNREACHABLE();
@@ -180,7 +180,7 @@ gl::Error TextureStorage9_2D::getSurfaceLevel(int level, bool dirty, IDirect3DSu
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/, RenderTarget **outRT)
+gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/, RenderTargetD3D **outRT)
{
if (!mRenderTarget && isRenderTarget())
{
@@ -286,7 +286,7 @@ gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage)
return gl::Error(GL_NO_ERROR);
}
-TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
+TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly)
: TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget))
{
mTexture = NULL;
@@ -356,7 +356,7 @@ gl::Error TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level,
return gl::Error(GL_NO_ERROR);
}
-gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT)
+gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT)
{
ASSERT(outRT);
ASSERT(index.mipIndex == 0);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h
index da0e1f2f18..5cc06f07b1 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h
@@ -8,17 +8,17 @@
// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
// D3D9 texture.
-#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
-#define LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_
-#include "libGLESv2/renderer/d3d/TextureStorage.h"
+#include "libANGLE/renderer/d3d/TextureStorage.h"
#include "common/debug.h"
namespace rx
{
class Renderer9;
class SwapChain9;
-class RenderTarget;
+class RenderTargetD3D;
class RenderTarget9;
class TextureStorage9 : public TextureStorage
@@ -34,14 +34,14 @@ class TextureStorage9 : public TextureStorage
DWORD getUsage() const;
virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) = 0;
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT) = 0;
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0;
virtual int getTopLevel() const;
virtual bool isRenderTarget() const;
virtual bool isManaged() const;
virtual int getLevelCount() const;
- virtual gl::Error setData(const gl::ImageIndex &index, Image *image, const gl::Box *destBox, GLenum type,
+ virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type,
const gl::PixelUnpackState &unpack, const uint8_t *pixelData);
protected:
@@ -57,8 +57,6 @@ class TextureStorage9 : public TextureStorage
TextureStorage9(Renderer9 *renderer, DWORD usage);
private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage9);
-
const DWORD mD3DUsage;
const D3DPOOL mD3DPool;
};
@@ -73,14 +71,12 @@ class TextureStorage9_2D : public TextureStorage9
static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage);
gl::Error getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface);
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture);
virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
virtual gl::Error copyToStorage(TextureStorage *destStorage);
private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage9_2D);
-
IDirect3DTexture9 *mTexture;
RenderTarget9 *mRenderTarget;
};
@@ -88,20 +84,18 @@ class TextureStorage9_2D : public TextureStorage9
class TextureStorage9_Cube : public TextureStorage9
{
public:
- TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels);
+ TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly);
virtual ~TextureStorage9_Cube();
static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage);
gl::Error getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface);
- virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTarget **outRT);
+ virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT);
virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture);
virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex);
virtual gl::Error copyToStorage(TextureStorage *destStorage);
private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube);
-
static const size_t CUBE_FACE_COUNT = 6;
IDirect3DCubeTexture9 *mTexture;
@@ -110,5 +104,5 @@ class TextureStorage9_Cube : public TextureStorage9
}
-#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
index 791c108462..fb626bc0cf 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
@@ -6,11 +6,11 @@
// VertexArray9.h: Defines the rx::VertexArray9 class which implements rx::VertexArrayImpl.
-#ifndef LIBGLESV2_RENDERER_VERTEXARRAY9_H_
-#define LIBGLESV2_RENDERER_VERTEXARRAY9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_
-#include "libGLESv2/renderer/VertexArrayImpl.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/VertexArrayImpl.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
namespace rx
{
@@ -33,11 +33,9 @@ class VertexArray9 : public VertexArrayImpl
virtual void enableAttribute(size_t idx, bool enabledState) { }
private:
- DISALLOW_COPY_AND_ASSIGN(VertexArray9);
-
Renderer9 *mRenderer;
};
}
-#endif // LIBGLESV2_RENDERER_VERTEXARRAY9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp
index b90133097c..cb5003997f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp
@@ -6,13 +6,13 @@
// VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation.
-#include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/vertexconversion.h"
-#include "libGLESv2/renderer/d3d/BufferD3D.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/Buffer.h"
+#include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/vertexconversion.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/Buffer.h"
namespace rx
{
@@ -97,9 +97,9 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib
{
if (buffer)
{
- BufferD3D *storage = BufferD3D::makeFromBuffer(buffer);
+ BufferD3D *storage = GetImplAs<BufferD3D>(buffer);
ASSERT(storage);
- gl::Error error = storage->getData(&input);
+ error = storage->getData(&input);
if (error.isError())
{
return error;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h
index 9af2b98a6e..f5b110b22b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h
@@ -6,10 +6,10 @@
// VertexBuffer9.h: Defines the D3D9 VertexBuffer implementation.
-#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
-#define LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXBUFFER9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXBUFFER9_H_
-#include "libGLESv2/renderer/d3d/VertexBuffer.h"
+#include "libANGLE/renderer/d3d/VertexBuffer.h"
namespace rx
{
@@ -37,8 +37,6 @@ class VertexBuffer9 : public VertexBuffer
IDirect3DVertexBuffer9 *getBuffer() const;
private:
- DISALLOW_COPY_AND_ASSIGN(VertexBuffer9);
-
Renderer9 *mRenderer;
IDirect3DVertexBuffer9 *mVertexBuffer;
@@ -51,4 +49,4 @@ class VertexBuffer9 : public VertexBuffer
}
-#endif // LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXBUFFER9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp
index cefd786f11..f9eded9b50 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp
@@ -6,11 +6,11 @@
// VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations.
-#include "libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h"
-#include "libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/VertexAttribute.h"
+#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h"
+#include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/VertexAttribute.h"
namespace rx
{
@@ -40,7 +40,7 @@ VertexDeclarationCache::~VertexDeclarationCache()
}
}
-gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw)
+gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::Program *program, GLsizei instances, GLsizei *repeatDraw)
{
*repeatDraw = 1;
@@ -155,7 +155,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra
element->Type = d3d9VertexInfo.nativeFormat;
element->Method = D3DDECLMETHOD_DEFAULT;
element->Usage = D3DDECLUSAGE_TEXCOORD;
- element->UsageIndex = programBinary->getSemanticIndex(i);
+ element->UsageIndex = program->getSemanticIndex(i);
element++;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h
index 9af36e0d7a..fbd673097f 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h
@@ -6,15 +6,16 @@
// VertexDeclarationCache.h: Defines a helper class to construct and cache vertex declarations.
-#ifndef LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
-#define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXDECLARATIONCACHE_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXDECLARATIONCACHE_H_
-#include "libGLESv2/Error.h"
-#include "libGLESv2/renderer/d3d/VertexDataManager.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
namespace gl
{
class VertexDataManager;
+class Program;
}
namespace rx
@@ -26,7 +27,7 @@ class VertexDeclarationCache
VertexDeclarationCache();
~VertexDeclarationCache();
- gl::Error applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw);
+ gl::Error applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::Program *program, GLsizei instances, GLsizei *repeatDraw);
void markStateDirty();
@@ -56,4 +57,4 @@ class VertexDeclarationCache
}
-#endif // LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXDECLARATIONCACHE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp
index f3acaf7987..9bad5503d9 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp
@@ -7,12 +7,12 @@
// formatutils9.cpp: Queries for GL image formats and their translations to D3D9
// formats.
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#include "libGLESv2/renderer/generatemip.h"
-#include "libGLESv2/renderer/loadimage.h"
-#include "libGLESv2/renderer/copyimage.h"
-#include "libGLESv2/renderer/vertexconversion.h"
+#include "libANGLE/renderer/d3d/copyimage.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/vertexconversion.h"
+#include "libANGLE/renderer/d3d/generatemip.h"
+#include "libANGLE/renderer/d3d/loadimage.h"
namespace rx
{
@@ -57,6 +57,13 @@ D3DFormat::D3DFormat()
: pixelBytes(0),
blockWidth(0),
blockHeight(0),
+ redBits(0),
+ greenBits(0),
+ blueBits(0),
+ alphaBits(0),
+ luminanceBits(0),
+ depthBits(0),
+ stencilBits(0),
internalFormat(GL_NONE),
mipGenerationFunction(NULL),
colorReadFunction(NULL),
@@ -71,13 +78,22 @@ ColorCopyFunction D3DFormat::getFastCopyFunction(GLenum format, GLenum type) con
}
static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, GLuint bits, GLuint blockWidth,
- GLuint blockHeight, GLenum internalFormat, MipGenerationFunction mipFunc,
+ GLuint blockHeight, GLuint redBits, GLuint greenBits, GLuint blueBits,
+ GLuint alphaBits, GLuint lumBits, GLuint depthBits, GLuint stencilBits,
+ GLenum internalFormat, MipGenerationFunction mipFunc,
ColorReadFunction colorReadFunc)
{
D3DFormat info;
info.pixelBytes = bits / 8;
info.blockWidth = blockWidth;
info.blockHeight = blockHeight;
+ info.redBits = redBits;
+ info.greenBits = greenBits;
+ info.blueBits = blueBits;
+ info.alphaBits = alphaBits;
+ info.luminanceBits = lumBits;
+ info.depthBits = depthBits;
+ info.stencilBits = stencilBits;
info.internalFormat = internalFormat;
info.mipGenerationFunction = mipFunc;
info.colorReadFunction = colorReadFunc;
@@ -96,35 +112,35 @@ static D3D9FormatInfoMap BuildD3D9FormatInfoMap()
{
D3D9FormatInfoMap map;
- // | D3DFORMAT | S |W |H | Internal format | Mip generation function | Color read function |
- InsertD3DFormatInfo(&map, D3DFMT_NULL, 0, 0, 0, GL_NONE, NULL, NULL );
- InsertD3DFormatInfo(&map, D3DFMT_UNKNOWN, 0, 0, 0, GL_NONE, NULL, NULL );
-
- InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, GL_BGRA4_ANGLEX, GenerateMip<B4G4R4A4>, ReadColor<B4G4R4A4, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, GL_BGR5_A1_ANGLEX, GenerateMip<B5G5R5A1>, ReadColor<B5G5R5A1, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_R16F, 16, 1, 1, GL_R16F_EXT, GenerateMip<R16F>, ReadColor<R16F, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_G16R16F, 32, 1, 1, GL_RG16F_EXT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_A16B16G16R16F, 64, 1, 1, GL_RGBA16F_EXT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>);
- InsertD3DFormatInfo(&map, D3DFMT_R32F, 32, 1, 1, GL_R32F_EXT, GenerateMip<R32F>, ReadColor<R32F, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_G32R32F, 64, 1, 1, GL_RG32F_EXT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat> );
- InsertD3DFormatInfo(&map, D3DFMT_A32B32G32R32F, 128, 1, 1, GL_RGBA32F_EXT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>);
-
- InsertD3DFormatInfo(&map, D3DFMT_D16, 16, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL );
- InsertD3DFormatInfo(&map, D3DFMT_D24S8, 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL );
- InsertD3DFormatInfo(&map, D3DFMT_D24X8, 32, 1, 1, GL_DEPTH_COMPONENT16, NULL, NULL );
- InsertD3DFormatInfo(&map, D3DFMT_D32, 32, 1, 1, GL_DEPTH_COMPONENT32_OES, NULL, NULL );
-
- InsertD3DFormatInfo(&map, D3DFMT_INTZ, 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL, NULL );
-
- InsertD3DFormatInfo(&map, D3DFMT_DXT1, 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL );
- InsertD3DFormatInfo(&map, D3DFMT_DXT3, 128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL );
- InsertD3DFormatInfo(&map, D3DFMT_DXT5, 128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL );
+ // | D3DFORMAT | S |W |H | R | G | B | A | L | D | S | Internal format | Mip generation function | Color read function |
+ InsertD3DFormatInfo(&map, D3DFMT_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, GL_NONE, NULL, NULL );
+ InsertD3DFormatInfo(&map, D3DFMT_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, GL_NONE, NULL, NULL );
+
+ InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, 0, 0, 0, 0, 8, 0, 0, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, 0, 0, 0, 8, 0, 0, 0, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, 0, 0, 0, 8, 8, 0, 0, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, 4, 4, 4, 4, 0, 0, 0, GL_BGRA4_ANGLEX, GenerateMip<B4G4R4A4>, ReadColor<B4G4R4A4, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, 5, 5, 5, 1, 0, 0, 0, GL_BGR5_A1_ANGLEX, GenerateMip<B5G5R5A1>, ReadColor<B5G5R5A1, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, 5, 6, 5, 0, 0, 0, 0, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, 8, 8, 8, 0, 0, 0, 0, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, 8, 8, 8, 8, 0, 0, 0, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_R16F, 16, 1, 1, 16, 0, 0, 0, 0, 0, 0, GL_R16F_EXT, GenerateMip<R16F>, ReadColor<R16F, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_G16R16F, 32, 1, 1, 16, 16, 0, 0, 0, 0, 0, GL_RG16F_EXT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_A16B16G16R16F, 64, 1, 1, 16, 16, 16, 16, 0, 0, 0, GL_RGBA16F_EXT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>);
+ InsertD3DFormatInfo(&map, D3DFMT_R32F, 32, 1, 1, 32, 0, 0, 0, 0, 0, 0, GL_R32F_EXT, GenerateMip<R32F>, ReadColor<R32F, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_G32R32F, 64, 1, 1, 32, 32, 0, 0, 0, 0, 0, GL_RG32F_EXT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat> );
+ InsertD3DFormatInfo(&map, D3DFMT_A32B32G32R32F, 128, 1, 1, 32, 32, 32, 32, 0, 0, 0, GL_RGBA32F_EXT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>);
+
+ InsertD3DFormatInfo(&map, D3DFMT_D16, 16, 1, 1, 0, 0, 0, 0, 0, 16, 0, GL_DEPTH_COMPONENT16, NULL, NULL );
+ InsertD3DFormatInfo(&map, D3DFMT_D24S8, 32, 1, 1, 0, 0, 0, 0, 0, 24, 8, GL_DEPTH24_STENCIL8_OES, NULL, NULL );
+ InsertD3DFormatInfo(&map, D3DFMT_D24X8, 32, 1, 1, 0, 0, 0, 0, 0, 24, 0, GL_DEPTH_COMPONENT16, NULL, NULL );
+ InsertD3DFormatInfo(&map, D3DFMT_D32, 32, 1, 1, 0, 0, 0, 0, 0, 32, 0, GL_DEPTH_COMPONENT32_OES, NULL, NULL );
+
+ InsertD3DFormatInfo(&map, D3DFMT_INTZ, 32, 1, 1, 0, 0, 0, 0, 0, 24, 8, GL_DEPTH24_STENCIL8_OES, NULL, NULL );
+
+ InsertD3DFormatInfo(&map, D3DFMT_DXT1, 64, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL );
+ InsertD3DFormatInfo(&map, D3DFMT_DXT3, 128, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL );
+ InsertD3DFormatInfo(&map, D3DFMT_DXT5, 128, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL );
return map;
}
@@ -192,8 +208,8 @@ typedef std::pair<GLenum, TextureFormat> D3D9FormatPair;
typedef std::map<GLenum, TextureFormat> D3D9FormatMap;
TextureFormat::TextureFormat()
- : texFormat(D3DFMT_NULL),
- renderFormat(D3DFMT_NULL),
+ : texFormat(D3DFMT_UNKNOWN),
+ renderFormat(D3DFMT_UNKNOWN),
dataInitializerFunction(NULL),
loadFunction(UnreachableLoad)
{
@@ -544,7 +560,7 @@ const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::Vert
static bool initialized = false;
static DWORD intializedDeclTypes = 0;
static VertexFormat formatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
- if (!initialized)
+ if (intializedDeclTypes != supportedDeclTypes)
{
const TranslationDescription translations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
{
@@ -576,8 +592,6 @@ const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::Vert
intializedDeclTypes = supportedDeclTypes;
}
- ASSERT(intializedDeclTypes == supportedDeclTypes);
-
// Pure integer attributes only supported in ES3.0
ASSERT(!vertexFormat.mPureInteger);
return formatConverters[ComputeTypeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1];
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h
index f26fe43b36..15e26599c8 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h
@@ -7,10 +7,13 @@
// formatutils9.h: Queries for GL image formats and their translations to D3D9
// formats.
-#ifndef LIBGLESV2_RENDERER_FORMATUTILS9_H_
-#define LIBGLESV2_RENDERER_FORMATUTILS9_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_
-#include "libGLESv2/formatutils.h"
+#include "libANGLE/renderer/d3d/formatutilsD3D.h"
+#include "libANGLE/angletypes.h"
+
+#include "common/platform.h"
#include <map>
@@ -32,6 +35,15 @@ struct D3DFormat
GLuint blockWidth;
GLuint blockHeight;
+ GLuint redBits;
+ GLuint greenBits;
+ GLuint blueBits;
+ GLuint alphaBits;
+ GLuint luminanceBits;
+
+ GLuint depthBits;
+ GLuint stencilBits;
+
GLenum internalFormat;
MipGenerationFunction mipGenerationFunction;
@@ -71,4 +83,4 @@ const TextureFormat &GetTextureFormatInfo(GLenum internalFormat);
}
-#endif // LIBGLESV2_RENDERER_FORMATUTILS9_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
index a98b2081f3..c9711ac052 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -7,12 +7,13 @@
// renderer9_utils.cpp: Conversion functions and other utility routines
// specific to the D3D9 renderer.
-#include "libGLESv2/renderer/d3d/d3d9/renderer9_utils.h"
-#include "libGLESv2/renderer/d3d/d3d9/formatutils9.h"
-#include "libGLESv2/renderer/Workarounds.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/Workarounds.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
#include "common/mathutil.h"
#include "common/debug.h"
@@ -276,29 +277,41 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3
const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalFormat);
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
- if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
- {
- textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat));
- }
- else
+
+ if (d3dFormatInfo.texFormat != D3DFMT_UNKNOWN)
{
- 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 (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));
+ }
- textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat));
- textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat)) ||
- SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat));
+ textureCaps.filterable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat));
+ }
- textureCaps.sampleCounts.insert(1);
- for (size_t i = D3DMULTISAMPLE_2_SAMPLES; i <= D3DMULTISAMPLE_16_SAMPLES; i++)
+ if (d3dFormatInfo.renderFormat != D3DFMT_UNKNOWN)
{
- D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i);
+ textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat));
- HRESULT result = d3d9->CheckDeviceMultiSampleType(adapter, deviceType, d3dFormatInfo.renderFormat, TRUE, multisampleType, NULL);
- if (SUCCEEDED(result))
+ if ((formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) && !textureCaps.renderable)
{
- textureCaps.sampleCounts.insert(i);
+ textureCaps.renderable = SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat));
+ }
+
+ textureCaps.sampleCounts.insert(1);
+ for (size_t 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, NULL);
+ if (SUCCEEDED(result))
+ {
+ textureCaps.sampleCounts.insert(i);
+ }
}
}
@@ -378,6 +391,22 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT
// 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;
@@ -454,14 +483,23 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT
extensions->mapBuffer = false;
extensions->mapBufferRange = false;
- // ATI cards on XP have problems with non-power-of-two textures.
+ // textureRG is emulated and not performant.
+ extensions->textureRG = false;
+
D3DADAPTER_IDENTIFIER9 adapterId = { 0 };
if (SUCCEEDED(d3d9->GetAdapterIdentifier(adapter, 0, &adapterId)))
{
+ // ATI cards on XP have problems with non-power-of-two textures.
extensions->textureNPOT = !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
!(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
!(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
!(!isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD);
+
+ // Disable depth texture support on AMD cards (See ANGLE issue 839)
+ if (adapterId.VendorId == VENDOR_ID_AMD)
+ {
+ extensions->depthTextures = false;
+ }
}
else
{
@@ -533,9 +571,9 @@ void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsize
*levelOffset = upsampleCount;
}
-gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget9 **outRT)
+gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget9 **outRT)
{
- RenderTarget *renderTarget = NULL;
+ RenderTargetD3D *renderTarget = NULL;
gl::Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
if (error.isError())
{
@@ -550,6 +588,7 @@ Workarounds GenerateWorkarounds()
Workarounds workarounds;
workarounds.mrtPerfWorkaround = true;
workarounds.setDataFasterThanImageUpload = false;
+ workarounds.useInstancedPointSpriteEmulation = false;
return workarounds;
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
index 9760b9735a..3c6a57aee3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
@@ -7,12 +7,12 @@
// renderer9_utils.h: Conversion functions and other utility routines
// specific to the D3D9 renderer
-#ifndef LIBGLESV2_RENDERER_RENDERER9_UTILS_H
-#define LIBGLESV2_RENDERER_RENDERER9_UTILS_H
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/Caps.h"
-#include "libGLESv2/Error.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Error.h"
namespace gl
{
@@ -76,11 +76,11 @@ inline bool isDeviceLostError(HRESULT errorCode)
}
}
-gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget9 **outRT);
+gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTarget9 **outRT);
Workarounds GenerateWorkarounds();
}
}
-#endif // LIBGLESV2_RENDERER_RENDERER9_UTILS_H
+#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps
index eb43eb3e7a..dc357d0fa6 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps
@@ -11,7 +11,7 @@ uniform float4 add : c1;
// Passthrough Pixel Shader
// Outputs texture 0 sampled at texcoord 0.
-float4 PS_passthrough(float4 texcoord : TEXCOORD0) : COLOR
+float4 passthroughps(float4 texcoord : TEXCOORD0) : COLOR
{
return tex2D(tex, texcoord.xy);
};
@@ -19,7 +19,7 @@ float4 PS_passthrough(float4 texcoord : TEXCOORD0) : COLOR
// Luminance Conversion Pixel Shader
// Performs a mad operation using the LA data from the texture with mult.xw and add.xw.
// Returns data in the form of llla
-float4 PS_luminance(float4 texcoord : TEXCOORD0) : COLOR
+float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR
{
return (tex2D(tex, texcoord.xy).xw * mult.xw + add.xw).xxxy;
};
@@ -27,7 +27,7 @@ float4 PS_luminance(float4 texcoord : TEXCOORD0) : COLOR
// RGB/A Component Mask Pixel Shader
// Performs a mad operation using the texture's RGBA data with mult.xyzw and add.xyzw.
// Returns data in the form of rgba
-float4 PS_componentmask(float4 texcoord : TEXCOORD0) : COLOR
+float4 componentmaskps(float4 texcoord : TEXCOORD0) : COLOR
{
return tex2D(tex, texcoord.xy) * mult + add;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs
index 3bd611ba5d..3a36980b93 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs
@@ -17,7 +17,7 @@ uniform float4 halfPixelSize : c0;
// Outputs the homogenous position as-is.
// Outputs a tex coord with (0,0) in the upper-left corner of the screen and (1,1) in the bottom right.
// C0.X must be negative half-pixel width, C0.Y must be half-pixel height. C0.ZW must be 0.
-VS_OUTPUT VS_standard(in float4 position : POSITION)
+VS_OUTPUT standardvs(in float4 position : POSITION)
{
VS_OUTPUT Out;
@@ -32,7 +32,7 @@ VS_OUTPUT VS_standard(in float4 position : POSITION)
// Outputs the homogenous position as-is.
// Outputs a tex coord with (0,1) in the upper-left corner of the screen and (1,0) in the bottom right.
// C0.XY must be the half-pixel width and height. C0.ZW must be 0.
-VS_OUTPUT VS_flipy(in float4 position : POSITION)
+VS_OUTPUT flipyvs(in float4 position : POSITION)
{
VS_OUTPUT Out;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h
index 81ba8a0767..32eb376a78 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h
@@ -7,8 +7,8 @@
// vertexconversion.h: A library of vertex conversion classes that can be used to build
// the FormatConverter objects used by the buffer conversion system.
-#ifndef LIBGLESV2_VERTEXCONVERSION_H_
-#define LIBGLESV2_VERTEXCONVERSION_H_
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXCONVERSION_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXCONVERSION_H_
#include <limits>
#include <cstdint>
@@ -194,4 +194,4 @@ struct VertexDataConverter
}
-#endif // LIBGLESV2_VERTEXCONVERSION_H_
+#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXCONVERSION_H_
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.cpp
new file mode 100644
index 0000000000..8a4d41cbd9
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.cpp
@@ -0,0 +1,147 @@
+//
+// Copyright (c) 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.cpp: Queries for GL image formats and their translations to D3D
+// formats.
+
+#include "libANGLE/renderer/d3d/formatutilsD3D.h"
+
+#include <map>
+
+#include "common/debug.h"
+#include "libANGLE/renderer/d3d/imageformats.h"
+#include "libANGLE/renderer/d3d/copyimage.h"
+
+namespace rx
+{
+
+typedef std::pair<GLenum, GLenum> FormatTypePair;
+typedef std::pair<FormatTypePair, ColorWriteFunction> FormatWriteFunctionPair;
+typedef std::map<FormatTypePair, ColorWriteFunction> FormatWriteFunctionMap;
+
+static inline void InsertFormatWriteFunctionMapping(FormatWriteFunctionMap *map, GLenum format, GLenum type,
+ ColorWriteFunction writeFunc)
+{
+ map->insert(FormatWriteFunctionPair(FormatTypePair(format, type), writeFunc));
+}
+
+static FormatWriteFunctionMap BuildFormatWriteFunctionMap()
+{
+ FormatWriteFunctionMap map;
+
+ // | Format | Type | Color write function |
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, WriteColor<R8G8B8A8, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_BYTE, WriteColor<R8G8B8A8S, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, WriteColor<R4G4B4A4, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, WriteColor<R5G5B5A1, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, WriteColor<R10G10B10A2, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_FLOAT, WriteColor<R32G32B32A32F, GLfloat>);
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_HALF_FLOAT, WriteColor<R16G16B16A16F, GLfloat>);
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, WriteColor<R16G16B16A16F, GLfloat>);
+
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, WriteColor<R8G8B8A8, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_BYTE, WriteColor<R8G8B8A8S, GLint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, WriteColor<R16G16B16A16, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_SHORT, WriteColor<R16G16B16A16S, GLint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, WriteColor<R32G32B32A32, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_INT, WriteColor<R32G32B32A32S, GLint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, WriteColor<R10G10B10A2, GLuint> );
+
+ InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, WriteColor<R8G8B8, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_BYTE, WriteColor<R8G8B8S, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, WriteColor<R5G6B5, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, WriteColor<R11G11B10F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, WriteColor<R9G9B9E5, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_FLOAT, WriteColor<R32G32B32F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_HALF_FLOAT, WriteColor<R16G16B16F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, WriteColor<R16G16B16F, GLfloat> );
+
+ InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, WriteColor<R8G8B8, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_BYTE, WriteColor<R8G8B8S, GLint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, WriteColor<R16G16B16, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_SHORT, WriteColor<R16G16B16S, GLint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, WriteColor<R32G32B32, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_INT, WriteColor<R32G32B32S, GLint> );
+
+ InsertFormatWriteFunctionMapping(&map, GL_RG, GL_UNSIGNED_BYTE, WriteColor<R8G8, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RG, GL_BYTE, WriteColor<R8G8S, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RG, GL_FLOAT, WriteColor<R32G32F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RG, GL_HALF_FLOAT, WriteColor<R16G16F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RG, GL_HALF_FLOAT_OES, WriteColor<R16G16F, GLfloat> );
+
+ InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, WriteColor<R8G8, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_BYTE, WriteColor<R8G8S, GLint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, WriteColor<R16G16, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_SHORT, WriteColor<R16G16S, GLint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, WriteColor<R32G32, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_INT, WriteColor<R32G32S, GLint> );
+
+ InsertFormatWriteFunctionMapping(&map, GL_RED, GL_UNSIGNED_BYTE, WriteColor<R8, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RED, GL_BYTE, WriteColor<R8S, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RED, GL_FLOAT, WriteColor<R32F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RED, GL_HALF_FLOAT, WriteColor<R16F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_RED, GL_HALF_FLOAT_OES, WriteColor<R16F, GLfloat> );
+
+ InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, WriteColor<R8, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_BYTE, WriteColor<R8S, GLint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, WriteColor<R16, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_SHORT, WriteColor<R16S, GLint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, WriteColor<R32, GLuint> );
+ InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_INT, WriteColor<R32S, GLint> );
+
+ InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, WriteColor<L8A8, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, WriteColor<L8, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, WriteColor<A8, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, WriteColor<L32A32F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_FLOAT, WriteColor<L32F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_FLOAT, WriteColor<A32F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, WriteColor<L16A16F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, WriteColor<L16A16F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, WriteColor<L16F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, WriteColor<L16F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_HALF_FLOAT, WriteColor<A16F, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, WriteColor<A16F, GLfloat> );
+
+ InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, WriteColor<B8G8R8A8, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, WriteColor<B4G4R4A4, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, WriteColor<B5G5R5A1, GLfloat> );
+
+ InsertFormatWriteFunctionMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, WriteColor<R8G8B8, GLfloat> );
+ InsertFormatWriteFunctionMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, WriteColor<R8G8B8A8, GLfloat> );
+
+ InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, NULL );
+ InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, NULL );
+ InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, NULL );
+ InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, NULL );
+
+ InsertFormatWriteFunctionMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL );
+ InsertFormatWriteFunctionMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL );
+ InsertFormatWriteFunctionMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, NULL );
+
+ InsertFormatWriteFunctionMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, NULL );
+
+ InsertFormatWriteFunctionMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL );
+ InsertFormatWriteFunctionMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NULL );
+
+ return map;
+}
+
+ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type)
+{
+ static const FormatWriteFunctionMap formatTypeMap = BuildFormatWriteFunctionMap();
+ FormatWriteFunctionMap::const_iterator iter = formatTypeMap.find(FormatTypePair(format, type));
+ ASSERT(iter != formatTypeMap.end());
+ if (iter != formatTypeMap.end())
+ {
+ return iter->second;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h
new file mode 100644
index 0000000000..6dd59ca94b
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h
@@ -0,0 +1,50 @@
+//
+// Copyright (c) 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_
+
+#include "angle_gl.h"
+
+#include <cstddef>
+#include <stdint.h>
+
+namespace rx
+{
+
+typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+ const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+ uint8_t *destData, size_t destRowPitch, size_t destDepthPitch);
+
+typedef void (*LoadImageFunction)(size_t width, size_t height, size_t depth,
+ const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
+ uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+typedef void (*InitializeTextureDataFunction)(size_t width, size_t height, size_t depth,
+ uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
+
+typedef void (*ColorReadFunction)(const uint8_t *source, uint8_t *dest);
+typedef void (*ColorWriteFunction)(const uint8_t *source, uint8_t *dest);
+typedef void (*ColorCopyFunction)(const uint8_t *source, uint8_t *dest);
+
+typedef void (*VertexCopyFunction)(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
+
+enum VertexConversionType
+{
+ VERTEX_CONVERT_NONE = 0,
+ VERTEX_CONVERT_CPU = 1,
+ VERTEX_CONVERT_GPU = 2,
+ VERTEX_CONVERT_BOTH = 3
+};
+
+ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type);
+
+}
+
+#endif // LIBANGLE_RENDERER_D3D_FORMATUTILSD3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/generatemip.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.h
index a57b00d444..398ef26b30 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/generatemip.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -7,11 +7,11 @@
// generatemip.h: Defines the GenerateMip function, templated on the format
// type of the image for which mip levels are being generated.
-#ifndef LIBGLESV2_RENDERER_GENERATEMIP_H_
-#define LIBGLESV2_RENDERER_GENERATEMIP_H_
+#ifndef LIBANGLE_RENDERER_D3D_GENERATEMIP_H_
+#define LIBANGLE_RENDERER_D3D_GENERATEMIP_H_
-#include "libGLESv2/renderer/imageformats.h"
-#include "libGLESv2/angletypes.h"
+#include "libANGLE/renderer/d3d/imageformats.h"
+#include "libANGLE/angletypes.h"
namespace rx
{
@@ -25,4 +25,4 @@ inline void GenerateMip(size_t sourceWidth, size_t sourceHeight, size_t sourceDe
#include "generatemip.inl"
-#endif // LIBGLESV2_RENDERER_GENERATEMIP_H_
+#endif // LIBANGLE_RENDERER_D3D_GENERATEMIP_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/generatemip.inl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.inl
index 6788a42f03..265783641e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/generatemip.inl
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.inl
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 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.
//
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/imageformats.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/imageformats.h
index 2140a9ee72..e0f9a16c1a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/imageformats.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/imageformats.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -7,8 +7,10 @@
// imageformats.h: Defines image format types with functions for mip generation
// and copying.
-#ifndef LIBGLESV2_RENDERER_IMAGEFORMATS_H_
-#define LIBGLESV2_RENDERER_IMAGEFORMATS_H_
+#ifndef LIBANGLE_RENDERER_D3D_IMAGEFORMATS_H_
+#define LIBANGLE_RENDERER_D3D_IMAGEFORMATS_H_
+
+#include "libANGLE/angletypes.h"
#include "common/mathutil.h"
@@ -2026,4 +2028,4 @@ struct R11G11B10F
}
-#endif // LIBGLESV2_RENDERER_IMAGEFORMATS_H_
+#endif // LIBANGLE_RENDERER_D3D_IMAGEFORMATS_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/loadimage.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.cpp
index 1986191a75..172832b3e7 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/loadimage.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.cpp
@@ -1,12 +1,12 @@
//
-// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// loadimage.cpp: Defines image loading functions.
-#include "libGLESv2/renderer/loadimage.h"
+#include "libANGLE/renderer/d3d/loadimage.h"
namespace rx
{
@@ -91,9 +91,10 @@ void LoadL8ToRGBA8(size_t width, size_t height, size_t depth,
uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
for (size_t x = 0; x < width; x++)
{
- dest[4 * x + 0] = source[x];
- dest[4 * x + 1] = source[x];
- dest[4 * x + 2] = source[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;
}
}
@@ -341,7 +342,7 @@ void LoadRGBA8ToBGRA8(size_t width, size_t height, size_t depth,
for (size_t x = 0; x < width; x++)
{
uint32_t rgba = source[x];
- dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
+ dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
}
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/loadimage.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.h
index bcdff24a66..6967dc868e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/loadimage.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.h
@@ -1,17 +1,17 @@
//
-// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// loadimage.h: Defines image loading functions
-#ifndef LIBGLESV2_RENDERER_LOADIMAGE_H_
-#define LIBGLESV2_RENDERER_LOADIMAGE_H_
+#ifndef LIBANGLE_RENDERER_D3D_LOADIMAGE_H_
+#define LIBANGLE_RENDERER_D3D_LOADIMAGE_H_
-#include "libGLESv2/angletypes.h"
+#include "libANGLE/angletypes.h"
-#include <cstdint>
+#include <stdint.h>
namespace rx
{
@@ -190,4 +190,4 @@ inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_
#include "loadimage.inl"
-#endif // LIBGLESV2_RENDERER_LOADIMAGE_H_
+#endif // LIBANGLE_RENDERER_D3D_LOADIMAGE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/loadimage.inl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.inl
index abd0a3673c..920e667db1 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/loadimage.inl
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.inl
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2014-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.
//
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimageSSE2.cpp
index 159b4c7e9f..c87d35c82b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimageSSE2.cpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -8,7 +8,13 @@
// in a separated file for GCC, which can enable SSE usage only per-file,
// not for code blocks that use SSE2 explicitly.
-#include "libGLESv2/renderer/loadimage.h"
+#include "libANGLE/renderer/d3d/loadimage.h"
+
+#include "common/platform.h"
+
+#ifdef ANGLE_USE_SSE
+#include <emmintrin.h>
+#endif
namespace rx
{
@@ -17,12 +23,7 @@ void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
{
-#if defined(_M_ARM)
- // Ensure that this function is reported as not implemented for ARM builds because
- // the instructions below are not present for that architecture.
- UNIMPLEMENTED();
- return;
-#else
+#if defined(ANGLE_USE_SSE)
__m128i zeroWide = _mm_setzero_si128();
for (size_t z = 0; z < depth; z++)
@@ -60,6 +61,11 @@ void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
}
}
}
+#else
+ // Ensure that this function is reported as not implemented for ARM builds because
+ // the instructions below are not present for that architecture.
+ UNIMPLEMENTED();
+ return;
#endif
}
@@ -67,12 +73,7 @@ void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
{
-#if defined(_M_ARM)
- // Ensure that this function is reported as not implemented for ARM builds because
- // the instructions below are not present for that architecture.
- UNIMPLEMENTED();
- return;
-#else
+#if defined(ANGLE_USE_SSE)
__m128i brMask = _mm_set1_epi32(0x00ff00ff);
for (size_t z = 0; z < depth; z++)
@@ -88,7 +89,7 @@ void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
for (; ((reinterpret_cast<intptr_t>(&dest[x]) & 15) != 0) && x < width; x++)
{
uint32_t rgba = source[x];
- dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
+ dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
}
for (; x + 3 < width; x += 4)
@@ -108,11 +109,17 @@ void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth,
for (; x < width; x++)
{
uint32_t rgba = source[x];
- dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
+ dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
}
}
}
+#else
+ // Ensure that this function is reported as not implemented for ARM builds because
+ // the instructions below are not present for that architecture.
+ UNIMPLEMENTED();
+ return;
#endif
}
}
+
diff --git a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp
new file mode 100644
index 0000000000..12ee6a2b93
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp
@@ -0,0 +1,503 @@
+//
+// Copyright (c) 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.cpp: Validation functions for generic EGL entry point parameters
+
+#include "libANGLE/validationEGL.h"
+
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Surface.h"
+
+#include <EGL/eglext.h>
+
+namespace egl
+{
+
+Error ValidateDisplay(const Display *display)
+{
+ if (display == EGL_NO_DISPLAY)
+ {
+ return Error(EGL_BAD_DISPLAY);
+ }
+
+ if (!display->isInitialized())
+ {
+ return Error(EGL_NOT_INITIALIZED);
+ }
+
+ return Error(EGL_SUCCESS);
+}
+
+Error ValidateSurface(const Display *display, Surface *surface)
+{
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!display->isValidSurface(surface))
+ {
+ return Error(EGL_BAD_SURFACE);
+ }
+
+ return Error(EGL_SUCCESS);
+}
+
+Error ValidateConfig(const Display *display, const Config *config)
+{
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!display->isValidConfig(config))
+ {
+ return Error(EGL_BAD_CONFIG);
+ }
+
+ return Error(EGL_SUCCESS);
+}
+
+Error ValidateContext(const Display *display, gl::Context *context)
+{
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!display->isValidContext(context))
+ {
+ return Error(EGL_BAD_CONTEXT);
+ }
+
+ return Error(EGL_SUCCESS);
+}
+
+Error ValidateCreateContext(Display *display, Config *configuration, gl::Context *shareContext,
+ const AttributeMap& attributes)
+{
+ Error error = ValidateConfig(display, configuration);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ // Get the requested client version (default is 1) and check it is 2 or 3.
+ EGLint clientMajorVersion = 1;
+ EGLint clientMinorVersion = 0;
+ EGLint contextFlags = 0;
+ bool resetNotification = false;
+ bool robustAccess = false;
+ for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
+ {
+ EGLint attribute = attributeIter->first;
+ EGLint value = attributeIter->second;
+
+ switch (attribute)
+ {
+ case EGL_CONTEXT_CLIENT_VERSION:
+ clientMajorVersion = value;
+ break;
+
+ case EGL_CONTEXT_MINOR_VERSION:
+ clientMinorVersion = value;
+ break;
+
+ case EGL_CONTEXT_FLAGS_KHR:
+ contextFlags = value;
+ break;
+
+ case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
+ // Only valid for OpenGL (non-ES) contexts
+ return Error(EGL_BAD_ATTRIBUTE);
+
+ case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
+ if (!display->getExtensions().createContextRobustness)
+ {
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ robustAccess = (value == EGL_TRUE);
+ break;
+
+ case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
+ static_assert(EGL_LOSE_CONTEXT_ON_RESET_EXT == EGL_LOSE_CONTEXT_ON_RESET_KHR, "EGL extension enums not equal.");
+ static_assert(EGL_NO_RESET_NOTIFICATION_EXT == EGL_NO_RESET_NOTIFICATION_KHR, "EGL extension enums not equal.");
+ // same as EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, fall through
+ case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
+ if (!display->getExtensions().createContextRobustness)
+ {
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ if (value == EGL_LOSE_CONTEXT_ON_RESET_EXT)
+ {
+ resetNotification = true;
+ }
+ else if (value != EGL_NO_RESET_NOTIFICATION_EXT)
+ {
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ break;
+
+ default:
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ }
+
+ if ((clientMajorVersion != 2 && clientMajorVersion != 3) || clientMinorVersion != 0)
+ {
+ return Error(EGL_BAD_CONFIG);
+ }
+
+ if (clientMajorVersion == 3 && !(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR) && !(configuration->configCaveat & EGL_NON_CONFORMANT_CONFIG))
+ {
+ return Error(EGL_BAD_CONFIG);
+ }
+
+ // Note: EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR does not apply to ES
+ const EGLint validContextFlags = (EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR |
+ EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR);
+ if ((contextFlags & ~validContextFlags) != 0)
+ {
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+
+ if ((contextFlags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) > 0)
+ {
+ robustAccess = true;
+ }
+
+ if (robustAccess)
+ {
+ // Unimplemented
+ return Error(EGL_BAD_CONFIG);
+ }
+
+ if (shareContext)
+ {
+ // Shared context is invalid or is owned by another display
+ if (!display->isValidContext(shareContext))
+ {
+ return Error(EGL_BAD_MATCH);
+ }
+
+ if (shareContext->isResetNotificationEnabled() != resetNotification)
+ {
+ return Error(EGL_BAD_MATCH);
+ }
+
+ if (shareContext->getClientVersion() != clientMajorVersion)
+ {
+ return Error(EGL_BAD_CONTEXT);
+ }
+ }
+
+ return Error(EGL_SUCCESS);
+}
+
+Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWindowType window,
+ const AttributeMap& attributes)
+{
+ Error error = ValidateConfig(display, config);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ if (!display->isValidNativeWindow(window))
+ {
+ return Error(EGL_BAD_NATIVE_WINDOW);
+ }
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+
+ for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
+ {
+ EGLint attribute = attributeIter->first;
+ EGLint value = attributeIter->second;
+
+ switch (attribute)
+ {
+ case EGL_RENDER_BUFFER:
+ switch (value)
+ {
+ case EGL_BACK_BUFFER:
+ break;
+ case EGL_SINGLE_BUFFER:
+ return Error(EGL_BAD_MATCH); // Rendering directly to front buffer not supported
+ default:
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ break;
+
+ case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
+ if (!displayExtensions.postSubBuffer)
+ {
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ break;
+
+ case EGL_WIDTH:
+ case EGL_HEIGHT:
+ if (!displayExtensions.windowFixedSize)
+ {
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ if (value < 0)
+ {
+ return Error(EGL_BAD_PARAMETER);
+ }
+ break;
+
+ case EGL_FIXED_SIZE_ANGLE:
+ if (!displayExtensions.windowFixedSize)
+ {
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ break;
+
+ case EGL_VG_COLORSPACE:
+ return Error(EGL_BAD_MATCH);
+
+ case EGL_VG_ALPHA_FORMAT:
+ return Error(EGL_BAD_MATCH);
+
+ default:
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ }
+
+ if (Display::hasExistingWindowSurface(window))
+ {
+ return Error(EGL_BAD_ALLOC);
+ }
+
+ return Error(EGL_SUCCESS);
+}
+
+Error ValidateCreatePbufferSurface(Display *display, Config *config, const AttributeMap& attributes)
+{
+ Error error = ValidateConfig(display, config);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
+ {
+ EGLint attribute = attributeIter->first;
+ EGLint value = attributeIter->second;
+
+ switch (attribute)
+ {
+ case EGL_WIDTH:
+ case EGL_HEIGHT:
+ if (value < 0)
+ {
+ return Error(EGL_BAD_PARAMETER);
+ }
+ 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:
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ break;
+
+ case EGL_TEXTURE_TARGET:
+ switch (value)
+ {
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_2D:
+ break;
+ default:
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ break;
+
+ case EGL_MIPMAP_TEXTURE:
+ break;
+
+ case EGL_VG_COLORSPACE:
+ break;
+
+ case EGL_VG_ALPHA_FORMAT:
+ break;
+
+ default:
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ }
+
+ if (!(config->surfaceType & EGL_PBUFFER_BIT))
+ {
+ return Error(EGL_BAD_MATCH);
+ }
+
+ const Caps &caps = display->getCaps();
+
+ EGLenum textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
+ EGLenum 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))
+ {
+ return Error(EGL_BAD_MATCH);
+ }
+
+ if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) ||
+ (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
+ {
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+
+ EGLint width = attributes.get(EGL_WIDTH, 0);
+ EGLint height = attributes.get(EGL_HEIGHT, 0);
+ if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
+ {
+ return Error(EGL_BAD_MATCH);
+ }
+
+ return Error(EGL_SUCCESS);
+}
+
+Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, EGLClientBuffer buffer,
+ Config *config, const AttributeMap& attributes)
+{
+ Error error = ValidateConfig(display, config);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+
+ switch (buftype)
+ {
+ case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
+ if (!displayExtensions.d3dShareHandleClientBuffer)
+ {
+ return Error(EGL_BAD_PARAMETER);
+ }
+ if (buffer == nullptr)
+ {
+ return Error(EGL_BAD_PARAMETER);
+ }
+ break;
+
+ default:
+ return Error(EGL_BAD_PARAMETER);
+ }
+
+ for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++)
+ {
+ EGLint attribute = attributeIter->first;
+ EGLint value = attributeIter->second;
+
+ switch (attribute)
+ {
+ case EGL_WIDTH:
+ case EGL_HEIGHT:
+ if (!displayExtensions.d3dShareHandleClientBuffer)
+ {
+ return Error(EGL_BAD_PARAMETER);
+ }
+ if (value < 0)
+ {
+ return Error(EGL_BAD_PARAMETER);
+ }
+ break;
+
+ case EGL_TEXTURE_FORMAT:
+ switch (value)
+ {
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_RGB:
+ case EGL_TEXTURE_RGBA:
+ break;
+ default:
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ break;
+
+ case EGL_TEXTURE_TARGET:
+ switch (value)
+ {
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_2D:
+ break;
+ default:
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ break;
+
+ case EGL_MIPMAP_TEXTURE:
+ break;
+
+ default:
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+ }
+
+ if (!(config->surfaceType & EGL_PBUFFER_BIT))
+ {
+ return Error(EGL_BAD_MATCH);
+ }
+
+ EGLenum textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
+ EGLenum 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))
+ {
+ return Error(EGL_BAD_MATCH);
+ }
+
+ if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) ||
+ (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
+ {
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+
+ if (buftype == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE)
+ {
+ EGLint width = attributes.get(EGL_WIDTH, 0);
+ EGLint height = attributes.get(EGL_HEIGHT, 0);
+
+ if (width == 0 || height == 0)
+ {
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) // On Windows Store, we know the originating texture came from D3D11, so bypass this check
+ const Caps &caps = display->getCaps();
+ if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
+ {
+ return Error(EGL_BAD_MATCH);
+ }
+#endif
+ }
+
+ return Error(EGL_SUCCESS);
+}
+
+}
diff --git a/src/3rdparty/angle/src/libANGLE/validationEGL.h b/src/3rdparty/angle/src/libANGLE/validationEGL.h
new file mode 100644
index 0000000000..4daff791fd
--- /dev/null
+++ b/src/3rdparty/angle/src/libANGLE/validationEGL.h
@@ -0,0 +1,49 @@
+//
+// Copyright (c) 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 "libANGLE/Error.h"
+
+#include <EGL/egl.h>
+
+namespace gl
+{
+class Context;
+}
+
+namespace egl
+{
+
+class AttributeMap;
+struct Config;
+class Display;
+class Surface;
+
+// Object validation
+Error ValidateDisplay(const Display *display);
+Error ValidateSurface(const Display *display, Surface *surface);
+Error ValidateConfig(const Display *display, const Config *config);
+Error ValidateContext(const Display *display, gl::Context *context);
+
+// Entry point validation
+Error ValidateCreateContext(Display *display, Config *configuration, gl::Context *shareContext,
+ const AttributeMap& attributes);
+
+Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWindowType window,
+ const AttributeMap& attributes);
+
+Error ValidateCreatePbufferSurface(Display *display, Config *config, const AttributeMap& attributes);
+Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, EGLClientBuffer buffer,
+ Config *config, const AttributeMap& attributes);
+
+
+}
+
+#endif // LIBANGLE_VALIDATIONEGL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES.cpp b/src/3rdparty/angle/src/libANGLE/validationES.cpp
index 265f4b4fba..d267cbf2e6 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES.cpp
+++ b/src/3rdparty/angle/src/libANGLE/validationES.cpp
@@ -6,27 +6,24 @@
// validationES.h: Validation functions for generic OpenGL ES entry point parameters
-#include "libGLESv2/validationES.h"
-#include "libGLESv2/validationES2.h"
-#include "libGLESv2/validationES3.h"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/Query.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/TransformFeedback.h"
-#include "libGLESv2/VertexArray.h"
-#include "libGLESv2/renderer/BufferImpl.h"
+#include "libANGLE/validationES.h"
+#include "libANGLE/validationES2.h"
+#include "libANGLE/validationES3.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Query.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Uniform.h"
+#include "libANGLE/TransformFeedback.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/renderer/BufferImpl.h"
#include "common/mathutil.h"
#include "common/utilities.h"
-// FIXME(jmadill): remove this when we support buffer data caching
-#include "libGLESv2/renderer/d3d/BufferD3D.h"
-
namespace gl
{
@@ -95,7 +92,8 @@ bool ValidTexture2DDestinationTarget(const Context *context, GLenum target)
bool ValidFramebufferTarget(GLenum target)
{
- META_ASSERT(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER && GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER);
+ 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)
{
@@ -212,8 +210,8 @@ bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLs
bool ValidQueryType(const Context *context, GLenum queryType)
{
- META_ASSERT(GL_ANY_SAMPLES_PASSED == GL_ANY_SAMPLES_PASSED_EXT);
- META_ASSERT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);
+ static_assert(GL_ANY_SAMPLES_PASSED == GL_ANY_SAMPLES_PASSED_EXT, "GL extension enums not equal.");
+ static_assert(GL_ANY_SAMPLES_PASSED_CONSERVATIVE == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, "GL extension enums not equal.");
switch (queryType)
{
@@ -288,9 +286,8 @@ bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment)
return true;
}
-bool ValidateRenderbufferStorageParameters(gl::Context *context, GLenum target, GLsizei samples,
- GLenum internalformat, GLsizei width, GLsizei height,
- bool angleExtension)
+bool ValidateRenderbufferStorageParametersBase(gl::Context *context, GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width, GLsizei height)
{
switch (target)
{
@@ -316,8 +313,7 @@ bool ValidateRenderbufferStorageParameters(gl::Context *context, GLenum target,
// 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. The ES3 spec (section 4.4.2) does, however, state that the
- // internal format must be sized and not an integer format if samples is greater than zero.
+ // only sized internal formats.
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
if (formatInfo.pixelBytes == 0)
{
@@ -325,55 +321,47 @@ bool ValidateRenderbufferStorageParameters(gl::Context *context, GLenum target,
return false;
}
- if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT) && samples > 0)
+ if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
{
- context->recordError(Error(GL_INVALID_OPERATION));
+ context->recordError(Error(GL_INVALID_VALUE));
return false;
}
- if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
+ GLuint handle = context->getState().getRenderbufferId();
+ if (handle == 0)
{
- context->recordError(Error(GL_INVALID_VALUE));
+ context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
- // to MAX_SAMPLES_ANGLE (Context::getMaxSupportedSamples) while the ES3.0 spec (section 4.4.2)
- // states that samples must be less than or equal to the maximum samples for the specified
- // internal format.
- if (angleExtension)
- {
- ASSERT(context->getExtensions().framebufferMultisample);
- if (static_cast<GLuint>(samples) > context->getExtensions().maxSamples)
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
+ return true;
+}
- // Check if this specific format supports enough samples
- if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
- {
- context->recordError(Error(GL_OUT_OF_MEMORY));
- return false;
- }
- }
- else
+bool ValidateRenderbufferStorageParametersANGLE(gl::Context *context, GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width, GLsizei height)
+{
+ ASSERT(samples == 0 || context->getExtensions().framebufferMultisample);
+
+ // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
+ // to MAX_SAMPLES_ANGLE (Context::getExtensions().maxSamples) otherwise GL_INVALID_VALUE is
+ // generated.
+ if (static_cast<GLuint>(samples) > context->getExtensions().maxSamples)
{
- if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
- GLuint handle = context->getState().getRenderbufferId();
- if (handle == 0)
+ // 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.
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
+ if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
{
- context->recordError(Error(GL_INVALID_OPERATION));
+ context->recordError(Error(GL_OUT_OF_MEMORY));
return false;
}
- return true;
+ return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat, width, height);
}
bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum target, GLenum attachment,
@@ -507,13 +495,13 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
return false;
}
- if (!readFramebuffer->completeness(context->getData()))
+ if (!readFramebuffer->checkStatus(context->getData()))
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
}
- if (!drawFramebuffer->completeness(context->getData()))
+ if (!drawFramebuffer->checkStatus(context->getData()))
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
@@ -534,14 +522,14 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (readColorBuffer && drawColorBuffer)
{
- GLenum readInternalFormat = readColorBuffer->getActualFormat();
+ GLenum readInternalFormat = readColorBuffer->getInternalFormat();
const InternalFormat &readFormatInfo = GetInternalFormatInfo(readInternalFormat);
- for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
+ for (GLuint i = 0; i < context->getCaps().maxColorAttachments; i++)
{
if (drawFramebuffer->isEnabledColorAttachment(i))
{
- GLenum drawInternalFormat = drawFramebuffer->getColorbuffer(i)->getActualFormat();
+ GLenum drawInternalFormat = drawFramebuffer->getColorbuffer(i)->getInternalFormat();
const InternalFormat &drawFormatInfo = GetInternalFormatInfo(drawInternalFormat);
// The GL ES 3.0.2 spec (pg 193) states that:
@@ -583,21 +571,26 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
if (fromAngleExtension)
{
- const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
- if (readColorbufferType != GL_TEXTURE_2D && readColorbufferType != GL_RENDERBUFFER)
+ FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
+ if (!readColorAttachment ||
+ (!(readColorAttachment->type() == GL_TEXTURE && readColorAttachment->getTextureImageIndex()->type == GL_TEXTURE_2D) &&
+ readColorAttachment->type() != GL_RENDERBUFFER &&
+ readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT))
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+ for (GLuint colorAttachment = 0; colorAttachment < context->getCaps().maxColorAttachments; ++colorAttachment)
{
if (drawFramebuffer->isEnabledColorAttachment(colorAttachment))
{
FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(colorAttachment);
ASSERT(attachment);
- if (attachment->type() != GL_TEXTURE_2D && attachment->type() != GL_RENDERBUFFER)
+ if (!(attachment->type() == GL_TEXTURE && attachment->getTextureImageIndex()->type == GL_TEXTURE_2D) &&
+ attachment->type() != GL_RENDERBUFFER &&
+ attachment->type() != GL_FRAMEBUFFER_DEFAULT)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -625,77 +618,44 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
}
}
- if (mask & GL_DEPTH_BUFFER_BIT)
+ 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++)
{
- gl::FramebufferAttachment *readDepthBuffer = readFramebuffer->getDepthbuffer();
- gl::FramebufferAttachment *drawDepthBuffer = drawFramebuffer->getDepthbuffer();
-
- if (readDepthBuffer && drawDepthBuffer)
+ if (mask & masks[i])
{
- if (readDepthBuffer->getActualFormat() != drawDepthBuffer->getActualFormat())
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
+ gl::FramebufferAttachment *readBuffer = readFramebuffer->getAttachment(attachments[i]);
+ gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getAttachment(attachments[i]);
- if (readDepthBuffer->getSamples() > 0 && !sameBounds)
+ if (readBuffer && drawBuffer)
{
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- if (fromAngleExtension)
- {
- if (IsPartialBlit(context, readDepthBuffer, drawDepthBuffer,
- srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
+ if (readBuffer->getInternalFormat() != drawBuffer->getInternalFormat())
{
- ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
- context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted
+ context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- if (readDepthBuffer->getSamples() != 0 || drawDepthBuffer->getSamples() != 0)
+ if (readBuffer->getSamples() > 0 && !sameBounds)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- }
- }
- }
-
- if (mask & GL_STENCIL_BUFFER_BIT)
- {
- gl::FramebufferAttachment *readStencilBuffer = readFramebuffer->getStencilbuffer();
- gl::FramebufferAttachment *drawStencilBuffer = drawFramebuffer->getStencilbuffer();
-
- if (readStencilBuffer && drawStencilBuffer)
- {
- if (readStencilBuffer->getActualFormat() != drawStencilBuffer->getActualFormat())
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
- if (readStencilBuffer->getSamples() > 0 && !sameBounds)
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- if (fromAngleExtension)
- {
- if (IsPartialBlit(context, readStencilBuffer, drawStencilBuffer,
- srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
+ if (fromAngleExtension)
{
- ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
- context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted
- return false;
- }
+ if (IsPartialBlit(context, readBuffer, drawBuffer,
+ srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
+ {
+ ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
+ context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted
+ return false;
+ }
- if (readStencilBuffer->getSamples() != 0 || drawStencilBuffer->getSamples() != 0)
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
+ if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
}
}
}
@@ -720,7 +680,8 @@ bool ValidateGetVertexAttribParameters(Context *context, GLenum pname)
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
// Don't verify ES3 context because GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE uses
// the same constant.
- META_ASSERT(GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE);
+ static_assert(GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
+ "ANGLE extension enums not equal to GL enums.");
return true;
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
@@ -931,7 +892,7 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize
gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
ASSERT(framebuffer);
- if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
@@ -944,17 +905,18 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize
return false;
}
- if (!framebuffer->getReadColorbuffer())
+ const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
+ if (!readBuffer)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- GLenum currentInternalFormat, currentFormat, currentType;
+ GLenum currentFormat = framebuffer->getImplementationColorReadFormat();
+ GLenum currentType = framebuffer->getImplementationColorReadType();
+ GLenum currentInternalFormat = readBuffer->getInternalFormat();
GLuint clientVersion = context->getClientVersion();
- context->getCurrentReadFormatType(&currentInternalFormat, &currentFormat, &currentType);
-
bool validReadFormat = (clientVersion < 3) ? ValidES2ReadFormatType(context, format, type) :
ValidES3ReadFormatType(context, currentInternalFormat, format, type);
@@ -967,7 +929,7 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize
GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
- GLsizei outputPitch = sizedFormatInfo.computeRowPitch(type, width, context->getState().getPackAlignment());
+ GLsizei outputPitch = sizedFormatInfo.computeRowPitch(type, width, context->getState().getPackAlignment(), 0);
// sized query sanity check
if (bufSize)
{
@@ -1064,8 +1026,8 @@ static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniform
return false;
}
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- if (!programBinary)
+ gl::Program *program = context->getState().getProgram();
+ if (!program)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1077,13 +1039,13 @@ static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniform
return false;
}
- if (!programBinary->isValidUniformLocation(location))
+ if (!program->isValidUniformLocation(location))
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- LinkedUniform *uniform = programBinary->getUniformByLocation(location);
+ LinkedUniform *uniform = program->getUniformByLocation(location);
// attempting to write an array to a non-array uniform is an INVALID_OPERATION
if (uniform->elementCount() == 1 && count > 1)
@@ -1112,7 +1074,7 @@ bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, G
}
GLenum targetBoolType = VariableBoolVectorType(uniformType);
- bool samplerUniformCheck = (IsSampler(uniform->type) && uniformType == GL_INT);
+ bool samplerUniformCheck = (IsSamplerType(uniform->type) && uniformType == GL_INT);
if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type)
{
context->recordError(Error(GL_INVALID_OPERATION));
@@ -1163,11 +1125,13 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
return false;
}
+ const Caps &caps = context->getCaps();
+
if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
{
unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
- if (colorAttachment >= context->getCaps().maxDrawBuffers)
+ if (colorAttachment >= caps.maxDrawBuffers)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1180,7 +1144,7 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
case GL_TEXTURE_BINDING_CUBE_MAP:
case GL_TEXTURE_BINDING_3D:
case GL_TEXTURE_BINDING_2D_ARRAY:
- if (context->getState().getActiveSampler() >= context->getCaps().maxCombinedTextureImageUnits)
+ if (context->getState().getActiveSampler() >= caps.maxCombinedTextureImageUnits)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1192,7 +1156,7 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType,
{
Framebuffer *framebuffer = context->getState().getReadFramebuffer();
ASSERT(framebuffer);
- if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1256,7 +1220,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
}
gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
- if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
@@ -1270,28 +1234,11 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
const gl::Caps &caps = context->getCaps();
- gl::Texture *texture = NULL;
- GLenum textureInternalFormat = GL_NONE;
- GLint textureLevelWidth = 0;
- GLint textureLevelHeight = 0;
- GLint textureLevelDepth = 0;
GLuint maxDimension = 0;
-
switch (target)
{
case GL_TEXTURE_2D:
- {
- gl::Texture2D *texture2d = context->getTexture2D();
- if (texture2d)
- {
- textureInternalFormat = texture2d->getInternalFormat(level);
- textureLevelWidth = texture2d->getWidth(level);
- textureLevelHeight = texture2d->getHeight(level);
- textureLevelDepth = 1;
- texture = texture2d;
- maxDimension = caps.max2DTextureSize;
- }
- }
+ maxDimension = caps.max2DTextureSize;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
@@ -1300,48 +1247,15 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- {
- gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
- if (textureCube)
- {
- textureInternalFormat = textureCube->getInternalFormat(target, level);
- textureLevelWidth = textureCube->getWidth(target, level);
- textureLevelHeight = textureCube->getHeight(target, level);
- textureLevelDepth = 1;
- texture = textureCube;
- maxDimension = caps.maxCubeMapTextureSize;
- }
- }
+ maxDimension = caps.maxCubeMapTextureSize;
break;
case GL_TEXTURE_2D_ARRAY:
- {
- gl::Texture2DArray *texture2dArray = context->getTexture2DArray();
- if (texture2dArray)
- {
- textureInternalFormat = texture2dArray->getInternalFormat(level);
- textureLevelWidth = texture2dArray->getWidth(level);
- textureLevelHeight = texture2dArray->getHeight(level);
- textureLevelDepth = texture2dArray->getLayers(level);
- texture = texture2dArray;
- maxDimension = caps.max2DTextureSize;
- }
- }
+ maxDimension = caps.max2DTextureSize;
break;
case GL_TEXTURE_3D:
- {
- gl::Texture3D *texture3d = context->getTexture3D();
- if (texture3d)
- {
- textureInternalFormat = texture3d->getInternalFormat(level);
- textureLevelWidth = texture3d->getWidth(level);
- textureLevelHeight = texture3d->getHeight(level);
- textureLevelDepth = texture3d->getDepth(level);
- texture = texture3d;
- maxDimension = caps.max3DTextureSize;
- }
- }
+ maxDimension = caps.max3DTextureSize;
break;
default:
@@ -1349,6 +1263,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
return false;
}
+ gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
if (!texture)
{
context->recordError(Error(GL_INVALID_OPERATION));
@@ -1369,21 +1284,17 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
return false;
}
- if (formatInfo.compressed)
+ if (formatInfo.compressed && !ValidCompressedImageSize(context, internalformat, width, height))
{
- if (((width % formatInfo.compressedBlockWidth) != 0 && width != textureLevelWidth) ||
- ((height % formatInfo.compressedBlockHeight) != 0 && height != textureLevelHeight))
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
}
if (isSubImage)
{
- if (xoffset + width > textureLevelWidth ||
- yoffset + height > textureLevelHeight ||
- zoffset >= textureLevelDepth)
+ 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->recordError(Error(GL_INVALID_VALUE));
return false;
@@ -1391,7 +1302,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
}
else
{
- if (IsCubemapTextureTarget(target) && width != height)
+ if (IsCubeMapTextureTarget(target) && width != height)
{
context->recordError(Error(GL_INVALID_VALUE));
return false;
@@ -1411,7 +1322,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
}
}
- *textureFormatOut = textureInternalFormat;
+ *textureFormatOut = texture->getInternalFormat(target, level);
return true;
}
@@ -1461,20 +1372,20 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz
}
const gl::Framebuffer *fbo = state.getDrawFramebuffer();
- if (!fbo || fbo->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
+ if (!fbo || fbo->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
}
- if (state.getCurrentProgramId() == 0)
+ gl::Program *program = state.getProgram();
+ if (!program)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
- if (!programBinary->validateSamplers(NULL, context->getCaps()))
+ if (!program->validateSamplers(NULL, context->getCaps()))
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1485,7 +1396,7 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex);
- bool attribActive = (programBinary->getSemanticIndex(attributeIndex) != -1);
+ bool attribActive = (program->getSemanticIndex(attributeIndex) != -1);
if (attribActive && attrib.enabled)
{
gl::Buffer *buffer = attrib.buffer.get();
@@ -1525,6 +1436,36 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz
}
}
+ // Uniform buffer validation
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
+ {
+ const gl::UniformBlock *uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
+ GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
+ const gl::Buffer *uniformBuffer = state.getIndexedUniformBuffer(blockBinding);
+
+ if (!uniformBuffer)
+ {
+ // undefined behaviour
+ context->recordError(Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer."));
+ return false;
+ }
+
+ size_t uniformBufferSize = state.getIndexedUniformBufferSize(blockBinding);
+
+ if (uniformBufferSize == 0)
+ {
+ // Bind the whole buffer.
+ uniformBufferSize = uniformBuffer->getSize();
+ }
+
+ if (uniformBufferSize < uniformBlock->dataSize)
+ {
+ // undefined behaviour
+ context->recordError(Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small."));
+ return false;
+ }
+ }
+
// No-op if zero count
return (count > 0);
}
@@ -1579,13 +1520,13 @@ static bool ValidateDrawInstancedANGLE(Context *context)
// Verify there is at least one active attribute with a divisor of zero
const gl::State& state = context->getState();
- gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
+ gl::Program *program = state.getProgram();
const VertexArray *vao = state.getVertexArray();
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex);
- bool active = (programBinary->getSemanticIndex(attributeIndex) != -1);
+ bool active = (program->getSemanticIndex(attributeIndex) != -1);
if (active && attrib.divisor == 0)
{
return true;
@@ -1646,7 +1587,7 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t
}
const gl::VertexArray *vao = state.getVertexArray();
- const gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+ gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
if (!indices && !elementArrayBuffer)
{
context->recordError(Error(GL_INVALID_OPERATION));
@@ -1688,12 +1629,11 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t
if (elementArrayBuffer)
{
uintptr_t offset = reinterpret_cast<uintptr_t>(indices);
- if (!elementArrayBuffer->getIndexRangeCache()->findRange(type, offset, count, indexRangeOut, NULL))
+ if (!elementArrayBuffer->getIndexRangeCache()->findRange(type, offset, count, indexRangeOut))
{
- // FIXME(jmadill): Use buffer data caching instead of the D3D back-end
- rx::BufferD3D *bufferD3D = rx::BufferD3D::makeBufferD3D(elementArrayBuffer->getImplementation());
+ rx::BufferImpl *bufferImpl = elementArrayBuffer->getImplementation();
const uint8_t *dataPointer = NULL;
- Error error = bufferD3D->getData(&dataPointer);
+ Error error = bufferImpl->getData(&dataPointer);
if (error.isError())
{
context->recordError(error);
@@ -1702,6 +1642,7 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t
const uint8_t *offsetPointer = dataPointer + offset;
*indexRangeOut = rx::IndexRangeCache::ComputeRange(type, offsetPointer, count);
+ elementArrayBuffer->getIndexRangeCache()->addRange(type, offset, count, *indexRangeOut);
}
}
else
@@ -1827,12 +1768,6 @@ bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attach
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
- if (tex2d->isCompressed(level))
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
}
break;
@@ -1853,12 +1788,6 @@ bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attach
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
- if (texcube->isCompressed(textarget, level))
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
}
break;
@@ -1866,6 +1795,13 @@ bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attach
context->recordError(Error(GL_INVALID_ENUM));
return false;
}
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(tex->getInternalFormat(textarget, level));
+ if (internalFormatInfo.compressed)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
}
return true;
@@ -1892,14 +1828,7 @@ bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
return false;
}
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programBinary)
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- if (!programBinary->isValidUniformLocation(location))
+ if (!programObject->isValidUniformLocation(location))
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -1927,10 +1856,9 @@ static bool ValidateSizedGetUniform(Context *context, GLuint program, GLint loca
gl::Program *programObject = context->getProgram(program);
ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
// sized queries -- ensure the provided buffer is large enough
- LinkedUniform *uniform = programBinary->getUniformByLocation(location);
+ LinkedUniform *uniform = programObject->getUniformByLocation(location);
size_t requiredBytes = VariableExternalSize(uniform->type);
if (static_cast<size_t>(bufSize) < requiredBytes)
{
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES.h b/src/3rdparty/angle/src/libANGLE/validationES.h
index 1fdb633cb6..b0ccd8eecc 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES.h
+++ b/src/3rdparty/angle/src/libANGLE/validationES.h
@@ -6,8 +6,8 @@
// validationES.h: Validation functions for generic OpenGL ES entry point parameters
-#ifndef LIBGLESV2_VALIDATION_ES_H
-#define LIBGLESV2_VALIDATION_ES_H
+#ifndef LIBANGLE_VALIDATION_ES_H_
+#define LIBANGLE_VALIDATION_ES_H_
#include "common/mathutil.h"
@@ -32,9 +32,11 @@ bool ValidQueryType(const Context *context, GLenum queryType);
bool ValidProgram(Context *context, GLuint id);
bool ValidateAttachmentTarget(Context *context, GLenum attachment);
-bool ValidateRenderbufferStorageParameters(Context *context, GLenum target, GLsizei samples,
- GLenum internalformat, GLsizei width, GLsizei height,
- bool angleExtension);
+bool ValidateRenderbufferStorageParametersBase(Context *context, GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width, GLsizei height);
+bool ValidateRenderbufferStorageParametersANGLE(Context *context, GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width, GLsizei height);
+
bool ValidateFramebufferRenderbufferParameters(Context *context, GLenum target, GLenum attachment,
GLenum renderbuffertarget, GLuint renderbuffer);
@@ -49,7 +51,7 @@ bool ValidateTexParamParameters(Context *context, GLenum pname, GLint param);
bool ValidateSamplerObjectParameter(Context *context, GLenum pname);
bool ValidateReadPixelsParameters(Context *context, GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels);
+ GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels);
bool ValidateBeginQuery(Context *context, GLenum target, GLuint id);
bool ValidateEndQuery(Context *context, GLenum target);
@@ -61,8 +63,8 @@ bool ValidateUniformMatrix(Context *context, GLenum matrixType, GLint location,
bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams);
bool ValidateCopyTexImageParametersBase(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
- GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border, GLenum *textureInternalFormatOut);
+ GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height,
+ GLint border, GLenum *textureInternalFormatOut);
bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
@@ -79,7 +81,7 @@ bool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei c
bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment,
GLuint texture, GLint level);
bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level);
+ GLenum textarget, GLuint texture, GLint level);
bool ValidateGetUniformBase(Context *context, GLuint program, GLint location);
bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat* params);
@@ -89,4 +91,4 @@ bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location,
}
-#endif // LIBGLESV2_VALIDATION_ES_H
+#endif // LIBANGLE_VALIDATION_ES_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES2.cpp b/src/3rdparty/angle/src/libANGLE/validationES2.cpp
index f950454df0..9eece1b54a 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES2.cpp
+++ b/src/3rdparty/angle/src/libANGLE/validationES2.cpp
@@ -6,15 +6,14 @@
// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
-#include "libGLESv2/validationES2.h"
-#include "libGLESv2/validationES.h"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/FramebufferAttachment.h"
+#include "libANGLE/validationES2.h"
+#include "libANGLE/validationES.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/FramebufferAttachment.h"
#include "common/mathutil.h"
#include "common/utilities.h"
@@ -22,227 +21,118 @@
namespace gl
{
-static bool ValidateSubImageParams2D(Context *context, bool compressed, GLsizei width, GLsizei height,
- GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type,
- gl::Texture2D *texture)
+bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
+ GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
- if (!texture)
+ if (!ValidTexture2DDestinationTarget(context, target))
{
- context->recordError(Error(GL_INVALID_OPERATION));
+ context->recordError(Error(GL_INVALID_ENUM));
return false;
}
- if (compressed != texture->isCompressed(level))
+ if (!ValidImageSize(context, target, level, width, height, 1))
{
- context->recordError(Error(GL_INVALID_OPERATION));
+ context->recordError(Error(GL_INVALID_VALUE));
return false;
}
- if (format != GL_NONE)
- {
- if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(level))
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
- }
-
- if (compressed)
- {
- if ((width % 4 != 0 && width != texture->getWidth(level)) ||
- (height % 4 != 0 && height != texture->getHeight(level)))
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
- }
-
- if (xoffset + width > texture->getWidth(level) ||
- yoffset + height > texture->getHeight(level))
+ if (level < 0 || xoffset < 0 ||
+ std::numeric_limits<GLsizei>::max() - xoffset < width ||
+ std::numeric_limits<GLsizei>::max() - yoffset < height)
{
context->recordError(Error(GL_INVALID_VALUE));
return false;
}
- return true;
-}
-
-static bool ValidateSubImageParamsCube(Context *context, bool compressed, GLsizei width, GLsizei height,
- GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type,
- gl::TextureCubeMap *texture)
-{
- if (!texture)
+ if (!isSubImage && !isCompressed && internalformat != format)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- if (compressed != texture->isCompressed(target, level))
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
+ const gl::Caps &caps = context->getCaps();
- if (format != GL_NONE)
+ if (target == GL_TEXTURE_2D)
{
- if (gl::GetFormatTypeInfo(format, type).internalFormat != texture->getInternalFormat(target, level))
+ if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
+ static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
{
- context->recordError(Error(GL_INVALID_OPERATION));
+ context->recordError(Error(GL_INVALID_VALUE));
return false;
}
}
-
- if (compressed)
+ else if (IsCubeMapTextureTarget(target))
{
- if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
- (height % 4 != 0 && height != texture->getHeight(target, 0)))
+ if (!isSubImage && width != height)
{
- context->recordError(Error(GL_INVALID_OPERATION));
+ context->recordError(Error(GL_INVALID_VALUE));
return false;
}
- }
- if (xoffset + width > texture->getWidth(target, level) ||
- yoffset + height > texture->getHeight(target, level))
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
+ if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
+ static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
+ }
}
-
- return true;
-}
-
-bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage,
- GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- if (!ValidTexture2DDestinationTarget(context, target))
+ else
{
context->recordError(Error(GL_INVALID_ENUM));
return false;
}
- if (!ValidImageSize(context, target, level, width, height, 1))
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
-
- if (level < 0 || xoffset < 0 ||
- std::numeric_limits<GLsizei>::max() - xoffset < width ||
- std::numeric_limits<GLsizei>::max() - yoffset < height)
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
-
- if (!isSubImage && !isCompressed && internalformat != format)
+ gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ if (!texture)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- const gl::Caps &caps = context->getCaps();
-
- gl::Texture *texture = NULL;
- bool textureCompressed = false;
- GLenum textureInternalFormat = GL_NONE;
- GLint textureLevelWidth = 0;
- GLint textureLevelHeight = 0;
- switch (target)
+ if (isSubImage)
{
- case GL_TEXTURE_2D:
+ if (format != GL_NONE)
{
- if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
- static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
-
- gl::Texture2D *tex2d = context->getTexture2D();
- if (tex2d)
- {
- textureCompressed = tex2d->isCompressed(level);
- textureInternalFormat = tex2d->getInternalFormat(level);
- textureLevelWidth = tex2d->getWidth(level);
- textureLevelHeight = tex2d->getHeight(level);
- texture = tex2d;
- }
-
- if (isSubImage && !ValidateSubImageParams2D(context, isCompressed, width, height, xoffset, yoffset,
- level, format, type, tex2d))
+ if (gl::GetSizedInternalFormat(format, type) != texture->getInternalFormat(target, level))
{
+ context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
-
- texture = tex2d;
}
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
+ static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
{
- if (!isSubImage && width != height)
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
-
- if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
- static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
-
- gl::TextureCubeMap *texCube = context->getTextureCubeMap();
- if (texCube)
- {
- textureCompressed = texCube->isCompressed(target, level);
- textureInternalFormat = texCube->getInternalFormat(target, level);
- textureLevelWidth = texCube->getWidth(target, level);
- textureLevelHeight = texCube->getHeight(target, level);
- texture = texCube;
- }
-
- if (isSubImage && !ValidateSubImageParamsCube(context, isCompressed, width, height, xoffset, yoffset,
- target, level, format, type, texCube))
- {
- return false;
- }
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
- break;
-
- default:
- context->recordError(Error(GL_INVALID_ENUM));
- return false;
}
-
- if (!texture)
+ else
{
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
+ if (texture->isImmutable())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
}
- if (!isSubImage && texture->isImmutable())
+ // Verify zero border
+ if (border != 0)
{
- context->recordError(Error(GL_INVALID_OPERATION));
+ context->recordError(Error(GL_INVALID_VALUE));
return false;
}
- // Verify zero border
- if (border != 0)
+ GLenum actualInternalFormat = isSubImage ? texture->getInternalFormat(target, level) : internalformat;
+ const InternalFormat &actualFormatInfo = GetInternalFormatInfo(actualInternalFormat);
+
+ if (isCompressed != actualFormatInfo.compressed)
{
- context->recordError(Error(GL_INVALID_VALUE));
+ context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
if (isCompressed)
{
if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
@@ -521,7 +411,8 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat();
- GLenum textureFormat = gl::GetInternalFormatInfo(textureInternalFormat).format;
+ const auto &internalFormatInfo = gl::GetInternalFormatInfo(textureInternalFormat);
+ GLenum textureFormat = internalFormatInfo.format;
// [OpenGL ES 2.0.24] table 3.9
if (isSubImage)
@@ -558,7 +449,11 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
- colorbufferFormat != GL_RGBA8_OES)
+ colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_R32F &&
+ colorbufferFormat != GL_RG32F &&
+ colorbufferFormat != GL_RGB32F &&
+ colorbufferFormat != GL_RGBA32F)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -570,7 +465,10 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
- colorbufferFormat != GL_RGBA8_OES)
+ colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_RG32F &&
+ colorbufferFormat != GL_RGB32F &&
+ colorbufferFormat != GL_RGBA32F)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -581,7 +479,9 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
- colorbufferFormat != GL_RGBA8_OES)
+ colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_RGB32F &&
+ colorbufferFormat != GL_RGBA32F)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -591,7 +491,8 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
case GL_RGBA:
if (colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
- colorbufferFormat != GL_RGBA8_OES)
+ colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_RGBA32F)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -611,6 +512,13 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
+
+ if (internalFormatInfo.type == GL_FLOAT &&
+ !context->getExtensions().textureFloat)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
}
else
{
@@ -621,7 +529,8 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
- colorbufferFormat != GL_RGBA8_OES)
+ colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -635,7 +544,8 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
- colorbufferFormat != GL_RGBA8_OES)
+ colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -649,7 +559,8 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
- colorbufferFormat != GL_RGBA8_OES)
+ colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -662,7 +573,8 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
- colorbufferFormat != GL_RGBA8_OES)
+ colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -674,7 +586,8 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
- colorbufferFormat != GL_RGBA8_OES)
+ colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -685,7 +598,8 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
if (colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_BGRA8_EXT &&
- colorbufferFormat != GL_RGBA8_OES)
+ colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
@@ -903,19 +817,7 @@ bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei le
break;
}
- gl::Texture *texture = NULL;
- switch(target)
- {
- case GL_TEXTURE_2D:
- texture = context->getTexture2D();
- break;
- case GL_TEXTURE_CUBE_MAP:
- texture = context->getTextureCubeMap();
- break;
- default:
- UNREACHABLE();
- }
-
+ gl::Texture *texture = context->getTargetTexture(target);
if (!texture || texture->id() == 0)
{
context->recordError(Error(GL_INVALID_OPERATION));
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES2.h b/src/3rdparty/angle/src/libANGLE/validationES2.h
index 53a0b630ea..b9c1fd3bc4 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES2.h
+++ b/src/3rdparty/angle/src/libANGLE/validationES2.h
@@ -6,8 +6,8 @@
// validationES2.h: Validation functions for OpenGL ES 2.0 entry point parameters
-#ifndef LIBGLESV2_VALIDATION_ES2_H
-#define LIBGLESV2_VALIDATION_ES2_H
+#ifndef LIBANGLE_VALIDATION_ES2_H_
+#define LIBANGLE_VALIDATION_ES2_H_
#include <GLES2/gl2.h>
@@ -25,10 +25,10 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le
GLint border);
bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
- GLsizei width, GLsizei height);
+ GLsizei width, GLsizei height);
bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type);
}
-#endif // LIBGLESV2_VALIDATION_ES2_H
+#endif // LIBANGLE_VALIDATION_ES2_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES3.cpp b/src/3rdparty/angle/src/libANGLE/validationES3.cpp
index 2d3a039e13..e141bb6ece 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES3.cpp
+++ b/src/3rdparty/angle/src/libANGLE/validationES3.cpp
@@ -6,17 +6,17 @@
// validationES3.cpp: Validation functions for OpenGL ES 3.0 entry point parameters
-#include "libGLESv2/validationES3.h"
-#include "libGLESv2/validationES.h"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/FramebufferAttachment.h"
+#include "libANGLE/validationES3.h"
+#include "libANGLE/validationES.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/FramebufferAttachment.h"
#include "common/mathutil.h"
+#include "common/utilities.h"
namespace gl
{
@@ -311,33 +311,14 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level,
const gl::Caps &caps = context->getCaps();
- gl::Texture *texture = NULL;
- bool textureCompressed = false;
- GLenum textureInternalFormat = GL_NONE;
- GLint textureLevelWidth = 0;
- GLint textureLevelHeight = 0;
- GLint textureLevelDepth = 0;
switch (target)
{
case GL_TEXTURE_2D:
+ if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
+ static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
{
- if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
- static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
-
- gl::Texture2D *texture2d = context->getTexture2D();
- if (texture2d)
- {
- textureCompressed = texture2d->isCompressed(level);
- textureInternalFormat = texture2d->getInternalFormat(level);
- textureLevelWidth = texture2d->getWidth(level);
- textureLevelHeight = texture2d->getHeight(level);
- textureLevelDepth = 1;
- texture = texture2d;
- }
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
break;
@@ -347,83 +328,45 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level,
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (!isSubImage && width != height)
{
- if (!isSubImage && width != height)
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
-
- if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level))
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
+ }
- gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
- if (textureCube)
- {
- textureCompressed = textureCube->isCompressed(target, level);
- textureInternalFormat = textureCube->getInternalFormat(target, level);
- textureLevelWidth = textureCube->getWidth(target, level);
- textureLevelHeight = textureCube->getHeight(target, level);
- textureLevelDepth = 1;
- texture = textureCube;
- }
+ if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
break;
case GL_TEXTURE_3D:
+ if (static_cast<GLuint>(width) > (caps.max3DTextureSize >> level) ||
+ static_cast<GLuint>(height) > (caps.max3DTextureSize >> level) ||
+ static_cast<GLuint>(depth) > (caps.max3DTextureSize >> level))
{
- if (static_cast<GLuint>(width) > (caps.max3DTextureSize >> level) ||
- static_cast<GLuint>(height) > (caps.max3DTextureSize >> level) ||
- static_cast<GLuint>(depth) > (caps.max3DTextureSize >> level))
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
-
- gl::Texture3D *texture3d = context->getTexture3D();
- if (texture3d)
- {
- textureCompressed = texture3d->isCompressed(level);
- textureInternalFormat = texture3d->getInternalFormat(level);
- textureLevelWidth = texture3d->getWidth(level);
- textureLevelHeight = texture3d->getHeight(level);
- textureLevelDepth = texture3d->getDepth(level);
- texture = texture3d;
- }
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
}
break;
- case GL_TEXTURE_2D_ARRAY:
- {
- if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
- static_cast<GLuint>(height) > (caps.max2DTextureSize >> level) ||
- static_cast<GLuint>(depth) > (caps.maxArrayTextureLayers >> level))
- {
- context->recordError(Error(GL_INVALID_VALUE));
- return false;
- }
-
- gl::Texture2DArray *texture2darray = context->getTexture2DArray();
- if (texture2darray)
- {
- textureCompressed = texture2darray->isCompressed(level);
- textureInternalFormat = texture2darray->getInternalFormat(level);
- textureLevelWidth = texture2darray->getWidth(level);
- textureLevelHeight = texture2darray->getHeight(level);
- textureLevelDepth = texture2darray->getLayers(level);
- texture = texture2darray;
- }
- }
- break;
+ case GL_TEXTURE_2D_ARRAY:
+ if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
+ static_cast<GLuint>(height) > (caps.max2DTextureSize >> level) ||
+ static_cast<GLuint>(depth) > (caps.maxArrayTextureLayers >> level))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return false;
+ }
+ break;
default:
context->recordError(Error(GL_INVALID_ENUM));
return false;
}
+ gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
if (!texture)
{
context->recordError(Error(GL_INVALID_OPERATION));
@@ -437,7 +380,7 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level,
}
// Validate texture formats
- GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
+ GLenum actualInternalFormat = isSubImage ? texture->getInternalFormat(target, level) : internalformat;
const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(actualInternalFormat);
if (isCompressed)
{
@@ -476,22 +419,12 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level,
// Validate sub image parameters
if (isSubImage)
{
- if (isCompressed != textureCompressed)
+ if (isCompressed != actualFormatInfo.compressed)
{
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
- if (isCompressed)
- {
- if ((width % 4 != 0 && width != textureLevelWidth) ||
- (height % 4 != 0 && height != textureLevelHeight))
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
- }
-
if (width == 0 || height == 0 || depth == 0)
{
return false;
@@ -511,9 +444,9 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level,
return false;
}
- if (xoffset + width > textureLevelWidth ||
- yoffset + height > textureLevelHeight ||
- zoffset + depth > textureLevelDepth)
+ 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->recordError(Error(GL_INVALID_VALUE));
return false;
@@ -798,8 +731,8 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen
{
// 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.
- const FormatType &typeInfo = GetFormatTypeInfo(framebufferInternalFormatInfo.format, framebufferInternalFormatInfo.type);
- sourceEffectiveFormat = &GetInternalFormatInfo(typeInfo.internalFormat);
+ GLenum sizedInternalFormat = GetSizedInternalFormat(framebufferInternalFormatInfo.format, framebufferInternalFormatInfo.type);
+ sourceEffectiveFormat = &GetInternalFormatInfo(sizedInternalFormat);
}
}
else
@@ -876,7 +809,7 @@ bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint le
gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
- if (framebuffer->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
@@ -932,13 +865,10 @@ bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei le
const gl::Caps &caps = context->getCaps();
- gl::Texture *texture = NULL;
switch (target)
{
case GL_TEXTURE_2D:
{
- texture = context->getTexture2D();
-
if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
static_cast<GLuint>(height) > caps.max2DTextureSize)
{
@@ -950,8 +880,6 @@ bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei le
case GL_TEXTURE_CUBE_MAP:
{
- texture = context->getTextureCubeMap();
-
if (width != height)
{
context->recordError(Error(GL_INVALID_VALUE));
@@ -968,8 +896,6 @@ bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei le
case GL_TEXTURE_3D:
{
- texture = context->getTexture3D();
-
if (static_cast<GLuint>(width) > caps.max3DTextureSize ||
static_cast<GLuint>(height) > caps.max3DTextureSize ||
static_cast<GLuint>(depth) > caps.max3DTextureSize)
@@ -982,8 +908,6 @@ bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei le
case GL_TEXTURE_2D_ARRAY:
{
- texture = context->getTexture2DArray();
-
if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
static_cast<GLuint>(height) > caps.max2DTextureSize ||
static_cast<GLuint>(depth) > caps.maxArrayTextureLayers)
@@ -999,6 +923,7 @@ bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei le
return false;
}
+ gl::Texture *texture = context->getTargetTexture(target);
if (!texture || texture->id() == 0)
{
context->recordError(Error(GL_INVALID_OPERATION));
@@ -1068,13 +993,6 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att
context->recordError(Error(GL_INVALID_VALUE));
return false;
}
-
- gl::Texture2DArray *texArray = static_cast<gl::Texture2DArray *>(tex);
- if (texArray->isCompressed(level))
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
}
break;
@@ -1091,13 +1009,6 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att
context->recordError(Error(GL_INVALID_VALUE));
return false;
}
-
- gl::Texture3D *tex3d = static_cast<gl::Texture3D *>(tex);
- if (tex3d->isCompressed(level))
- {
- context->recordError(Error(GL_INVALID_OPERATION));
- return false;
- }
}
break;
@@ -1105,6 +1016,13 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att
context->recordError(Error(GL_INVALID_OPERATION));
return false;
}
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(tex->getInternalFormat(tex->getTarget(), level));
+ if (internalFormatInfo.compressed)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
}
return true;
@@ -1187,6 +1105,33 @@ bool ValidES3ReadFormatType(Context *context, GLenum internalFormat, GLenum form
return true;
}
+bool ValidateES3RenderbufferStorageParameters(gl::Context *context, GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width, GLsizei height)
+{
+ if (!ValidateRenderbufferStorageParametersBase(context, 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.
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
+ if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT) && samples > 0)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ 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->recordError(Error(GL_INVALID_VALUE));
+ return false;
+ }
+
+ return true;
+}
+
bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments,
const GLenum* attachments)
{
@@ -1263,7 +1208,7 @@ bool ValidateClearBuffer(Context *context)
}
const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer();
- if (!fbo || fbo->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
+ if (!fbo || fbo->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return false;
@@ -1283,4 +1228,55 @@ bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLu
return ValidateGetUniformBase(context, program, location);
}
+bool ValidateReadBuffer(Context *context, GLenum src)
+{
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ Framebuffer *readFBO = context->getState().getReadFramebuffer();
+
+ if (readFBO == nullptr)
+ {
+ context->recordError(gl::Error(GL_INVALID_OPERATION, "No active read framebuffer."));
+ return false;
+ }
+
+ if (src == GL_NONE)
+ {
+ return true;
+ }
+
+ if (src != GL_BACK && (src < GL_COLOR_ATTACHMENT0 || src > GL_COLOR_ATTACHMENT15))
+ {
+ context->recordError(gl::Error(GL_INVALID_ENUM, "Unknown enum for 'src' in ReadBuffer"));
+ return false;
+ }
+
+ if (readFBO->id() == 0)
+ {
+ if (src != GL_BACK)
+ {
+ const char *errorMsg = "'src' must be GL_NONE or GL_BACK when reading from the default framebuffer.";
+ context->recordError(gl::Error(GL_INVALID_OPERATION, errorMsg));
+ return false;
+ }
+ }
+ else
+ {
+ GLuint drawBuffer = static_cast<GLuint>(src - GL_COLOR_ATTACHMENT0);
+
+ if (drawBuffer >= context->getCaps().maxDrawBuffers)
+ {
+ const char *errorMsg = "'src' is greater than MAX_DRAW_BUFFERS.";
+ context->recordError(gl::Error(GL_INVALID_OPERATION, errorMsg));
+ return false;
+ }
+ }
+
+ return true;
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/validationES3.h b/src/3rdparty/angle/src/libANGLE/validationES3.h
index cafacca601..517cb5d27f 100644
--- a/src/3rdparty/angle/src/libGLESv2/validationES3.h
+++ b/src/3rdparty/angle/src/libANGLE/validationES3.h
@@ -6,8 +6,8 @@
// validationES3.h: Validation functions for OpenGL ES 3.0 entry point parameters
-#ifndef LIBGLESV2_VALIDATION_ES3_H
-#define LIBGLESV2_VALIDATION_ES3_H
+#ifndef LIBANGLE_VALIDATION_ES3_H_
+#define LIBANGLE_VALIDATION_ES3_H_
#include <GLES3/gl3.h>
@@ -32,6 +32,9 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att
bool ValidES3ReadFormatType(Context *context, GLenum internalFormat, GLenum format, GLenum type);
+bool ValidateES3RenderbufferStorageParameters(Context *context, GLenum target, GLsizei samples,
+ GLenum internalformat, GLsizei width, GLsizei height);
+
bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments,
const GLenum* attachments);
@@ -39,6 +42,8 @@ bool ValidateClearBuffer(Context *context);
bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params);
+bool ValidateReadBuffer(Context *context, GLenum mode);
+
}
-#endif // LIBGLESV2_VALIDATION_ES3_H
+#endif // LIBANGLE_VALIDATION_ES3_H_
diff --git a/src/3rdparty/angle/src/libEGL/Config.cpp b/src/3rdparty/angle/src/libEGL/Config.cpp
deleted file mode 100644
index fdc41a95f0..0000000000
--- a/src/3rdparty/angle/src/libEGL/Config.cpp
+++ /dev/null
@@ -1,353 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// Config.cpp: Implements the egl::Config class, describing the format, type
-// and size for an egl::Surface. Implements EGLConfig and related functionality.
-// [EGL 1.4] section 3.4 page 15.
-
-#include "libEGL/Config.h"
-
-#include <algorithm>
-#include <vector>
-
-#include "angle_gl.h"
-#include <EGL/eglext.h>
-
-#include "common/debug.h"
-
-using namespace std;
-
-namespace egl
-{
-Config::Config(rx::ConfigDesc desc, EGLint minInterval, EGLint maxInterval, EGLint texWidth, EGLint texHeight)
- : mRenderTargetFormat(desc.renderTargetFormat), mDepthStencilFormat(desc.depthStencilFormat), mMultiSample(desc.multiSample)
-{
- mBindToTextureRGB = EGL_FALSE;
- mBindToTextureRGBA = EGL_FALSE;
- switch (desc.renderTargetFormat)
- {
- case GL_RGB5_A1:
- mBufferSize = 16;
- mRedSize = 5;
- mGreenSize = 5;
- mBlueSize = 5;
- mAlphaSize = 1;
- break;
- case GL_BGR5_A1_ANGLEX:
- mBufferSize = 16;
- mRedSize = 5;
- mGreenSize = 5;
- mBlueSize = 5;
- mAlphaSize = 1;
- break;
- case GL_RGBA8_OES:
- mBufferSize = 32;
- mRedSize = 8;
- mGreenSize = 8;
- mBlueSize = 8;
- mAlphaSize = 8;
- mBindToTextureRGBA = true;
- break;
- case GL_RGB565:
- mBufferSize = 16;
- mRedSize = 5;
- mGreenSize = 6;
- mBlueSize = 5;
- mAlphaSize = 0;
- break;
- case GL_RGB8_OES:
- mBufferSize = 32;
- mRedSize = 8;
- mGreenSize = 8;
- mBlueSize = 8;
- mAlphaSize = 0;
- mBindToTextureRGB = true;
- break;
- case GL_BGRA8_EXT:
- mBufferSize = 32;
- mRedSize = 8;
- mGreenSize = 8;
- mBlueSize = 8;
- mAlphaSize = 8;
- mBindToTextureRGBA = true;
- break;
- default:
- UNREACHABLE(); // Other formats should not be valid
- }
-
- mLuminanceSize = 0;
- mAlphaMaskSize = 0;
- mColorBufferType = EGL_RGB_BUFFER;
- mConfigCaveat = (desc.fastConfig) ? EGL_NONE : EGL_SLOW_CONFIG;
- mConfigID = 0;
- mConformant = EGL_OPENGL_ES2_BIT;
-
- switch (desc.depthStencilFormat)
- {
- case GL_NONE:
- mDepthSize = 0;
- mStencilSize = 0;
- break;
- case GL_DEPTH_COMPONENT32_OES:
- mDepthSize = 32;
- mStencilSize = 0;
- break;
- case GL_DEPTH24_STENCIL8_OES:
- mDepthSize = 24;
- mStencilSize = 8;
- break;
- case GL_DEPTH_COMPONENT24_OES:
- mDepthSize = 24;
- mStencilSize = 0;
- break;
- case GL_DEPTH_COMPONENT16:
- mDepthSize = 16;
- mStencilSize = 0;
- break;
- default:
- UNREACHABLE();
- }
-
- mLevel = 0;
- mMatchNativePixmap = EGL_NONE;
- mMaxPBufferWidth = texWidth;
- mMaxPBufferHeight = texHeight;
- mMaxPBufferPixels = texWidth*texHeight;
- mMaxSwapInterval = maxInterval;
- mMinSwapInterval = minInterval;
- mNativeRenderable = EGL_FALSE;
- mNativeVisualID = 0;
- mNativeVisualType = 0;
- mRenderableType = EGL_OPENGL_ES2_BIT;
- mSampleBuffers = desc.multiSample ? 1 : 0;
- mSamples = desc.multiSample;
- mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
- mTransparentType = EGL_NONE;
- mTransparentRedValue = 0;
- mTransparentGreenValue = 0;
- mTransparentBlueValue = 0;
-
- if (desc.es3Capable)
- {
- mRenderableType |= EGL_OPENGL_ES3_BIT_KHR;
- mConformant |= EGL_OPENGL_ES3_BIT_KHR;
- }
-}
-
-EGLConfig Config::getHandle() const
-{
- return (EGLConfig)(size_t)mConfigID;
-}
-
-SortConfig::SortConfig(const EGLint *attribList)
- : mWantRed(false), mWantGreen(false), mWantBlue(false), mWantAlpha(false), mWantLuminance(false)
-{
- scanForWantedComponents(attribList);
-}
-
-void SortConfig::scanForWantedComponents(const EGLint *attribList)
-{
- // [EGL] section 3.4.1 page 24
- // Sorting rule #3: by larger total number of color bits, not considering
- // components that are 0 or don't-care.
- for (const EGLint *attr = attribList; attr[0] != EGL_NONE; attr += 2)
- {
- if (attr[1] != 0 && attr[1] != EGL_DONT_CARE)
- {
- switch (attr[0])
- {
- case EGL_RED_SIZE: mWantRed = true; break;
- case EGL_GREEN_SIZE: mWantGreen = true; break;
- case EGL_BLUE_SIZE: mWantBlue = true; break;
- case EGL_ALPHA_SIZE: mWantAlpha = true; break;
- case EGL_LUMINANCE_SIZE: mWantLuminance = true; break;
- }
- }
- }
-}
-
-EGLint SortConfig::wantedComponentsSize(const Config &config) const
-{
- EGLint total = 0;
-
- if (mWantRed) total += config.mRedSize;
- if (mWantGreen) total += config.mGreenSize;
- if (mWantBlue) total += config.mBlueSize;
- if (mWantAlpha) total += config.mAlphaSize;
- if (mWantLuminance) total += config.mLuminanceSize;
-
- return total;
-}
-
-bool SortConfig::operator()(const Config *x, const Config *y) const
-{
- return (*this)(*x, *y);
-}
-
-bool SortConfig::operator()(const Config &x, const Config &y) const
-{
- #define SORT(attribute) \
- if (x.attribute != y.attribute) \
- { \
- return x.attribute < y.attribute; \
- }
-
- META_ASSERT(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
- SORT(mConfigCaveat);
-
- META_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
- SORT(mColorBufferType);
-
- // 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(mBufferSize);
- SORT(mSampleBuffers);
- SORT(mSamples);
- SORT(mDepthSize);
- SORT(mStencilSize);
- SORT(mAlphaMaskSize);
- SORT(mNativeVisualType);
- SORT(mConfigID);
-
- #undef SORT
-
- return false;
-}
-
-// We'd like to use SortConfig to also eliminate duplicate configs.
-// This works as long as we never have two configs with different per-RGB-component layouts,
-// but the same total.
-// 5551 and 565 are different because R+G+B is different.
-// 5551 and 555 are different because bufferSize is different.
-const EGLint ConfigSet::mSortAttribs[] =
-{
- EGL_RED_SIZE, 1,
- EGL_GREEN_SIZE, 1,
- EGL_BLUE_SIZE, 1,
- EGL_LUMINANCE_SIZE, 1,
- // BUT NOT ALPHA
- EGL_NONE
-};
-
-ConfigSet::ConfigSet()
- : mSet(SortConfig(mSortAttribs))
-{
-}
-
-void ConfigSet::add(rx::ConfigDesc desc, EGLint minSwapInterval, EGLint maxSwapInterval, EGLint texWidth, EGLint texHeight)
-{
- Config config(desc, minSwapInterval, maxSwapInterval, texWidth, texHeight);
- mSet.insert(config);
-}
-
-size_t ConfigSet::size() const
-{
- return mSet.size();
-}
-
-bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
-{
- vector<const Config*> passed;
- passed.reserve(mSet.size());
-
- for (Iterator config = mSet.begin(); config != mSet.end(); config++)
- {
- bool match = true;
- const EGLint *attribute = attribList;
-
- while (attribute[0] != EGL_NONE)
- {
- switch (attribute[0])
- {
- case EGL_BUFFER_SIZE: match = config->mBufferSize >= attribute[1]; break;
- case EGL_ALPHA_SIZE: match = config->mAlphaSize >= attribute[1]; break;
- case EGL_BLUE_SIZE: match = config->mBlueSize >= attribute[1]; break;
- case EGL_GREEN_SIZE: match = config->mGreenSize >= attribute[1]; break;
- case EGL_RED_SIZE: match = config->mRedSize >= attribute[1]; break;
- case EGL_DEPTH_SIZE: match = config->mDepthSize >= attribute[1]; break;
- case EGL_STENCIL_SIZE: match = config->mStencilSize >= attribute[1]; break;
- case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == (EGLenum) attribute[1]; break;
- case EGL_CONFIG_ID: match = config->mConfigID == attribute[1]; break;
- case EGL_LEVEL: match = config->mLevel >= attribute[1]; break;
- case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == (EGLBoolean) attribute[1]; break;
- case EGL_NATIVE_VISUAL_TYPE: match = config->mNativeVisualType == attribute[1]; break;
- case EGL_SAMPLES: match = config->mSamples >= attribute[1]; break;
- case EGL_SAMPLE_BUFFERS: match = config->mSampleBuffers >= attribute[1]; break;
- case EGL_SURFACE_TYPE: match = (config->mSurfaceType & attribute[1]) == attribute[1]; break;
- case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == (EGLenum) attribute[1]; break;
- case EGL_TRANSPARENT_BLUE_VALUE: match = config->mTransparentBlueValue == attribute[1]; break;
- case EGL_TRANSPARENT_GREEN_VALUE: match = config->mTransparentGreenValue == attribute[1]; break;
- case EGL_TRANSPARENT_RED_VALUE: match = config->mTransparentRedValue == attribute[1]; break;
- case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == (EGLBoolean) attribute[1]; break;
- case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == (EGLBoolean) attribute[1]; break;
- case EGL_MIN_SWAP_INTERVAL: match = config->mMinSwapInterval == attribute[1]; break;
- case EGL_MAX_SWAP_INTERVAL: match = config->mMaxSwapInterval == attribute[1]; break;
- case EGL_LUMINANCE_SIZE: match = config->mLuminanceSize >= attribute[1]; break;
- case EGL_ALPHA_MASK_SIZE: match = config->mAlphaMaskSize >= attribute[1]; break;
- case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == (EGLenum) attribute[1]; break;
- case EGL_RENDERABLE_TYPE: match = (config->mRenderableType & attribute[1]) == attribute[1]; break;
- case EGL_MATCH_NATIVE_PIXMAP: match = false; UNIMPLEMENTED(); break;
- case EGL_CONFORMANT: match = (config->mConformant & attribute[1]) == attribute[1]; break;
- case EGL_MAX_PBUFFER_WIDTH: match = config->mMaxPBufferWidth >= attribute[1]; break;
- case EGL_MAX_PBUFFER_HEIGHT: match = config->mMaxPBufferHeight >= attribute[1]; break;
- case EGL_MAX_PBUFFER_PIXELS: match = config->mMaxPBufferPixels >= attribute[1]; break;
- default:
- return false;
- }
-
- if (!match)
- {
- break;
- }
-
- attribute += 2;
- }
-
- if (match)
- {
- passed.push_back(&*config);
- }
- }
-
- if (configs)
- {
- sort(passed.begin(), passed.end(), SortConfig(attribList));
-
- EGLint index;
- for (index = 0; index < configSize && index < static_cast<EGLint>(passed.size()); index++)
- {
- configs[index] = passed[index]->getHandle();
- }
-
- *numConfig = index;
- }
- else
- {
- *numConfig = passed.size();
- }
-
- return true;
-}
-
-const egl::Config *ConfigSet::get(EGLConfig configHandle)
-{
- for (Iterator config = mSet.begin(); config != mSet.end(); config++)
- {
- if (config->getHandle() == configHandle)
- {
- return &(*config);
- }
- }
-
- return NULL;
-}
-}
diff --git a/src/3rdparty/angle/src/libEGL/Config.h b/src/3rdparty/angle/src/libEGL/Config.h
deleted file mode 100644
index 98441142f4..0000000000
--- a/src/3rdparty/angle/src/libEGL/Config.h
+++ /dev/null
@@ -1,114 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// Config.h: Defines the egl::Config class, describing the format, type
-// and size for an egl::Surface. Implements EGLConfig and related functionality.
-// [EGL 1.4] section 3.4 page 15.
-
-#ifndef INCLUDE_CONFIG_H_
-#define INCLUDE_CONFIG_H_
-
-#include <EGL/egl.h>
-
-#include <set>
-
-#include "libGLESv2/renderer/Renderer.h"
-#include "common/angleutils.h"
-
-namespace egl
-{
-class Display;
-
-class Config
-{
- public:
- Config(rx::ConfigDesc desc, EGLint minSwapInterval, EGLint maxSwapInterval, EGLint texWidth, EGLint texHeight);
-
- EGLConfig getHandle() const;
-
- const GLenum mRenderTargetFormat;
- const GLenum mDepthStencilFormat;
- const GLint mMultiSample;
-
- EGLint mBufferSize; // Depth of the color buffer
- EGLint mRedSize; // Bits of Red in the color buffer
- EGLint mGreenSize; // Bits of Green in the color buffer
- EGLint mBlueSize; // Bits of Blue in the color buffer
- EGLint mLuminanceSize; // Bits of Luminance in the color buffer
- EGLint mAlphaSize; // Bits of Alpha in the color buffer
- EGLint mAlphaMaskSize; // Bits of Alpha Mask in the mask buffer
- EGLBoolean mBindToTextureRGB; // True if bindable to RGB textures.
- EGLBoolean mBindToTextureRGBA; // True if bindable to RGBA textures.
- EGLenum mColorBufferType; // Color buffer type
- EGLenum mConfigCaveat; // Any caveats for the configuration
- EGLint mConfigID; // Unique EGLConfig identifier
- EGLint mConformant; // Whether contexts created with this config are conformant
- EGLint mDepthSize; // Bits of Z in the depth buffer
- EGLint mLevel; // Frame buffer level
- EGLBoolean mMatchNativePixmap; // Match the native pixmap format
- EGLint mMaxPBufferWidth; // Maximum width of pbuffer
- EGLint mMaxPBufferHeight; // Maximum height of pbuffer
- EGLint mMaxPBufferPixels; // Maximum size of pbuffer
- EGLint mMaxSwapInterval; // Maximum swap interval
- EGLint mMinSwapInterval; // Minimum swap interval
- EGLBoolean mNativeRenderable; // EGL_TRUE if native rendering APIs can render to surface
- EGLint mNativeVisualID; // Handle of corresponding native visual
- EGLint mNativeVisualType; // Native visual type of the associated visual
- EGLint mRenderableType; // Which client rendering APIs are supported.
- EGLint mSampleBuffers; // Number of multisample buffers
- EGLint mSamples; // Number of samples per pixel
- EGLint mStencilSize; // Bits of Stencil in the stencil buffer
- EGLint mSurfaceType; // Which types of EGL surfaces are supported.
- EGLenum mTransparentType; // Type of transparency supported
- EGLint mTransparentRedValue; // Transparent red value
- EGLint mTransparentGreenValue; // Transparent green value
- EGLint mTransparentBlueValue; // Transparent blue value
-};
-
-// Function object used by STL sorting routines for ordering Configs according to [EGL] section 3.4.1 page 24.
-class SortConfig
-{
- public:
- explicit SortConfig(const EGLint *attribList);
-
- bool operator()(const Config *x, const Config *y) const;
- bool operator()(const Config &x, const Config &y) const;
-
- private:
- void scanForWantedComponents(const EGLint *attribList);
- EGLint wantedComponentsSize(const Config &config) const;
-
- bool mWantRed;
- bool mWantGreen;
- bool mWantBlue;
- bool mWantAlpha;
- bool mWantLuminance;
-};
-
-class ConfigSet
-{
- friend Display;
-
- public:
- ConfigSet();
-
- void add(rx::ConfigDesc desc, EGLint minSwapInterval, EGLint maxSwapInterval, EGLint texWidth, EGLint texHeight);
- size_t size() const;
- bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
- const egl::Config *get(EGLConfig configHandle);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ConfigSet);
-
- typedef std::set<Config, SortConfig> Set;
- typedef Set::iterator Iterator;
- Set mSet;
-
- static const EGLint mSortAttribs[];
-};
-}
-
-#endif // INCLUDE_CONFIG_H_
diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
deleted file mode 100644
index eea93b1d87..0000000000
--- a/src/3rdparty/angle/src/libEGL/Display.cpp
+++ /dev/null
@@ -1,648 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// 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 "libEGL/Display.h"
-
-#include <algorithm>
-#include <map>
-#include <vector>
-#include <sstream>
-#include <iterator>
-
-#include "common/debug.h"
-#include "common/mathutil.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/renderer/SwapChain.h"
-
-#include "libEGL/main.h"
-#include "libEGL/Surface.h"
-
-namespace egl
-{
-
-typedef std::map<EGLNativeDisplayType, Display*> DisplayMap;
-static DisplayMap *GetDisplayMap()
-{
- static DisplayMap displays;
- return &displays;
-}
-
-egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap)
-{
- Display *display = NULL;
-
- DisplayMap *displays = GetDisplayMap();
- DisplayMap::const_iterator iter = displays->find(displayId);
- if (iter != displays->end())
- {
- display = iter->second;
- }
- else
- {
- display = new egl::Display(displayId);
- displays->insert(std::make_pair(displayId, display));
- }
-
- // Apply new attributes if the display is not initialized yet.
- if (!display->isInitialized())
- {
- display->setAttributes(attribMap);
- }
-
- return display;
-}
-
-Display::Display(EGLNativeDisplayType displayId)
- : mDisplayId(displayId),
- mAttributeMap(),
- mRenderer(NULL)
-{
-}
-
-Display::~Display()
-{
- terminate();
-
- DisplayMap *displays = GetDisplayMap();
- DisplayMap::iterator iter = displays->find(mDisplayId);
- if (iter != displays->end())
- {
- displays->erase(iter);
- }
-}
-
-void Display::setAttributes(const AttributeMap &attribMap)
-{
- mAttributeMap = attribMap;
-}
-
-Error Display::initialize()
-{
- if (isInitialized())
- {
- return Error(EGL_SUCCESS);
- }
-
- mRenderer = glCreateRenderer(this, mDisplayId, mAttributeMap);
-
- if (!mRenderer)
- {
- terminate();
- return Error(EGL_NOT_INITIALIZED);
- }
-
- //TODO(jmadill): should be part of caps?
- EGLint minSwapInterval = mRenderer->getMinSwapInterval();
- EGLint maxSwapInterval = mRenderer->getMaxSwapInterval();
- EGLint maxTextureSize = mRenderer->getRendererCaps().max2DTextureSize;
-
- rx::ConfigDesc *descList;
- int numConfigs = mRenderer->generateConfigs(&descList);
- ConfigSet configSet;
-
- for (int i = 0; i < numConfigs; ++i)
- {
- configSet.add(descList[i], minSwapInterval, maxSwapInterval, maxTextureSize, maxTextureSize);
- }
-
- // Give the sorted configs a unique ID and store them internally
- EGLint index = 1;
- for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
- {
- Config configuration = *config;
- configuration.mConfigID = index;
- index++;
-
- mConfigSet.mSet.insert(configuration);
- }
-
- mRenderer->deleteConfigs(descList);
- descList = NULL;
-
- if (!isInitialized())
- {
- terminate();
- return Error(EGL_NOT_INITIALIZED);
- }
-
- initDisplayExtensionString();
- initVendorString();
-
- return Error(EGL_SUCCESS);
-}
-
-void Display::terminate()
-{
- while (!mSurfaceSet.empty())
- {
- destroySurface(*mSurfaceSet.begin());
- }
-
- while (!mContextSet.empty())
- {
- destroyContext(*mContextSet.begin());
- }
-
- glDestroyRenderer(mRenderer);
- mRenderer = NULL;
-
- mConfigSet.mSet.clear();
-}
-
-bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
-{
- return mConfigSet.getConfigs(configs, attribList, configSize, numConfig);
-}
-
-bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
-{
- const egl::Config *configuration = mConfigSet.get(config);
-
- switch (attribute)
- {
- case EGL_BUFFER_SIZE: *value = configuration->mBufferSize; break;
- case EGL_ALPHA_SIZE: *value = configuration->mAlphaSize; break;
- case EGL_BLUE_SIZE: *value = configuration->mBlueSize; break;
- case EGL_GREEN_SIZE: *value = configuration->mGreenSize; break;
- case EGL_RED_SIZE: *value = configuration->mRedSize; break;
- case EGL_DEPTH_SIZE: *value = configuration->mDepthSize; break;
- case EGL_STENCIL_SIZE: *value = configuration->mStencilSize; break;
- case EGL_CONFIG_CAVEAT: *value = configuration->mConfigCaveat; break;
- case EGL_CONFIG_ID: *value = configuration->mConfigID; break;
- case EGL_LEVEL: *value = configuration->mLevel; break;
- case EGL_NATIVE_RENDERABLE: *value = configuration->mNativeRenderable; break;
- case EGL_NATIVE_VISUAL_TYPE: *value = configuration->mNativeVisualType; break;
- case EGL_SAMPLES: *value = configuration->mSamples; break;
- case EGL_SAMPLE_BUFFERS: *value = configuration->mSampleBuffers; break;
- case EGL_SURFACE_TYPE: *value = configuration->mSurfaceType; break;
- case EGL_TRANSPARENT_TYPE: *value = configuration->mTransparentType; break;
- case EGL_TRANSPARENT_BLUE_VALUE: *value = configuration->mTransparentBlueValue; break;
- case EGL_TRANSPARENT_GREEN_VALUE: *value = configuration->mTransparentGreenValue; break;
- case EGL_TRANSPARENT_RED_VALUE: *value = configuration->mTransparentRedValue; break;
- case EGL_BIND_TO_TEXTURE_RGB: *value = configuration->mBindToTextureRGB; break;
- case EGL_BIND_TO_TEXTURE_RGBA: *value = configuration->mBindToTextureRGBA; break;
- case EGL_MIN_SWAP_INTERVAL: *value = configuration->mMinSwapInterval; break;
- case EGL_MAX_SWAP_INTERVAL: *value = configuration->mMaxSwapInterval; break;
- case EGL_LUMINANCE_SIZE: *value = configuration->mLuminanceSize; break;
- case EGL_ALPHA_MASK_SIZE: *value = configuration->mAlphaMaskSize; break;
- case EGL_COLOR_BUFFER_TYPE: *value = configuration->mColorBufferType; break;
- case EGL_RENDERABLE_TYPE: *value = configuration->mRenderableType; break;
- case EGL_MATCH_NATIVE_PIXMAP: *value = false; UNIMPLEMENTED(); break;
- case EGL_CONFORMANT: *value = configuration->mConformant; break;
- case EGL_MAX_PBUFFER_WIDTH: *value = configuration->mMaxPBufferWidth; break;
- case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->mMaxPBufferHeight; break;
- case EGL_MAX_PBUFFER_PIXELS: *value = configuration->mMaxPBufferPixels; break;
- default:
- return false;
- }
-
- return true;
-}
-
-
-
-Error Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface)
-{
- const Config *configuration = mConfigSet.get(config);
- EGLint postSubBufferSupported = EGL_FALSE;
-
- EGLint width = 0;
- EGLint height = 0;
- EGLint fixedSize = EGL_FALSE;
-
- if (attribList)
- {
- while (*attribList != EGL_NONE)
- {
- switch (attribList[0])
- {
- case EGL_RENDER_BUFFER:
- switch (attribList[1])
- {
- case EGL_BACK_BUFFER:
- break;
- case EGL_SINGLE_BUFFER:
- return Error(EGL_BAD_MATCH); // Rendering directly to front buffer not supported
- default:
- return Error(EGL_BAD_ATTRIBUTE);
- }
- break;
- case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
- postSubBufferSupported = attribList[1];
- break;
- case EGL_WIDTH:
- width = attribList[1];
- break;
- case EGL_HEIGHT:
- height = attribList[1];
- break;
- case EGL_FIXED_SIZE_ANGLE:
- fixedSize = attribList[1];
- break;
- case EGL_VG_COLORSPACE:
- return Error(EGL_BAD_MATCH);
- case EGL_VG_ALPHA_FORMAT:
- return Error(EGL_BAD_MATCH);
- default:
- return Error(EGL_BAD_ATTRIBUTE);
- }
-
- attribList += 2;
- }
- }
-
- if (width < 0 || height < 0)
- {
- return Error(EGL_BAD_PARAMETER);
- }
-
- if (!fixedSize)
- {
- width = -1;
- height = -1;
- }
-
- if (hasExistingWindowSurface(window))
- {
- return Error(EGL_BAD_ALLOC);
- }
-
- if (mRenderer->testDeviceLost(false))
- {
- Error error = restoreLostDevice();
- if (error.isError())
- {
- return error;
- }
- }
-
- Surface *surface = new Surface(this, configuration, window, fixedSize, width, height, postSubBufferSupported);
- Error error = surface->initialize();
- if (error.isError())
- {
- SafeDelete(surface);
- return error;
- }
-
- mSurfaceSet.insert(surface);
-
- *outSurface = surface;
- return Error(EGL_SUCCESS);
-}
-
-Error Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList, EGLSurface *outSurface)
-{
- EGLint width = 0, height = 0;
- EGLenum textureFormat = EGL_NO_TEXTURE;
- EGLenum textureTarget = EGL_NO_TEXTURE;
- const Config *configuration = mConfigSet.get(config);
-
- if (attribList)
- {
- while (*attribList != EGL_NONE)
- {
- switch (attribList[0])
- {
- case EGL_WIDTH:
- width = attribList[1];
- break;
- case EGL_HEIGHT:
- height = attribList[1];
- break;
- case EGL_LARGEST_PBUFFER:
- if (attribList[1] != EGL_FALSE)
- UNIMPLEMENTED(); // FIXME
- break;
- case EGL_TEXTURE_FORMAT:
- switch (attribList[1])
- {
- case EGL_NO_TEXTURE:
- case EGL_TEXTURE_RGB:
- case EGL_TEXTURE_RGBA:
- textureFormat = attribList[1];
- break;
- default:
- return Error(EGL_BAD_ATTRIBUTE);
- }
- break;
- case EGL_TEXTURE_TARGET:
- switch (attribList[1])
- {
- case EGL_NO_TEXTURE:
- case EGL_TEXTURE_2D:
- textureTarget = attribList[1];
- break;
- default:
- return Error(EGL_BAD_ATTRIBUTE);
- }
- break;
- case EGL_MIPMAP_TEXTURE:
- if (attribList[1] != EGL_FALSE)
- return Error(EGL_BAD_ATTRIBUTE);
- break;
- case EGL_VG_COLORSPACE:
- return Error(EGL_BAD_MATCH);
- case EGL_VG_ALPHA_FORMAT:
- return Error(EGL_BAD_MATCH);
- default:
- return Error(EGL_BAD_ATTRIBUTE);
- }
-
- attribList += 2;
- }
- }
-
- if (width < 0 || height < 0)
- {
- return Error(EGL_BAD_PARAMETER);
- }
-
- if (width == 0 || height == 0)
- {
- return Error(EGL_BAD_ATTRIBUTE);
- }
-
- if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getRendererExtensions().textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
- {
- return Error(EGL_BAD_MATCH);
- }
-
- if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
- (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
- {
- return Error(EGL_BAD_MATCH);
- }
-
- if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
- {
- return Error(EGL_BAD_MATCH);
- }
-
- if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) ||
- (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE))
- {
- return Error(EGL_BAD_ATTRIBUTE);
- }
-
- if (mRenderer->testDeviceLost(false))
- {
- Error error = restoreLostDevice();
- if (error.isError())
- {
- return error;
- }
- }
-
- Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget);
- Error error = surface->initialize();
- if (error.isError())
- {
- SafeDelete(surface);
- return error;
- }
-
- mSurfaceSet.insert(surface);
-
- *outSurface = surface;
- return Error(EGL_SUCCESS);
-}
-
-Error Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets,
- bool robustAccess, EGLContext *outContext)
-{
- if (!mRenderer)
- {
- *outContext = EGL_NO_CONTEXT;
- return Error(EGL_SUCCESS);
- }
- else if (mRenderer->testDeviceLost(false)) // Lost device
- {
- Error error = restoreLostDevice();
- if (error.isError())
- {
- return error;
- }
- }
-
- //TODO(jmadill): shader model is not cross-platform
- if (clientVersion > 2 && mRenderer->getMajorShaderModel() < 4)
- {
- return Error(EGL_BAD_CONFIG);
- }
-
- gl::Context *context = glCreateContext(clientVersion, shareContext, mRenderer, notifyResets, robustAccess);
- mContextSet.insert(context);
-
- *outContext = context;
- return Error(EGL_SUCCESS);
-}
-
-Error Display::restoreLostDevice()
-{
- for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++)
- {
- if ((*ctx)->isResetNotificationEnabled())
- {
- // If reset notifications have been requested, application must delete all contexts first
- return Error(EGL_CONTEXT_LOST);
- }
- }
-
- // Release surface resources to make the Reset() succeed
- for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
- {
- (*surface)->release();
- }
-
- if (!mRenderer->resetDevice())
- {
- return Error(EGL_BAD_ALLOC);
- }
-
- // Restore any surfaces that may have been lost
- for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
- {
- Error error = (*surface)->resetSwapChain();
- if (error.isError())
- {
- return error;
- }
- }
-
- return Error(EGL_SUCCESS);
-}
-
-
-void Display::destroySurface(egl::Surface *surface)
-{
- delete surface;
- mSurfaceSet.erase(surface);
-}
-
-void Display::destroyContext(gl::Context *context)
-{
- glDestroyContext(context);
- mContextSet.erase(context);
-}
-
-void Display::notifyDeviceLost()
-{
- for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++)
- {
- (*context)->markContextLost();
- }
-}
-
-void Display::recreateSwapChains()
-{
- for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
- {
- (*surface)->getSwapChain()->recreate();
- }
-}
-
-bool Display::isInitialized() const
-{
- return mRenderer != NULL && mConfigSet.size() > 0;
-}
-
-bool Display::isValidConfig(EGLConfig config)
-{
- return mConfigSet.get(config) != NULL;
-}
-
-bool Display::isValidContext(gl::Context *context)
-{
- return mContextSet.find(context) != mContextSet.end();
-}
-
-bool Display::isValidSurface(egl::Surface *surface)
-{
- return mSurfaceSet.find(surface) != mSurfaceSet.end();
-}
-
-bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
-{
- for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
- {
- if ((*surface)->getWindowHandle() == window)
- {
- return true;
- }
- }
-
- return false;
-}
-
-std::string Display::generateClientExtensionString()
-{
- std::vector<std::string> extensions;
-
- extensions.push_back("EGL_EXT_client_extensions");
-
- extensions.push_back("ANGLE_platform_angle");
-
- if (supportsPlatformD3D())
- {
- extensions.push_back("ANGLE_platform_angle_d3d");
- }
-
- if (supportsPlatformOpenGL())
- {
- extensions.push_back("ANGLE_platform_angle_opengl");
- }
-
- std::ostringstream stream;
- std::copy(extensions.begin(), extensions.end(), std::ostream_iterator<std::string>(stream, " "));
- return stream.str();
-}
-
-void Display::initDisplayExtensionString()
-{
- std::vector<std::string> extensions;
-
- // Multi-vendor (EXT) extensions
- extensions.push_back("EGL_EXT_create_context_robustness");
-
- // ANGLE-specific extensions
- if (mRenderer->getShareHandleSupport())
- {
- extensions.push_back("EGL_ANGLE_d3d_share_handle_client_buffer");
- extensions.push_back("EGL_ANGLE_surface_d3d_texture_2d_share_handle");
- }
-
- extensions.push_back("EGL_ANGLE_query_surface_pointer");
- extensions.push_back("EGL_ANGLE_window_fixed_size");
-
- if (mRenderer->getPostSubBufferSupport())
- {
- extensions.push_back("EGL_NV_post_sub_buffer");
- }
-
-#if defined (ANGLE_TEST_CONFIG)
- // TODO: complete support for the EGL_KHR_create_context extension
- extensions.push_back("EGL_KHR_create_context");
-#endif
-
- std::ostringstream stream;
- std::copy(extensions.begin(), extensions.end(), std::ostream_iterator<std::string>(stream, " "));
- mDisplayExtensionString = stream.str();
-}
-
-const char *Display::getExtensionString(egl::Display *display)
-{
- if (display != EGL_NO_DISPLAY)
- {
- return display->mDisplayExtensionString.c_str();
- }
- else
- {
- static std::string clientExtensions = generateClientExtensionString();
- return clientExtensions.c_str();
- }
-}
-
-bool Display::supportsPlatformD3D()
-{
-#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
- return true;
-#else
- return false;
-#endif
-}
-
-bool Display::supportsPlatformOpenGL()
-{
- return false;
-}
-
-void Display::initVendorString()
-{
- mVendorString = "Google Inc.";
-
- LUID adapterLuid = {0};
-
- //TODO(jmadill): LUID is not cross-platform
- if (mRenderer && mRenderer->getLUID(&adapterLuid))
- {
- char adapterLuidString[64];
- sprintf_s(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
-
- mVendorString += adapterLuidString;
- }
-}
-
-const char *Display::getVendorString() const
-{
- return mVendorString.c_str();
-}
-
-}
diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
deleted file mode 100644
index b3ffcc84c5..0000000000
--- a/src/3rdparty/angle/src/libEGL/Display.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// 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 LIBEGL_DISPLAY_H_
-#define LIBEGL_DISPLAY_H_
-
-#include <set>
-#include <vector>
-
-#include "libEGL/Error.h"
-#include "libEGL/Config.h"
-#include "libEGL/AttributeMap.h"
-
-namespace gl
-{
-class Context;
-}
-
-namespace egl
-{
-class Surface;
-
-class Display
-{
- public:
- ~Display();
-
- Error initialize();
- void terminate();
-
- static egl::Display *getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap);
-
- static const char *getExtensionString(egl::Display *display);
-
- static bool supportsPlatformD3D();
- static bool supportsPlatformOpenGL();
-
- bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
- bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
-
- Error createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface);
- Error createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList, EGLSurface *outSurface);
- Error createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets,
- bool robustAccess, EGLContext *outContext);
-
- void destroySurface(egl::Surface *surface);
- void destroyContext(gl::Context *context);
-
- bool isInitialized() const;
- bool isValidConfig(EGLConfig config);
- bool isValidContext(gl::Context *context);
- bool isValidSurface(egl::Surface *surface);
- bool hasExistingWindowSurface(EGLNativeWindowType window);
-
- rx::Renderer *getRenderer() { return mRenderer; };
-
- // exported methods must be virtual
- virtual void notifyDeviceLost();
- virtual void recreateSwapChains();
-
- const char *getExtensionString() const;
- const char *getVendorString() const;
- EGLNativeDisplayType getDisplayId() const { return mDisplayId; }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Display);
-
- Display(EGLNativeDisplayType displayId);
-
- void setAttributes(const AttributeMap &attribMap);
-
- Error restoreLostDevice();
-
- EGLNativeDisplayType mDisplayId;
- AttributeMap mAttributeMap;
-
- typedef std::set<Surface*> SurfaceSet;
- SurfaceSet mSurfaceSet;
-
- ConfigSet mConfigSet;
-
- typedef std::set<gl::Context*> ContextSet;
- ContextSet mContextSet;
-
- rx::Renderer *mRenderer;
-
- static std::string generateClientExtensionString();
-
- void initDisplayExtensionString();
- std::string mDisplayExtensionString;
-
- void initVendorString();
- std::string mVendorString;
-};
-}
-
-#endif // LIBEGL_DISPLAY_H_
diff --git a/src/3rdparty/angle/src/libEGL/Error.cpp b/src/3rdparty/angle/src/libEGL/Error.cpp
deleted file mode 100644
index df5f163d32..0000000000
--- a/src/3rdparty/angle/src/libEGL/Error.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Copyright (c) 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 class which encapsulates an EGL error
-// and optional error message.
-
-#include "libEGL/Error.h"
-
-#include "common/angleutils.h"
-
-#include <cstdarg>
-
-namespace egl
-{
-
-Error::Error(EGLint errorCode)
- : mCode(errorCode),
- mMessage()
-{
-}
-
-Error::Error(EGLint errorCode, const char *msg, ...)
- : mCode(errorCode),
- mMessage()
-{
- va_list vararg;
- va_start(vararg, msg);
- mMessage = FormatString(msg, vararg);
- va_end(vararg);
-}
-
-Error::Error(const Error &other)
- : mCode(other.mCode),
- mMessage(other.mMessage)
-{
-}
-
-Error &Error::operator=(const Error &other)
-{
- mCode = other.mCode;
- mMessage = other.mMessage;
- return *this;
-}
-
-}
diff --git a/src/3rdparty/angle/src/libEGL/Error.h b/src/3rdparty/angle/src/libEGL/Error.h
deleted file mode 100644
index 71805d2fb7..0000000000
--- a/src/3rdparty/angle/src/libEGL/Error.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// Copyright (c) 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 class which encapsulates an EGL error
-// and optional error message.
-
-#ifndef LIBEGL_ERROR_H_
-#define LIBEGL_ERROR_H_
-
-#include <EGL/egl.h>
-
-#include <string>
-
-namespace egl
-{
-
-class Error
-{
- public:
- explicit Error(EGLint errorCode);
- Error(EGLint errorCode, const char *msg, ...);
- Error(const Error &other);
- Error &operator=(const Error &other);
-
- EGLint getCode() const { return mCode; }
- bool isError() const { return (mCode != EGL_SUCCESS); }
-
- const std::string &getMessage() const { return mMessage; }
-
- private:
- EGLint mCode;
- std::string mMessage;
-};
-
-}
-
-#endif // LIBEGL_ERROR_H_
diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
deleted file mode 100644
index b664a8530e..0000000000
--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
+++ /dev/null
@@ -1,505 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// 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 <tchar.h>
-
-#include <algorithm>
-
-#include "libEGL/Surface.h"
-
-#include "common/debug.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/renderer/SwapChain.h"
-#include "libGLESv2/main.h"
-
-#include "libEGL/main.h"
-#include "libEGL/Display.h"
-
-#include "common/NativeWindow.h"
-
-//TODO(jmadill): phase this out
-#include "libGLESv2/renderer/d3d/RendererD3D.h"
-
-namespace egl
-{
-
-Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported)
- : mDisplay(display), mConfig(config), mNativeWindow(window, display->getDisplayId()), mPostSubBufferSupported(postSubBufferSupported)
-{
- //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
- mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
- mSwapChain = NULL;
- mShareHandle = NULL;
- mTexture = NULL;
- mTextureFormat = EGL_NO_TEXTURE;
- mTextureTarget = EGL_NO_TEXTURE;
-
- mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
- mRenderBuffer = EGL_BACK_BUFFER;
- mSwapBehavior = EGL_BUFFER_PRESERVED;
- mSwapInterval = -1;
- mWidth = width;
- mHeight = height;
- mFixedWidth = mWidth;
- mFixedHeight = mHeight;
- setSwapInterval(1);
- mFixedSize = fixedSize;
-
- subclassWindow();
-}
-
-Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
- : mDisplay(display), mNativeWindow(NULL, NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
-{
- //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
- mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
- mSwapChain = NULL;
- mWindowSubclassed = false;
- mTexture = NULL;
- mTextureFormat = textureFormat;
- mTextureTarget = textureType;
-
- mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
- mRenderBuffer = EGL_BACK_BUFFER;
- mSwapBehavior = EGL_BUFFER_PRESERVED;
- mSwapInterval = -1;
- setSwapInterval(1);
- // This constructor is for offscreen surfaces, which are always fixed-size.
- mFixedSize = EGL_TRUE;
- mFixedWidth = mWidth;
- mFixedHeight = mHeight;
-}
-
-Surface::~Surface()
-{
- unsubclassWindow();
- release();
-}
-
-Error Surface::initialize()
-{
- if (mNativeWindow.getNativeWindow())
- {
- if (!mNativeWindow.initialize())
- {
- return Error(EGL_BAD_SURFACE);
- }
- }
-
- Error error = resetSwapChain();
- if (error.isError())
- {
- return error;
- }
-
- return Error(EGL_SUCCESS);
-}
-
-void Surface::release()
-{
- delete mSwapChain;
- mSwapChain = NULL;
-
- if (mTexture)
- {
- mTexture->releaseTexImage();
- mTexture = NULL;
- }
-}
-
-Error Surface::resetSwapChain()
-{
- ASSERT(!mSwapChain);
-
- int width;
- int height;
-
- if (!mFixedSize)
- {
- RECT windowRect;
- if (!mNativeWindow.getClientRect(&windowRect))
- {
- ASSERT(false);
-
- return Error(EGL_BAD_SURFACE, "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 = mWidth;
- height = mHeight;
- }
-
- mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle,
- mConfig->mRenderTargetFormat,
- mConfig->mDepthStencilFormat);
- if (!mSwapChain)
- {
- return Error(EGL_BAD_ALLOC);
- }
-
- Error error = resetSwapChain(width, height);
- if (error.isError())
- {
- SafeDelete(mSwapChain);
- return error;
- }
-
- return Error(EGL_SUCCESS);
-}
-
-Error Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
-{
- ASSERT(mSwapChain);
-
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- backbufferWidth = std::max(1, backbufferWidth);
- backbufferHeight = std::max(1, backbufferHeight);
-#endif
- EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
-
- if (status == EGL_CONTEXT_LOST)
- {
- mDisplay->notifyDeviceLost();
- return Error(status);
- }
- else if (status != EGL_SUCCESS)
- {
- return Error(status);
- }
-
- mWidth = backbufferWidth;
- mHeight = backbufferHeight;
-
- return Error(EGL_SUCCESS);
-}
-
-Error Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
-{
- ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
- ASSERT(mSwapChain);
-
- EGLint status = mSwapChain->reset(std::max(1, backbufferWidth), std::max(1, backbufferHeight), mSwapInterval);
-
- if (status == EGL_CONTEXT_LOST)
- {
- mRenderer->notifyDeviceLost();
- return Error(status);
- }
- else if (status != EGL_SUCCESS)
- {
- return Error(status);
- }
-
- mWidth = backbufferWidth;
- mHeight = backbufferHeight;
- mSwapIntervalDirty = false;
-
- return Error(EGL_SUCCESS);
-}
-
-Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
-{
- if (!mSwapChain)
- {
- return Error(EGL_SUCCESS);
- }
-
- if (x + width > abs(mWidth))
- {
- width = abs(mWidth) - x;
- }
-
- if (y + height > abs(mHeight))
- {
- height = abs(mHeight) - y;
- }
-
- if (width == 0 || height == 0)
- {
- return Error(EGL_SUCCESS);
- }
-
- ASSERT(width > 0);
- ASSERT(height > 0);
-
- EGLint status = mSwapChain->swapRect(x, y, width, height);
-
- if (status == EGL_CONTEXT_LOST)
- {
- mRenderer->notifyDeviceLost();
- return Error(status);
- }
- else if (status != EGL_SUCCESS)
- {
- return Error(status);
- }
-
- checkForOutOfDateSwapChain();
-
- return Error(EGL_SUCCESS);
-}
-
-EGLNativeWindowType Surface::getWindowHandle()
-{
- return mNativeWindow.getNativeWindow();
-}
-
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
-#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
-#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
-
-static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
-{
- if (message == WM_SIZE)
- {
- Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
- if(surf)
- {
- surf->checkForOutOfDateSwapChain();
- }
- }
- WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
- return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
-}
-#endif
-
-void Surface::subclassWindow()
-{
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- HWND window = mNativeWindow.getNativeWindow();
- if (!window)
- {
- return;
- }
-
- DWORD processId;
- DWORD threadId = GetWindowThreadProcessId(window, &processId);
- if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
- {
- return;
- }
-
- SetLastError(0);
- LONG_PTR oldWndProc = SetWindowLongPtr(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
- if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
- {
- mWindowSubclassed = false;
- return;
- }
-
- SetProp(window, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
- SetProp(window, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
- mWindowSubclassed = true;
-#endif
-}
-
-void Surface::unsubclassWindow()
-{
- if(!mWindowSubclassed)
- {
- return;
- }
-
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- HWND window = mNativeWindow.getNativeWindow();
- if (!window)
- {
- return;
- }
-
- // un-subclass
- LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(window, kParentWndProc));
-
- // Check the windowproc is still SurfaceWindowProc.
- // If this assert fails, then it is likely the application has subclassed the
- // hwnd as well and did not unsubclass before destroying its EGL context. The
- // application should be modified to either subclass before initializing the
- // EGL context, or to unsubclass before destroying the EGL context.
- if(parentWndFunc)
- {
- LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc);
- UNUSED_ASSERTION_VARIABLE(prevWndFunc);
- ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
- }
-
- RemoveProp(window, kSurfaceProperty);
- RemoveProp(window, kParentWndProc);
-#endif
- mWindowSubclassed = false;
-}
-
-bool Surface::checkForOutOfDateSwapChain()
-{
- 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))
- {
- ASSERT(false);
- return false;
- }
-
- // 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();
- }
-
- if (mFixedSize && (mWidth != mFixedWidth || mHeight != mFixedHeight))
- {
- clientWidth = mFixedWidth;
- clientHeight = mFixedHeight;
- sizeDirty = true;
- }
-
- bool wasDirty = (mSwapIntervalDirty || sizeDirty);
-
- if (mSwapIntervalDirty)
- {
- resetSwapChain(clientWidth, clientHeight);
- }
- else if (sizeDirty)
- {
- resizeSwapChain(clientWidth, clientHeight);
- }
-
- if (wasDirty)
- {
- if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
- {
- glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
- }
-
- return true;
- }
-
- return false;
-}
-
-Error Surface::swap()
-{
- return swapRect(0, 0, abs(mWidth), abs(mHeight));
-}
-
-Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
-{
- if (!mPostSubBufferSupported)
- {
- // Spec is not clear about how this should be handled.
- return Error(EGL_SUCCESS);
- }
-
- return swapRect(x, y, width, height);
-}
-
-EGLint Surface::isPostSubBufferSupported() const
-{
- return mPostSubBufferSupported;
-}
-
-rx::SwapChain *Surface::getSwapChain() const
-{
- return mSwapChain;
-}
-
-void Surface::setSwapInterval(EGLint interval)
-{
- if (mSwapInterval == interval)
- {
- return;
- }
-
- mSwapInterval = interval;
- mSwapInterval = std::max(mSwapInterval, mRenderer->getMinSwapInterval());
- mSwapInterval = std::min(mSwapInterval, mRenderer->getMaxSwapInterval());
-
- mSwapIntervalDirty = true;
-}
-
-EGLint Surface::getConfigID() const
-{
- return mConfig->mConfigID;
-}
-
-EGLint Surface::getWidth() const
-{
- return mWidth;
-}
-
-EGLint Surface::getHeight() const
-{
- return mHeight;
-}
-
-EGLint Surface::getPixelAspectRatio() const
-{
- return mPixelAspectRatio;
-}
-
-EGLenum Surface::getRenderBuffer() const
-{
- return mRenderBuffer;
-}
-
-EGLenum Surface::getSwapBehavior() const
-{
- return mSwapBehavior;
-}
-
-EGLenum Surface::getTextureFormat() const
-{
- return mTextureFormat;
-}
-
-EGLenum Surface::getTextureTarget() const
-{
- return mTextureTarget;
-}
-
-void Surface::setBoundTexture(gl::Texture2D *texture)
-{
- mTexture = texture;
-}
-
-gl::Texture2D *Surface::getBoundTexture() const
-{
- return mTexture;
-}
-
-EGLint Surface::isFixedSize() const
-{
- return mFixedSize;
-}
-
-void Surface::setFixedWidth(EGLint width)
-{
- mFixedWidth = width;
-}
-
-void Surface::setFixedHeight(EGLint height)
-{
- mFixedHeight = height;
-}
-
-EGLenum Surface::getFormat() const
-{
- return mConfig->mRenderTargetFormat;
-}
-}
diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h
deleted file mode 100644
index 46382d06e1..0000000000
--- a/src/3rdparty/angle/src/libEGL/Surface.h
+++ /dev/null
@@ -1,120 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// 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 LIBEGL_SURFACE_H_
-#define LIBEGL_SURFACE_H_
-
-#include "libEGL/Error.h"
-
-#include <EGL/egl.h>
-
-#include "common/angleutils.h"
-#include "common/NativeWindow.h"
-
-namespace gl
-{
-class Texture2D;
-}
-namespace rx
-{
-class SwapChain;
-class RendererD3D; //TODO(jmadill): remove this
-}
-
-namespace egl
-{
-class Display;
-class Config;
-
-class Surface
-{
- public:
- Surface(Display *display, const egl::Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported);
- Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);
-
- virtual ~Surface();
-
- Error initialize();
- void release();
- Error resetSwapChain();
-
- EGLNativeWindowType getWindowHandle();
- Error swap();
- Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
-
- virtual EGLint isPostSubBufferSupported() const;
-
- virtual rx::SwapChain *getSwapChain() const;
-
- void setSwapInterval(EGLint interval);
- bool checkForOutOfDateSwapChain(); // Returns true if swapchain changed due to resize or interval update
-
- virtual EGLint getConfigID() const;
- virtual EGLint getWidth() const;
- virtual EGLint getHeight() const;
- virtual EGLint getPixelAspectRatio() const;
- virtual EGLenum getRenderBuffer() const;
- virtual EGLenum getSwapBehavior() const;
- virtual EGLenum getTextureFormat() const;
- virtual EGLenum getTextureTarget() const;
- virtual EGLenum getFormat() const;
-
- virtual void setBoundTexture(gl::Texture2D *texture);
- virtual gl::Texture2D *getBoundTexture() const;
-
- EGLint isFixedSize() const;
- void setFixedWidth(EGLint width);
- void setFixedHeight(EGLint height);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Surface);
-
- Display *const mDisplay;
- rx::RendererD3D *mRenderer;
-
- HANDLE mShareHandle;
- rx::SwapChain *mSwapChain;
-
- void subclassWindow();
- void unsubclassWindow();
- Error resizeSwapChain(int backbufferWidth, int backbufferHeight);
- Error resetSwapChain(int backbufferWidth, int backbufferHeight);
- Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
-
- rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for.
- bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
- const egl::Config *mConfig; // EGL config surface was created with
- EGLint mHeight; // Height of surface
- EGLint mWidth; // Width of surface
- EGLint mFixedHeight; // Pending height of the surface
- EGLint mFixedWidth; // Pending width of the surface
-// EGLint horizontalResolution; // Horizontal dot pitch
-// EGLint verticalResolution; // Vertical dot pitch
-// EGLBoolean largestPBuffer; // If true, create largest pbuffer possible
-// EGLBoolean mipmapTexture; // True if texture has mipmaps
-// EGLint mipmapLevel; // Mipmap level to render to
-// EGLenum multisampleResolve; // Multisample resolve behavior
- EGLint mPixelAspectRatio; // Display aspect ratio
- EGLenum mRenderBuffer; // Render buffer
- EGLenum mSwapBehavior; // Buffer swap behavior
- EGLenum mTextureFormat; // Format of texture: RGB, RGBA, or no texture
- EGLenum mTextureTarget; // Type of texture: 2D or no texture
-// EGLenum vgAlphaFormat; // Alpha format for OpenVG
-// EGLenum vgColorSpace; // Color space for OpenVG
- EGLint mSwapInterval;
- EGLint mPostSubBufferSupported;
- EGLint mFixedSize;
-
- bool mSwapIntervalDirty;
- gl::Texture2D *mTexture;
-};
-}
-
-#endif // LIBEGL_SURFACE_H_
diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
index 68399d63a4..d09219e308 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
@@ -6,1258 +6,245 @@
// libEGL.cpp: Implements the exported EGL functions.
-#undef EGLAPI
-#define EGLAPI
+#include "libGLESv2/entry_points_egl.h"
+#include "libGLESv2/entry_points_egl_ext.h"
-#include <exception>
-
-#include "common/debug.h"
-#include "common/version.h"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/renderer/SwapChain.h"
-#if defined(ANGLE_ENABLE_D3D11)
-# include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#endif
-
-#include "libEGL/main.h"
-#include "libEGL/Display.h"
-#include "libEGL/Surface.h"
-
-#include "common/NativeWindow.h"
-
-bool validateDisplay(egl::Display *display)
+extern "C"
{
- if (display == EGL_NO_DISPLAY)
- {
- recordError(egl::Error(EGL_BAD_DISPLAY));
- return false;
- }
-
- if (!display->isInitialized())
- {
- recordError(egl::Error(EGL_NOT_INITIALIZED));
- return false;
- }
- return true;
+EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+ return egl::ChooseConfig(dpy, attrib_list, configs, config_size, num_config);
}
-bool validateConfig(egl::Display *display, EGLConfig config)
+EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
{
- if (!validateDisplay(display))
- {
- return false;
- }
-
- if (!display->isValidConfig(config))
- {
- recordError(egl::Error(EGL_BAD_CONFIG));
- return false;
- }
-
- return true;
+ return egl::CopyBuffers(dpy, surface, target);
}
-bool validateContext(egl::Display *display, gl::Context *context)
+EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
{
- if (!validateDisplay(display))
- {
- return false;
- }
-
- if (!display->isValidContext(context))
- {
- recordError(egl::Error(EGL_BAD_CONTEXT));
- return false;
- }
-
- return true;
+ return egl::CreateContext(dpy, config, share_context, attrib_list);
}
-bool validateSurface(egl::Display *display, egl::Surface *surface)
+EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{
- if (!validateDisplay(display))
- {
- return false;
- }
-
- if (!display->isValidSurface(surface))
- {
- recordError(egl::Error(EGL_BAD_SURFACE));
- return false;
- }
-
- return true;
+ return egl::CreatePbufferSurface(dpy, config, attrib_list);
}
-extern "C"
-{
-EGLint __stdcall eglGetError(void)
+EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
{
- EVENT("()");
-
- EGLint error = egl::getCurrentError();
- recordError(egl::Error(EGL_SUCCESS));
- return error;
+ return egl::CreatePixmapSurface(dpy, config, pixmap, attrib_list);
}
-EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
+EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
{
- EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
-
- return egl::Display::getDisplay(display_id, egl::AttributeMap());
+ return egl::CreateWindowSurface(dpy, config, win, attrib_list);
}
-EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
+EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
- EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
- platform, native_display, attrib_list);
-
- switch (platform)
- {
- case EGL_PLATFORM_ANGLE_ANGLE:
- break;
-
- default:
- recordError(egl::Error(EGL_BAD_CONFIG));
- return EGL_NO_DISPLAY;
- }
-
- EGLNativeDisplayType displayId = static_cast<EGLNativeDisplayType>(native_display);
-
-#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- // Validate the display device context
- if (WindowFromDC(displayId) == NULL)
- {
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_NO_DISPLAY;
- }
-#endif
-
- EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
- bool majorVersionSpecified = false;
- bool minorVersionSpecified = false;
- bool requestedWARP = false;
-
- if (attrib_list)
- {
- for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2)
- {
- switch (curAttrib[0])
- {
- case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
- switch (curAttrib[1])
- {
- case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
- break;
-
- case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
- case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
- if (!egl::Display::supportsPlatformD3D())
- {
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_NO_DISPLAY;
- }
- break;
-
- case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
- case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
- if (!egl::Display::supportsPlatformOpenGL())
- {
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_NO_DISPLAY;
- }
- break;
-
- default:
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_NO_DISPLAY;
- }
- platformType = curAttrib[1];
- break;
-
- case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE:
- if (curAttrib[1] != EGL_DONT_CARE)
- {
- majorVersionSpecified = true;
- }
- break;
-
- case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE:
- if (curAttrib[1] != EGL_DONT_CARE)
- {
- minorVersionSpecified = true;
- }
- break;
-
- case EGL_PLATFORM_ANGLE_USE_WARP_ANGLE:
- if (!egl::Display::supportsPlatformD3D())
- {
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_NO_DISPLAY;
- }
-
- switch (curAttrib[1])
- {
- case EGL_FALSE:
- case EGL_TRUE:
- break;
-
- default:
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_NO_DISPLAY;
- }
-
- requestedWARP = (curAttrib[1] == EGL_TRUE);
- break;
-
- default:
- break;
- }
- }
- }
-
- if (!majorVersionSpecified && minorVersionSpecified)
- {
- recordError(egl::Error(EGL_BAD_ATTRIBUTE));
- return EGL_NO_DISPLAY;
- }
-
- if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE && requestedWARP)
- {
- recordError(egl::Error(EGL_BAD_ATTRIBUTE));
- return EGL_NO_DISPLAY;
- }
-
- recordError(egl::Error(EGL_SUCCESS));
- return egl::Display::getDisplay(displayId, egl::AttributeMap(attrib_list));
+ return egl::DestroyContext(dpy, ctx);
}
-EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)",
- dpy, major, minor);
-
- if (dpy == EGL_NO_DISPLAY)
- {
- recordError(egl::Error(EGL_BAD_DISPLAY));
- return EGL_FALSE;
- }
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
-
- egl::Error error = display->initialize();
- if (error.isError())
- {
- recordError(error);
- return EGL_FALSE;
- }
-
- if (major) *major = 1;
- if (minor) *minor = 4;
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::DestroySurface(dpy, surface);
}
-EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
+EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy);
-
- if (dpy == EGL_NO_DISPLAY)
- {
- recordError(egl::Error(EGL_BAD_DISPLAY));
- return EGL_FALSE;
- }
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
-
- display->terminate();
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::GetConfigAttrib(dpy, config, attribute, value);
}
-const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
+EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) && !validateDisplay(display))
- {
- return NULL;
- }
-
- const char *result;
- switch (name)
- {
- case EGL_CLIENT_APIS:
- result = "OpenGL_ES";
- break;
- case EGL_EXTENSIONS:
- result = egl::Display::getExtensionString(display);
- break;
- case EGL_VENDOR:
- result = display->getVendorString();
- break;
- case EGL_VERSION:
- result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")";
- break;
- default:
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return NULL;
- }
-
- recordError(egl::Error(EGL_SUCCESS));
- return result;
+ return egl::GetConfigs(dpy, configs, config_size, num_config);
}
-EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
- "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
- dpy, configs, config_size, num_config);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
-
- if (!validateDisplay(display))
- {
- return EGL_FALSE;
- }
-
- if (!num_config)
- {
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return EGL_FALSE;
- }
-
- const EGLint attribList[] = {EGL_NONE};
-
- if (!display->getConfigs(configs, attribList, config_size, num_config))
- {
- recordError(egl::Error(EGL_BAD_ATTRIBUTE));
- return EGL_FALSE;
- }
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::GetCurrentDisplay();
}
-EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
- "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
- dpy, attrib_list, configs, config_size, num_config);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
-
- if (!validateDisplay(display))
- {
- return EGL_FALSE;
- }
-
- if (!num_config)
- {
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return EGL_FALSE;
- }
-
- const EGLint attribList[] = {EGL_NONE};
-
- if (!attrib_list)
- {
- attrib_list = attribList;
- }
-
- display->getConfigs(configs, attrib_list, config_size, num_config);
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::GetCurrentSurface(readdraw);
}
-EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
- dpy, config, attribute, value);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
-
- if (!validateConfig(display, config))
- {
- return EGL_FALSE;
- }
-
- if (!display->getConfigAttrib(config, attribute, value))
- {
- recordError(egl::Error(EGL_BAD_ATTRIBUTE));
- return EGL_FALSE;
- }
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::GetDisplay(display_id);
}
-EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
+EGLint EGLAPIENTRY eglGetError(void)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
- "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
-
- if (!validateConfig(display, config))
- {
- return EGL_NO_SURFACE;
- }
-
- if (!rx::IsValidEGLNativeWindowType(win))
- {
- recordError(egl::Error(EGL_BAD_NATIVE_WINDOW));
- return EGL_NO_SURFACE;
- }
-
- EGLSurface surface = EGL_NO_SURFACE;
- egl::Error error = display->createWindowSurface(win, config, attrib_list, &surface);
- if (error.isError())
- {
- recordError(error);
- return EGL_NO_SURFACE;
- }
-
- return surface;
+ return egl::GetError();
}
-EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
- dpy, config, attrib_list);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
-
- if (!validateConfig(display, config))
- {
- return EGL_NO_SURFACE;
- }
-
- EGLSurface surface = EGL_NO_SURFACE;
- egl::Error error = display->createOffscreenSurface(config, NULL, attrib_list, &surface);
- if (error.isError())
- {
- recordError(error);
- return EGL_NO_SURFACE;
- }
-
- return surface;
+ return egl::Initialize(dpy, major, minor);
}
-EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
- "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
-
- if (!validateConfig(display, config))
- {
- return EGL_NO_SURFACE;
- }
-
- UNIMPLEMENTED(); // FIXME
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_NO_SURFACE;
+ return egl::MakeCurrent(dpy, draw, read, ctx);
}
-EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
- if (!validateSurface(display, eglSurface))
- {
- return EGL_FALSE;
- }
-
- if (surface == EGL_NO_SURFACE)
- {
- recordError(egl::Error(EGL_BAD_SURFACE));
- return EGL_FALSE;
- }
-
- display->destroySurface((egl::Surface*)surface);
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::QueryContext(dpy, ctx, attribute, value);
}
-EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+const char* EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
- dpy, surface, attribute, value);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- egl::Surface *eglSurface = (egl::Surface*)surface;
-
- if (!validateSurface(display, eglSurface))
- {
- return EGL_FALSE;
- }
-
- if (surface == EGL_NO_SURFACE)
- {
- recordError(egl::Error(EGL_BAD_SURFACE));
- return EGL_FALSE;
- }
-
- switch (attribute)
- {
- case EGL_VG_ALPHA_FORMAT:
- UNIMPLEMENTED(); // FIXME
- break;
- case EGL_VG_COLORSPACE:
- UNIMPLEMENTED(); // FIXME
- break;
- case EGL_CONFIG_ID:
- *value = eglSurface->getConfigID();
- break;
- case EGL_HEIGHT:
- *value = eglSurface->getHeight();
- break;
- case EGL_HORIZONTAL_RESOLUTION:
- UNIMPLEMENTED(); // FIXME
- break;
- case EGL_LARGEST_PBUFFER:
- UNIMPLEMENTED(); // FIXME
- break;
- case EGL_MIPMAP_TEXTURE:
- UNIMPLEMENTED(); // FIXME
- break;
- case EGL_MIPMAP_LEVEL:
- UNIMPLEMENTED(); // FIXME
- break;
- case EGL_MULTISAMPLE_RESOLVE:
- UNIMPLEMENTED(); // FIXME
- break;
- case EGL_PIXEL_ASPECT_RATIO:
- *value = eglSurface->getPixelAspectRatio();
- break;
- case EGL_RENDER_BUFFER:
- *value = eglSurface->getRenderBuffer();
- break;
- case EGL_SWAP_BEHAVIOR:
- *value = eglSurface->getSwapBehavior();
- break;
- case EGL_TEXTURE_FORMAT:
- *value = eglSurface->getTextureFormat();
- break;
- case EGL_TEXTURE_TARGET:
- *value = eglSurface->getTextureTarget();
- break;
- case EGL_VERTICAL_RESOLUTION:
- UNIMPLEMENTED(); // FIXME
- break;
- case EGL_WIDTH:
- *value = eglSurface->getWidth();
- break;
- case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
- *value = eglSurface->isPostSubBufferSupported();
- break;
- case EGL_FIXED_SIZE_ANGLE:
- *value = eglSurface->isFixedSize();
- break;
- default:
- recordError(egl::Error(EGL_BAD_ATTRIBUTE));
- return EGL_FALSE;
- }
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::QueryString(dpy, name);
}
-EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
+EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
{
- TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)",
- dpy, surface, attribute, value);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- egl::Surface *eglSurface = (egl::Surface*)surface;
-
- switch (attribute)
- {
- case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
- {
- if (!validateSurface(display, eglSurface))
- {
- return EGL_FALSE;
- }
-
- if (surface == EGL_NO_SURFACE)
- {
- recordError(egl::Error(EGL_BAD_SURFACE));
- return EGL_FALSE;
- }
-
- rx::SwapChain *swapchain = eglSurface->getSwapChain();
- *value = (void*) (swapchain ? swapchain->getShareHandle() : NULL);
- }
- break;
-#if defined(ANGLE_ENABLE_D3D11)
- case EGL_DEVICE_EXT:
- {
- if (!validateDisplay(display))
- {
- return EGL_FALSE;
- }
-
- rx::Renderer *renderer = display->getRenderer();
- if (!renderer)
- {
- *value = NULL;
- break;
- }
-
- if (renderer->getMajorShaderModel() < 4)
- {
- recordError(egl::Error(EGL_BAD_CONTEXT));
- return EGL_FALSE;
- }
-
- *value = static_cast<rx::Renderer11*>(renderer)->getDevice();
- }
- break;
-#endif
- default:
- recordError(egl::Error(EGL_BAD_ATTRIBUTE));
- return EGL_FALSE;
- }
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::QuerySurface(dpy, surface, attribute, value);
}
-EGLBoolean __stdcall eglBindAPI(EGLenum api)
+EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
{
- EVENT("(EGLenum api = 0x%X)", api);
-
- switch (api)
- {
- case EGL_OPENGL_API:
- case EGL_OPENVG_API:
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return EGL_FALSE; // Not supported by this implementation
- case EGL_OPENGL_ES_API:
- break;
- default:
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return EGL_FALSE;
- }
-
- egl::setCurrentAPI(api);
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::SwapBuffers(dpy, surface);
}
-EGLenum __stdcall eglQueryAPI(void)
+EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
{
- EVENT("()");
-
- EGLenum API = egl::getCurrentAPI();
-
- recordError(egl::Error(EGL_SUCCESS));
- return API;
+ return egl::Terminate(dpy);
}
-EGLBoolean __stdcall eglWaitClient(void)
+EGLBoolean EGLAPIENTRY eglWaitGL(void)
{
- EVENT("()");
-
- UNIMPLEMENTED(); // FIXME
-
- recordError(egl::Error(EGL_SUCCESS));
- return 0;
+ return egl::WaitGL();
}
-EGLBoolean __stdcall eglReleaseThread(void)
+EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)
{
- EVENT("()");
-
- eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::WaitNative(engine);
}
-EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
- "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
- dpy, buftype, buffer, config, attrib_list);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
-
- if (!validateConfig(display, config))
- {
- return EGL_NO_SURFACE;
- }
-
- if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
- {
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return EGL_NO_SURFACE;
- }
-
- EGLSurface surface = EGL_NO_SURFACE;
- egl::Error error = display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list, &surface);
- if (error.isError())
- {
- recordError(error);
- return EGL_NO_SURFACE;
- }
-
- return surface;
+ return egl::BindTexImage(dpy, surface, buffer);
}
-EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
- dpy, surface, attribute, value);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
- if (!validateSurface(display, eglSurface))
- {
- return EGL_FALSE;
- }
-
- switch (attribute)
- {
- case EGL_WIDTH:
- if (!eglSurface->isFixedSize() || !value) {
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return EGL_FALSE;
- }
- eglSurface->setFixedWidth(value);
- return EGL_TRUE;
- case EGL_HEIGHT:
- if (!eglSurface->isFixedSize() || !value) {
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return EGL_FALSE;
- }
- eglSurface->setFixedHeight(value);
- return EGL_TRUE;
- default:
- break;
- }
-
- UNIMPLEMENTED(); // FIXME
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::ReleaseTexImage(dpy, surface, buffer);
}
-EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
- if (!validateSurface(display, eglSurface))
- {
- return EGL_FALSE;
- }
-
- if (buffer != EGL_BACK_BUFFER)
- {
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return EGL_FALSE;
- }
-
- if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
- {
- recordError(egl::Error(EGL_BAD_SURFACE));
- return EGL_FALSE;
- }
-
- if (eglSurface->getBoundTexture())
- {
- recordError(egl::Error(EGL_BAD_ACCESS));
- return EGL_FALSE;
- }
-
- if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
- {
- recordError(egl::Error(EGL_BAD_MATCH));
- return EGL_FALSE;
- }
-
- if (!glBindTexImage(eglSurface))
- {
- recordError(egl::Error(EGL_BAD_MATCH));
- return EGL_FALSE;
- }
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::SurfaceAttrib(dpy, surface, attribute, value);
}
-EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
- if (!validateSurface(display, eglSurface))
- {
- return EGL_FALSE;
- }
-
- if (buffer != EGL_BACK_BUFFER)
- {
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return EGL_FALSE;
- }
-
- if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
- {
- recordError(egl::Error(EGL_BAD_SURFACE));
- return EGL_FALSE;
- }
-
- if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
- {
- recordError(egl::Error(EGL_BAD_MATCH));
- return EGL_FALSE;
- }
-
- gl::Texture2D *texture = eglSurface->getBoundTexture();
-
- if (texture)
- {
- texture->releaseTexImage();
- }
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::SwapInterval(dpy, interval);
}
-EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
+EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
-
- if (!validateDisplay(display))
- {
- return EGL_FALSE;
- }
-
- egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
-
- if (draw_surface == NULL)
- {
- recordError(egl::Error(EGL_BAD_SURFACE));
- return EGL_FALSE;
- }
-
- draw_surface->setSwapInterval(interval);
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::BindAPI(api);
}
-EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+EGLenum EGLAPIENTRY eglQueryAPI(void)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
- "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
-
- // Get the requested client version (default is 1) and check it is 2 or 3.
- EGLint client_version = 1;
- bool reset_notification = false;
- bool robust_access = false;
-
- if (attrib_list)
- {
- for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
- {
- switch (attribute[0])
- {
- case EGL_CONTEXT_CLIENT_VERSION:
- client_version = attribute[1];
- break;
- case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
- if (attribute[1] == EGL_TRUE)
- {
- recordError(egl::Error(EGL_BAD_CONFIG)); // Unimplemented
- return EGL_NO_CONTEXT;
- // robust_access = true;
- }
- else if (attribute[1] != EGL_FALSE)
- {
- recordError(egl::Error(EGL_BAD_ATTRIBUTE));
- return EGL_NO_CONTEXT;
- }
- break;
- case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
- if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT)
- {
- reset_notification = true;
- }
- else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT)
- {
- recordError(egl::Error(EGL_BAD_ATTRIBUTE));
- return EGL_NO_CONTEXT;
- }
- break;
- default:
- recordError(egl::Error(EGL_BAD_ATTRIBUTE));
- return EGL_NO_CONTEXT;
- }
- }
- }
-
- if (client_version != 2 && client_version != 3)
- {
- recordError(egl::Error(EGL_BAD_CONFIG));
- return EGL_NO_CONTEXT;
- }
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
-
- if (share_context)
- {
- gl::Context* sharedGLContext = static_cast<gl::Context*>(share_context);
-
- if (sharedGLContext->isResetNotificationEnabled() != reset_notification)
- {
- recordError(egl::Error(EGL_BAD_MATCH));
- return EGL_NO_CONTEXT;
- }
-
- if (sharedGLContext->getClientVersion() != client_version)
- {
- recordError(egl::Error(EGL_BAD_CONTEXT));
- return EGL_NO_CONTEXT;
- }
-
- // Can not share contexts between displays
- if (sharedGLContext->getRenderer() != display->getRenderer())
- {
- recordError(egl::Error(EGL_BAD_MATCH));
- return EGL_NO_CONTEXT;
- }
- }
-
- if (!validateConfig(display, config))
- {
- return EGL_NO_CONTEXT;
- }
-
- EGLContext context = EGL_NO_CONTEXT;
- egl::Error error = display->createContext(config, client_version, static_cast<gl::Context*>(share_context),
- reset_notification, robust_access, &context);
- if (error.isError())
- {
- recordError(error);
- return EGL_NO_CONTEXT;
- }
-
- return context;
+ return egl::QueryAPI();
}
-EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- gl::Context *context = static_cast<gl::Context*>(ctx);
-
- if (!validateContext(display, context))
- {
- return EGL_FALSE;
- }
-
- if (ctx == EGL_NO_CONTEXT)
- {
- recordError(egl::Error(EGL_BAD_CONTEXT));
- return EGL_FALSE;
- }
-
- display->destroyContext(context);
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::CreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
}
-EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+EGLBoolean EGLAPIENTRY eglReleaseThread(void)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
- dpy, draw, read, ctx);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- gl::Context *context = static_cast<gl::Context*>(ctx);
-
- bool noContext = (ctx == EGL_NO_CONTEXT);
- bool noSurface = (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE);
- if (noContext != noSurface)
- {
- recordError(egl::Error(EGL_BAD_MATCH));
- return EGL_FALSE;
- }
-
- if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
- {
- return EGL_FALSE;
- }
-
- if (dpy != EGL_NO_DISPLAY && display->isInitialized())
- {
- rx::Renderer *renderer = display->getRenderer();
- if (renderer->testDeviceLost(true))
- {
- return EGL_FALSE;
- }
-
- if (renderer->isDeviceLost())
- {
- recordError(egl::Error(EGL_CONTEXT_LOST));
- return EGL_FALSE;
- }
- }
-
- if ((draw != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(draw))) ||
- (read != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(read))))
- {
- return EGL_FALSE;
- }
-
- if (draw != read)
- {
- UNIMPLEMENTED(); // FIXME
- }
-
- egl::setCurrentDisplay(dpy);
- egl::setCurrentDrawSurface(draw);
- egl::setCurrentReadSurface(read);
-
- glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::ReleaseThread();
}
-EGLContext __stdcall eglGetCurrentContext(void)
+EGLBoolean EGLAPIENTRY eglWaitClient(void)
{
- EVENT("()");
-
- EGLContext context = glGetCurrentContext();
-
- recordError(egl::Error(EGL_SUCCESS));
- return context;
+ return egl::WaitClient();
}
-EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
+EGLContext EGLAPIENTRY eglGetCurrentContext(void)
{
- EVENT("(EGLint readdraw = %d)", readdraw);
-
- if (readdraw == EGL_READ)
- {
- recordError(egl::Error(EGL_SUCCESS));
- return egl::getCurrentReadSurface();
- }
- else if (readdraw == EGL_DRAW)
- {
- recordError(egl::Error(EGL_SUCCESS));
- return egl::getCurrentDrawSurface();
- }
- else
- {
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return EGL_NO_SURFACE;
- }
+ return egl::GetCurrentContext();
}
-EGLDisplay __stdcall eglGetCurrentDisplay(void)
+EGLSync EGLAPIENTRY eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
{
- EVENT("()");
-
- EGLDisplay dpy = egl::getCurrentDisplay();
-
- recordError(egl::Error(EGL_SUCCESS));
- return dpy;
+ return egl::CreateSync(dpy, type, attrib_list);
}
-EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+EGLBoolean EGLAPIENTRY eglDestroySync(EGLDisplay dpy, EGLSync sync)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
- dpy, ctx, attribute, value);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- gl::Context *context = static_cast<gl::Context*>(ctx);
-
- if (!validateContext(display, context))
- {
- return EGL_FALSE;
- }
-
- UNIMPLEMENTED(); // FIXME
-
- recordError(egl::Error(EGL_SUCCESS));
- return 0;
+ return egl::DestroySync(dpy, sync);
}
-EGLBoolean __stdcall eglWaitGL(void)
+EGLint EGLAPIENTRY eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
{
- EVENT("()");
-
- UNIMPLEMENTED(); // FIXME
-
- recordError(egl::Error(EGL_SUCCESS));
- return 0;
+ return egl::ClientWaitSync(dpy, sync, flags, timeout);
}
-EGLBoolean __stdcall eglWaitNative(EGLint engine)
+EGLBoolean EGLAPIENTRY eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
{
- EVENT("(EGLint engine = %d)", engine);
-
- UNIMPLEMENTED(); // FIXME
-
- recordError(egl::Error(EGL_SUCCESS));
- return 0;
+ return egl::GetSyncAttrib(dpy, sync, attribute, value);
}
-EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+EGLImage EGLAPIENTRY eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- egl::Surface *eglSurface = (egl::Surface*)surface;
-
- if (!validateSurface(display, eglSurface))
- {
- return EGL_FALSE;
- }
-
- if (display->getRenderer()->isDeviceLost())
- {
- recordError(egl::Error(EGL_CONTEXT_LOST));
- return EGL_FALSE;
- }
-
- if (surface == EGL_NO_SURFACE)
- {
- recordError(egl::Error(EGL_BAD_SURFACE));
- return EGL_FALSE;
- }
-
- egl::Error error = eglSurface->swap();
- if (error.isError())
- {
- recordError(error);
- return EGL_FALSE;
- }
-
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+ return egl::CreateImage(dpy, ctx, target, buffer, attrib_list);
}
-EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+EGLBoolean EGLAPIENTRY eglDestroyImage(EGLDisplay dpy, EGLImage image)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
- if (!validateSurface(display, eglSurface))
- {
- return EGL_FALSE;
- }
-
- if (display->getRenderer()->isDeviceLost())
- {
- recordError(egl::Error(EGL_CONTEXT_LOST));
- return EGL_FALSE;
- }
-
- UNIMPLEMENTED(); // FIXME
-
- recordError(egl::Error(EGL_SUCCESS));
- return 0;
+ return egl::DestroyImage(dpy, image);
}
-EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
+EGLDisplay EGLAPIENTRY eglGetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list)
{
- EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height);
-
- if (x < 0 || y < 0 || width < 0 || height < 0)
- {
- recordError(egl::Error(EGL_BAD_PARAMETER));
- return EGL_FALSE;
- }
-
- egl::Display *display = static_cast<egl::Display*>(dpy);
- egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
-
- if (!validateSurface(display, eglSurface))
- {
- return EGL_FALSE;
- }
-
- if (display->getRenderer()->isDeviceLost())
- {
- recordError(egl::Error(EGL_CONTEXT_LOST));
- return EGL_FALSE;
- }
-
- if (surface == EGL_NO_SURFACE)
- {
- recordError(egl::Error(EGL_BAD_SURFACE));
- return EGL_FALSE;
- }
+ return egl::GetPlatformDisplay(platform, native_display, attrib_list);
+}
- egl::Error error = eglSurface->postSubBuffer(x, y, width, height);
- if (error.isError())
- {
- recordError(error);
- return EGL_FALSE;
- }
+EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list)
+{
+ return egl::CreatePlatformWindowSurface(dpy, config, native_window, attrib_list);
+}
- recordError(egl::Error(EGL_SUCCESS));
- return EGL_TRUE;
+EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list)
+{
+ return egl::CreatePlatformPixmapSurface(dpy, config, native_pixmap, attrib_list);
}
-__eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname)
+EGLBoolean EGLAPIENTRY eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
{
- EVENT("(const char *procname = \"%s\")", procname);
+ return egl::WaitSync(dpy, sync, flags);
+}
- struct Extension
- {
- const char *name;
- __eglMustCastToProperFunctionPointerType address;
- };
+EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
+{
+ return egl::QuerySurfacePointerANGLE(dpy, surface, attribute, value);
+}
- static const Extension eglExtensions[] =
- {
- { "eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)eglQuerySurfacePointerANGLE },
- { "eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)eglPostSubBufferNV },
- { "eglGetPlatformDisplayEXT", (__eglMustCastToProperFunctionPointerType)eglGetPlatformDisplayEXT },
- { "", NULL },
- };
+EGLBoolean EGLAPIENTRY eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ return egl::PostSubBufferNV(dpy, surface, x, y, width, height);
+}
- for (unsigned int ext = 0; ext < ArraySize(eglExtensions); ext++)
- {
- if (strcmp(procname, eglExtensions[ext].name) == 0)
- {
- return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;
- }
- }
+EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
+{
+ return egl::GetPlatformDisplayEXT(platform, native_display, attrib_list);
+}
- return glGetProcAddress(procname);
+__eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
+{
+ return egl::GetProcAddress(procname);
}
+
}
diff --git a/src/3rdparty/angle/src/libEGL/libEGL.def b/src/3rdparty/angle/src/libEGL/libEGL.def
index d7949d0354..823cba2f88 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL.def
+++ b/src/3rdparty/angle/src/libEGL/libEGL.def
@@ -39,3 +39,15 @@ EXPORTS
eglGetPlatformDisplayEXT @35
eglQuerySurfacePointerANGLE @36
eglPostSubBufferNV @37
+
+ ; 1.5 entry points
+ eglCreateSync @38
+ eglDestroySync @39
+ eglClientWaitSync @40
+ eglGetSyncAttrib @41
+ eglCreateImage @42
+ eglDestroyImage @43
+ eglGetPlatformDisplay @44
+ eglCreatePlatformWindowSurface @45
+ eglCreatePlatformPixmapSurface @46
+ eglWaitSync @47
diff --git a/src/3rdparty/angle/src/libEGL/libEGL.rc b/src/3rdparty/angle/src/libEGL/libEGL.rc
deleted file mode 100644
index 65e0aa50c8..0000000000
--- a/src/3rdparty/angle/src/libEGL/libEGL.rc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include <windows.h>
-#include "../common/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,0,0
- PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,0,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) 2011 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/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def b/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def
index 492ad4d0cf..6a771a54b8 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def
+++ b/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def
@@ -39,3 +39,15 @@ EXPORTS
eglGetPlatformDisplayEXT@12 @35
eglQuerySurfacePointerANGLE@16 @36
eglPostSubBufferNV@24 @37
+
+ ; 1.5 entry points
+ eglCreateSync @38
+ eglDestroySync @39
+ eglClientWaitSync @40
+ eglGetSyncAttrib @41
+ eglCreateImage @42
+ eglDestroyImage @43
+ eglGetPlatformDisplay @44
+ eglCreatePlatformWindowSurface @45
+ eglCreatePlatformPixmapSurface @46
+ eglWaitSync @47
diff --git a/src/3rdparty/angle/src/libEGL/libEGLd.def b/src/3rdparty/angle/src/libEGL/libEGLd.def
index 0ebd27d0e1..cab7dc9d24 100644
--- a/src/3rdparty/angle/src/libEGL/libEGLd.def
+++ b/src/3rdparty/angle/src/libEGL/libEGLd.def
@@ -39,3 +39,15 @@ EXPORTS
eglGetPlatformDisplayEXT @35
eglQuerySurfacePointerANGLE @36
eglPostSubBufferNV @37
+
+ ; 1.5 entry points
+ eglCreateSync @38
+ eglDestroySync @39
+ eglClientWaitSync @40
+ eglGetSyncAttrib @41
+ eglCreateImage @42
+ eglDestroyImage @43
+ eglGetPlatformDisplay @44
+ eglCreatePlatformWindowSurface @45
+ eglCreatePlatformPixmapSurface @46
+ eglWaitSync @47
diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
deleted file mode 100644
index e88cad775f..0000000000
--- a/src/3rdparty/angle/src/libEGL/main.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// main.cpp: DLL entry point and management of thread-local data.
-
-#include "libEGL/main.h"
-
-#include "common/debug.h"
-#include "common/tls.h"
-
-static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
-
-namespace egl
-{
-
-Current *AllocateCurrent()
-{
- ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
- if (currentTLS == TLS_OUT_OF_INDEXES)
- {
- return NULL;
- }
-
- Current *current = new Current();
- current->error = EGL_SUCCESS;
- current->API = EGL_OPENGL_ES_API;
- current->display = EGL_NO_DISPLAY;
- current->drawSurface = EGL_NO_SURFACE;
- current->readSurface = EGL_NO_SURFACE;
-
- if (!SetTLSValue(currentTLS, current))
- {
- ERR("Could not set thread local storage.");
- return NULL;
- }
-
- return current;
-}
-
-void DeallocateCurrent()
-{
- Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
- SafeDelete(current);
- SetTLSValue(currentTLS, NULL);
-}
-
-}
-
-#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
-
-extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
-{
- switch (reason)
- {
- case DLL_PROCESS_ATTACH:
- {
-#if defined(ANGLE_ENABLE_DEBUG_TRACE)
- FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
-
- if (debug)
- {
- fclose(debug);
- debug = fopen(TRACE_OUTPUT_FILE, "wt"); // Erase
-
- if (debug)
- {
- fclose(debug);
- }
- }
-#endif
-
- currentTLS = CreateTLSIndex();
- if (currentTLS == TLS_OUT_OF_INDEXES)
- {
- return FALSE;
- }
-
-#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
- gl::InitializeDebugAnnotations();
-#endif
- }
- // Fall through to initialize index
- case DLL_THREAD_ATTACH:
- {
- egl::AllocateCurrent();
- }
- break;
- case DLL_THREAD_DETACH:
- {
- egl::DeallocateCurrent();
- }
- break;
- case DLL_PROCESS_DETACH:
- {
- egl::DeallocateCurrent();
- DestroyTLSIndex(currentTLS);
-
-#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
- gl::UninitializeDebugAnnotations();
-#endif
- }
- break;
- default:
- break;
- }
-
- return TRUE;
-}
-
-#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
-
-namespace egl
-{
-
-Current *GetCurrentData()
-{
-#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
- Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
-
- // ANGLE issue 488: when the dll is loaded after thread initialization,
- // thread local storage (current) might not exist yet.
- return (current ? current : AllocateCurrent());
-#else
- // No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
- static Current current = { EGL_SUCCESS, EGL_OPENGL_ES_API, EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE };
- return &current;
-#endif
-}
-
-void recordError(const Error &error)
-{
- Current *current = GetCurrentData();
-
- current->error = error.getCode();
-}
-
-EGLint getCurrentError()
-{
- Current *current = GetCurrentData();
-
- return current->error;
-}
-
-void setCurrentAPI(EGLenum API)
-{
- Current *current = GetCurrentData();
-
- current->API = API;
-}
-
-EGLenum getCurrentAPI()
-{
- Current *current = GetCurrentData();
-
- return current->API;
-}
-
-void setCurrentDisplay(EGLDisplay dpy)
-{
- Current *current = GetCurrentData();
-
- current->display = dpy;
-}
-
-EGLDisplay getCurrentDisplay()
-{
- Current *current = GetCurrentData();
-
- return current->display;
-}
-
-void setCurrentDrawSurface(EGLSurface surface)
-{
- Current *current = GetCurrentData();
-
- current->drawSurface = surface;
-}
-
-EGLSurface getCurrentDrawSurface()
-{
- Current *current = GetCurrentData();
-
- return current->drawSurface;
-}
-
-void setCurrentReadSurface(EGLSurface surface)
-{
- Current *current = GetCurrentData();
-
- current->readSurface = surface;
-}
-
-EGLSurface getCurrentReadSurface()
-{
- Current *current = GetCurrentData();
-
- return current->readSurface;
-}
-
-}
diff --git a/src/3rdparty/angle/src/libEGL/main.h b/src/3rdparty/angle/src/libEGL/main.h
deleted file mode 100644
index e5361a4a5e..0000000000
--- a/src/3rdparty/angle/src/libEGL/main.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// main.h: Management of thread-local data.
-
-#ifndef LIBEGL_MAIN_H_
-#define LIBEGL_MAIN_H_
-
-#include "libEGL/Error.h"
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-namespace egl
-{
-struct Current
-{
- EGLint error;
- EGLenum API;
- EGLDisplay display;
- EGLSurface drawSurface;
- EGLSurface readSurface;
-};
-
-void recordError(const Error &error);
-EGLint getCurrentError();
-
-void setCurrentAPI(EGLenum API);
-EGLenum getCurrentAPI();
-
-void setCurrentDisplay(EGLDisplay dpy);
-EGLDisplay getCurrentDisplay();
-
-void setCurrentDrawSurface(EGLSurface surface);
-EGLSurface getCurrentDrawSurface();
-
-void setCurrentReadSurface(EGLSurface surface);
-EGLSurface getCurrentReadSurface();
-
-}
-
-#endif // LIBEGL_MAIN_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Error.cpp b/src/3rdparty/angle/src/libGLESv2/Error.cpp
deleted file mode 100644
index cc7d17eb37..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/Error.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Copyright (c) 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 gl::Error class which encapsulates an OpenGL error
-// and optional error message.
-
-#include "libGLESv2/Error.h"
-
-#include "common/angleutils.h"
-
-#include <cstdarg>
-
-namespace gl
-{
-
-Error::Error(GLenum errorCode)
- : mCode(errorCode),
- mMessage()
-{
-}
-
-Error::Error(GLenum errorCode, const char *msg, ...)
- : mCode(errorCode),
- mMessage()
-{
- va_list vararg;
- va_start(vararg, msg);
- mMessage = FormatString(msg, vararg);
- va_end(vararg);
-}
-
-Error::Error(const Error &other)
- : mCode(other.mCode),
- mMessage(other.mMessage)
-{
-}
-
-Error &Error::operator=(const Error &other)
-{
- mCode = other.mCode;
- mMessage = other.mMessage;
- return *this;
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/Error.h b/src/3rdparty/angle/src/libGLESv2/Error.h
deleted file mode 100644
index b70b5a531c..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/Error.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// Copyright (c) 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 gl::Error class which encapsulates an OpenGL error
-// and optional error message.
-
-#ifndef LIBGLESV2_ERROR_H_
-#define LIBGLESV2_ERROR_H_
-
-#include "angle_gl.h"
-
-#include <string>
-
-namespace gl
-{
-
-class Error
-{
- public:
- explicit Error(GLenum errorCode);
- Error(GLenum errorCode, const char *msg, ...);
- Error(const Error &other);
- Error &operator=(const Error &other);
-
- GLenum getCode() const { return mCode; }
- bool isError() const { return (mCode != GL_NO_ERROR); }
-
- const std::string &getMessage() const { return mMessage; }
-
- private:
- GLenum mCode;
- std::string mMessage;
-};
-
-}
-
-#endif // LIBGLESV2_ERROR_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py b/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py
deleted file mode 100644
index cf039bfc21..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-
-# This script generates a function that converts 16-bit precision floating
-# point numbers to 32-bit.
-# It is based on ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf.
-
-def convertMantissa(i):
- if i == 0:
- return 0
- elif i < 1024:
- m = i << 13
- e = 0
- while not (m & 0x00800000):
- e -= 0x00800000
- m = m << 1
- m &= ~0x00800000
- e += 0x38800000
- return m | e
- else:
- return 0x38000000 + ((i - 1024) << 13)
-
-def convertExponent(i):
- if i == 0:
- return 0
- elif i in range(1, 31):
- return i << 23
- elif i == 31:
- return 0x47800000
- elif i == 32:
- return 0x80000000
- elif i in range(33, 63):
- return 0x80000000 + ((i - 32) << 23)
- else:
- return 0xC7800000
-
-def convertOffset(i):
- if i == 0 or i == 32:
- return 0
- else:
- return 1024
-
-print """//
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// This file is automatically generated.
-
-namespace gl
-{
-"""
-
-print "const static unsigned g_mantissa[2048] = {"
-for i in range(0, 2048):
- print " %#010x," % convertMantissa(i)
-print "};\n"
-
-print "const static unsigned g_exponent[64] = {"
-for i in range(0, 64):
- print " %#010x," % convertExponent(i)
-print "};\n"
-
-print "const static unsigned g_offset[64] = {"
-for i in range(0, 64):
- print " %#010x," % convertOffset(i)
-print "};\n"
-
-print """float float16ToFloat32(unsigned short h)
-{
- unsigned i32 = g_mantissa[g_offset[h >> 10] + (h & 0x3ff)] + g_exponent[h >> 10];
- return *(float*) &i32;
-}
-}
-"""
diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
deleted file mode 100644
index 3d57262e3c..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
+++ /dev/null
@@ -1,672 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// 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 "libGLESv2/Framebuffer.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/RenderTarget.h"
-#include "libGLESv2/renderer/RenderbufferImpl.h"
-#include "libGLESv2/renderer/Workarounds.h"
-#include "libGLESv2/renderer/d3d/TextureD3D.h"
-#include "libGLESv2/renderer/d3d/RenderbufferD3D.h"
-
-#include "common/utilities.h"
-
-namespace rx
-{
-// TODO: Move these functions, and the D3D-specific header inclusions above,
-// to FramebufferD3D.
-gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT)
-{
- if (attachment->isTexture())
- {
- gl::Texture *texture = attachment->getTexture();
- ASSERT(texture);
- TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
- const gl::ImageIndex *index = attachment->getTextureImageIndex();
- ASSERT(index);
- return textureD3D->getRenderTarget(*index, outRT);
- }
- else
- {
- gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
- ASSERT(renderbuffer);
- RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
- *outRT = renderbufferD3D->getRenderTarget();
- return gl::Error(GL_NO_ERROR);
- }
-}
-
-// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
-unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
-{
- if (attachment->isTexture())
- {
- gl::Texture *texture = attachment->getTexture();
- ASSERT(texture);
- TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
- const gl::ImageIndex *index = attachment->getTextureImageIndex();
- ASSERT(index);
- return textureD3D->getRenderTargetSerial(*index);
- }
-
- gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
- ASSERT(renderbuffer);
- RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
- return renderbufferD3D->getRenderTargetSerial();
-}
-
-}
-
-namespace gl
-{
-
-Framebuffer::Framebuffer(GLuint id)
- : mId(id),
- mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
- mDepthbuffer(NULL),
- mStencilbuffer(NULL)
-{
- for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
- {
- mColorbuffers[colorAttachment] = NULL;
- mDrawBufferStates[colorAttachment] = GL_NONE;
- }
- mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
-}
-
-Framebuffer::~Framebuffer()
-{
- for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
- {
- SafeDelete(mColorbuffers[colorAttachment]);
- }
- SafeDelete(mDepthbuffer);
- SafeDelete(mStencilbuffer);
-}
-
-void Framebuffer::detachTexture(GLuint textureId)
-{
- for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
- {
- FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
-
- if (attachment && attachment->isTextureWithId(textureId))
- {
- SafeDelete(mColorbuffers[colorAttachment]);
- }
- }
-
- if (mDepthbuffer && mDepthbuffer->isTextureWithId(textureId))
- {
- SafeDelete(mDepthbuffer);
- }
-
- if (mStencilbuffer && mStencilbuffer->isTextureWithId(textureId))
- {
- SafeDelete(mStencilbuffer);
- }
-}
-
-void Framebuffer::detachRenderbuffer(GLuint renderbufferId)
-{
- for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
- {
- FramebufferAttachment *attachment = mColorbuffers[colorAttachment];
-
- if (attachment && attachment->isRenderbufferWithId(renderbufferId))
- {
- SafeDelete(mColorbuffers[colorAttachment]);
- }
- }
-
- if (mDepthbuffer && mDepthbuffer->isRenderbufferWithId(renderbufferId))
- {
- SafeDelete(mDepthbuffer);
- }
-
- if (mStencilbuffer && mStencilbuffer->isRenderbufferWithId(renderbufferId))
- {
- SafeDelete(mStencilbuffer);
- }
-}
-
-FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
-{
- ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
- return mColorbuffers[colorAttachment];
-}
-
-FramebufferAttachment *Framebuffer::getDepthbuffer() const
-{
- return mDepthbuffer;
-}
-
-FramebufferAttachment *Framebuffer::getStencilbuffer() const
-{
- return mStencilbuffer;
-}
-
-FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const
-{
- return (hasValidDepthStencil() ? mDepthbuffer : NULL);
-}
-
-FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const
-{
- FramebufferAttachment *depthstencilbuffer = mDepthbuffer;
-
- if (!depthstencilbuffer)
- {
- depthstencilbuffer = mStencilbuffer;
- }
-
- return depthstencilbuffer;
-}
-
-FramebufferAttachment *Framebuffer::getReadColorbuffer() const
-{
- // Will require more logic if glReadBuffers is supported
- return mColorbuffers[0];
-}
-
-GLenum Framebuffer::getReadColorbufferType() const
-{
- // Will require more logic if glReadBuffers is supported
- return (mColorbuffers[0] ? mColorbuffers[0]->type() : GL_NONE);
-}
-
-FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
-{
- for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
- {
- if (mColorbuffers[colorAttachment])
- {
- return mColorbuffers[colorAttachment];
- }
- }
-
- return NULL;
-}
-
-FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
-{
- if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
- {
- return getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
- }
- else
- {
- switch (attachment)
- {
- case GL_DEPTH_ATTACHMENT:
- return getDepthbuffer();
- case GL_STENCIL_ATTACHMENT:
- return getStencilbuffer();
- case GL_DEPTH_STENCIL_ATTACHMENT:
- return getDepthStencilBuffer();
- default:
- UNREACHABLE();
- return NULL;
- }
- }
-}
-
-GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
-{
- return mDrawBufferStates[colorAttachment];
-}
-
-void Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer)
-{
- mDrawBufferStates[colorAttachment] = drawBuffer;
-}
-
-bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
-{
- return (mColorbuffers[colorAttachment] && mDrawBufferStates[colorAttachment] != GL_NONE);
-}
-
-bool Framebuffer::hasEnabledColorAttachment() const
-{
- for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
- {
- if (isEnabledColorAttachment(colorAttachment))
- {
- return true;
- }
- }
-
- return false;
-}
-
-bool Framebuffer::hasStencil() const
-{
- return (mStencilbuffer && mStencilbuffer->getStencilSize() > 0);
-}
-
-bool Framebuffer::usingExtendedDrawBuffers() const
-{
- for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
- {
- if (isEnabledColorAttachment(colorAttachment))
- {
- return true;
- }
- }
-
- return false;
-}
-
-GLenum Framebuffer::completeness(const gl::Data &data) const
-{
- int width = 0;
- int height = 0;
- unsigned int colorbufferSize = 0;
- int samples = -1;
- bool missingAttachment = true;
-
- for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
- {
- const FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
-
- if (colorbuffer)
- {
- if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
-
- GLenum internalformat = colorbuffer->getInternalFormat();
- const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
- const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
- if (colorbuffer->isTexture())
- {
- if (!formatCaps.renderable)
- {
- return GL_FRAMEBUFFER_UNSUPPORTED;
- }
-
- if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
- }
- else
- {
- if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
- }
-
- if (!missingAttachment)
- {
- // all color attachments must have the same width and height
- if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
- }
-
- // 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.
- if (colorbuffer->getSamples() != samples)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
- }
-
- // 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 (data.clientVersion < 3)
- {
- if (formatInfo.pixelBytes != colorbufferSize)
- {
- return GL_FRAMEBUFFER_UNSUPPORTED;
- }
- }
-
- // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
- for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
- {
- const FramebufferAttachment *previousAttachment = mColorbuffers[previousColorAttachment];
-
- if (previousAttachment &&
- (colorbuffer->id() == previousAttachment->id() &&
- colorbuffer->type() == previousAttachment->type()))
- {
- return GL_FRAMEBUFFER_UNSUPPORTED;
- }
- }
- }
- else
- {
- width = colorbuffer->getWidth();
- height = colorbuffer->getHeight();
- samples = colorbuffer->getSamples();
- colorbufferSize = formatInfo.pixelBytes;
- missingAttachment = false;
- }
- }
- }
-
- if (mDepthbuffer)
- {
- if (mDepthbuffer->getWidth() == 0 || mDepthbuffer->getHeight() == 0)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
-
- GLenum internalformat = mDepthbuffer->getInternalFormat();
- const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
- const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
- if (mDepthbuffer->isTexture())
- {
- // depth texture attachments require OES/ANGLE_depth_texture
- if (!data.extensions->depthTextures)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
-
- if (!formatCaps.renderable)
- {
- return GL_FRAMEBUFFER_UNSUPPORTED;
- }
-
- if (formatInfo.depthBits == 0)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
- }
- else
- {
- if (!formatCaps.renderable || formatInfo.depthBits == 0)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
- }
-
- if (missingAttachment)
- {
- width = mDepthbuffer->getWidth();
- height = mDepthbuffer->getHeight();
- samples = mDepthbuffer->getSamples();
- missingAttachment = false;
- }
- else if (width != mDepthbuffer->getWidth() || height != mDepthbuffer->getHeight())
- {
- return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
- }
- else if (samples != mDepthbuffer->getSamples())
- {
- return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
- }
- }
-
- if (mStencilbuffer)
- {
- if (mStencilbuffer->getWidth() == 0 || mStencilbuffer->getHeight() == 0)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
-
- GLenum internalformat = mStencilbuffer->getInternalFormat();
- const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
- const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
- if (mStencilbuffer->isTexture())
- {
- // texture stencil attachments come along as part
- // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
- if (!data.extensions->depthTextures)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
-
- if (!formatCaps.renderable)
- {
- return GL_FRAMEBUFFER_UNSUPPORTED;
- }
-
- if (formatInfo.stencilBits == 0)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
- }
- else
- {
- if (!formatCaps.renderable || formatInfo.stencilBits == 0)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
- }
-
- if (missingAttachment)
- {
- width = mStencilbuffer->getWidth();
- height = mStencilbuffer->getHeight();
- samples = mStencilbuffer->getSamples();
- missingAttachment = false;
- }
- else if (width != mStencilbuffer->getWidth() || height != mStencilbuffer->getHeight())
- {
- return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
- }
- else if (samples != mStencilbuffer->getSamples())
- {
- return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
- }
- }
-
- // 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 (mDepthbuffer && mStencilbuffer && !hasValidDepthStencil())
- {
- return GL_FRAMEBUFFER_UNSUPPORTED;
- }
-
- // we need to have at least one attachment to be complete
- if (missingAttachment)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
- }
-
- return GL_FRAMEBUFFER_COMPLETE;
-}
-
-Error Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
-{
- GLuint maxDimension = caps.maxRenderbufferSize;
- return invalidateSub(numAttachments, attachments, 0, 0, maxDimension, maxDimension);
-}
-
-Error Framebuffer::invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)
-{
- for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex)
- {
- GLenum attachmentTarget = attachments[attachIndex];
-
- FramebufferAttachment *attachment = (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer()
- : getAttachment(attachmentTarget);
-
- if (attachment)
- {
- rx::RenderTarget *renderTarget = NULL;
- Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
- if (error.isError())
- {
- return error;
- }
-
- renderTarget->invalidate(x, y, width, height);
- }
- }
-
- return Error(GL_NO_ERROR);
-}
-
-DefaultFramebuffer::DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil)
- : Framebuffer(0)
-{
- Renderbuffer *colorRenderbuffer = new Renderbuffer(colorbuffer, 0);
- mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
-
- Renderbuffer *depthStencilBuffer = new Renderbuffer(depthStencil, 0);
-
- // Make a new attachment objects to ensure we do not double-delete
- // See angle issue 686
- mDepthbuffer = (depthStencilBuffer->getDepthSize() != 0 ? new RenderbufferAttachment(GL_DEPTH_ATTACHMENT, depthStencilBuffer) : NULL);
- mStencilbuffer = (depthStencilBuffer->getStencilSize() != 0 ? new RenderbufferAttachment(GL_STENCIL_ATTACHMENT, depthStencilBuffer) : NULL);
-
- mDrawBufferStates[0] = GL_BACK;
- mReadBufferState = GL_BACK;
-}
-
-int Framebuffer::getSamples(const gl::Data &data) const
-{
- if (completeness(data) == GL_FRAMEBUFFER_COMPLETE)
- {
- // for a complete framebuffer, all attachments must have the same sample count
- // in this case return the first nonzero sample size
- for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
- {
- if (mColorbuffers[colorAttachment])
- {
- return mColorbuffers[colorAttachment]->getSamples();
- }
- }
- }
-
- return 0;
-}
-
-bool Framebuffer::hasValidDepthStencil() const
-{
- // A valid depth-stencil attachment has the same resource bound to both the
- // depth and stencil attachment points.
- return (mDepthbuffer && mStencilbuffer &&
- mDepthbuffer->type() == mStencilbuffer->type() &&
- mDepthbuffer->id() == mStencilbuffer->id());
-}
-
-ColorbufferInfo Framebuffer::getColorbuffersForRender(const rx::Workarounds &workarounds) const
-{
- ColorbufferInfo colorbuffersForRender;
-
- for (size_t colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; ++colorAttachment)
- {
- GLenum drawBufferState = mDrawBufferStates[colorAttachment];
- FramebufferAttachment *colorbuffer = mColorbuffers[colorAttachment];
-
- if (colorbuffer != NULL && drawBufferState != GL_NONE)
- {
- ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
- colorbuffersForRender.push_back(colorbuffer);
- }
- else if (!workarounds.mrtPerfWorkaround)
- {
- colorbuffersForRender.push_back(NULL);
- }
- }
-
- return colorbuffersForRender;
-}
-
-void Framebuffer::setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex)
-{
- setAttachment(attachment, new TextureAttachment(attachment, texture, imageIndex));
-}
-
-void Framebuffer::setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer)
-{
- setAttachment(attachment, new RenderbufferAttachment(attachment, renderbuffer));
-}
-
-void Framebuffer::setNULLAttachment(GLenum attachment)
-{
- setAttachment(attachment, NULL);
-}
-
-void Framebuffer::setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj)
-{
- if (attachment >= GL_COLOR_ATTACHMENT0 && attachment < (GL_COLOR_ATTACHMENT0 + IMPLEMENTATION_MAX_DRAW_BUFFERS))
- {
- size_t colorAttachment = attachment - GL_COLOR_ATTACHMENT0;
- SafeDelete(mColorbuffers[colorAttachment]);
- mColorbuffers[colorAttachment] = attachmentObj;
- }
- else if (attachment == GL_DEPTH_ATTACHMENT)
- {
- SafeDelete(mDepthbuffer);
- mDepthbuffer = attachmentObj;
- }
- else if (attachment == GL_STENCIL_ATTACHMENT)
- {
- SafeDelete(mStencilbuffer);
- mStencilbuffer = attachmentObj;
- }
- else if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
- {
- SafeDelete(mDepthbuffer);
- SafeDelete(mStencilbuffer);
-
- // ensure this is a legitimate depth+stencil format
- if (attachmentObj && attachmentObj->getDepthSize() > 0 && attachmentObj->getStencilSize() > 0)
- {
- mDepthbuffer = attachmentObj;
-
- // Make a new attachment object to ensure we do not double-delete
- // See angle issue 686
- if (attachmentObj->isTexture())
- {
- mStencilbuffer = new TextureAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getTexture(),
- *attachmentObj->getTextureImageIndex());
- }
- else
- {
- mStencilbuffer = new RenderbufferAttachment(GL_DEPTH_STENCIL_ATTACHMENT, attachmentObj->getRenderbuffer());
- }
- }
- }
- else
- {
- UNREACHABLE();
- }
-}
-
-GLenum DefaultFramebuffer::completeness(const gl::Data &) const
-{
- // The default framebuffer *must* always be complete, though it may not be
- // subject to the same rules as application FBOs. ie, it could have 0x0 size.
- return GL_FRAMEBUFFER_COMPLETE;
-}
-
-FramebufferAttachment *DefaultFramebuffer::getAttachment(GLenum attachment) const
-{
- switch (attachment)
- {
- case GL_COLOR:
- case GL_BACK:
- return getColorbuffer(0);
- case GL_DEPTH:
- return getDepthbuffer();
- case GL_STENCIL:
- return getStencilbuffer();
- case GL_DEPTH_STENCIL:
- return getDepthStencilBuffer();
- default:
- UNREACHABLE();
- return NULL;
- }
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
deleted file mode 100644
index d0fe8935ea..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
+++ /dev/null
@@ -1,126 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// 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 LIBGLESV2_FRAMEBUFFER_H_
-#define LIBGLESV2_FRAMEBUFFER_H_
-
-#include "libGLESv2/Error.h"
-
-#include "common/angleutils.h"
-#include "common/RefCountObject.h"
-#include "Constants.h"
-
-#include <vector>
-
-namespace rx
-{
-class RenderbufferImpl;
-struct Workarounds;
-}
-
-namespace gl
-{
-class FramebufferAttachment;
-class Texture;
-class Renderbuffer;
-struct ImageIndex;
-struct Caps;
-struct Extensions;
-class TextureCapsMap;
-struct Data;
-
-typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
-
-class Framebuffer
-{
- public:
- Framebuffer(GLuint id);
- virtual ~Framebuffer();
-
- GLuint id() const { return mId; }
-
- void setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex);
- void setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer);
- void setNULLAttachment(GLenum attachment);
-
- void detachTexture(GLuint texture);
- void detachRenderbuffer(GLuint renderbuffer);
-
- FramebufferAttachment *getColorbuffer(unsigned int colorAttachment) const;
- FramebufferAttachment *getDepthbuffer() const;
- FramebufferAttachment *getStencilbuffer() const;
- FramebufferAttachment *getDepthStencilBuffer() const;
- FramebufferAttachment *getDepthOrStencilbuffer() const;
- FramebufferAttachment *getReadColorbuffer() const;
- GLenum getReadColorbufferType() const;
- FramebufferAttachment *getFirstColorbuffer() const;
-
- virtual FramebufferAttachment *getAttachment(GLenum attachment) const;
-
- GLenum getDrawBufferState(unsigned int colorAttachment) const;
- void setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer);
-
- bool isEnabledColorAttachment(unsigned int colorAttachment) const;
- bool hasEnabledColorAttachment() const;
- bool hasStencil() const;
- int getSamples(const gl::Data &data) const;
- bool usingExtendedDrawBuffers() const;
-
- virtual GLenum completeness(const gl::Data &data) const;
- bool hasValidDepthStencil() const;
-
- Error invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
- Error invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
-
- // Use this method to retrieve the color buffer map when doing rendering.
- // It will apply a workaround for poor shader performance on some systems
- // by compacting the list to skip NULL values.
- ColorbufferInfo getColorbuffersForRender(const rx::Workarounds &workarounds) const;
-
- protected:
- GLuint mId;
-
- FramebufferAttachment *mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS];
- GLenum mDrawBufferStates[IMPLEMENTATION_MAX_DRAW_BUFFERS];
- GLenum mReadBufferState;
-
- FramebufferAttachment *mDepthbuffer;
- FramebufferAttachment *mStencilbuffer;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Framebuffer);
-
- void setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj);
-};
-
-class DefaultFramebuffer : public Framebuffer
-{
- public:
- DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil);
-
- GLenum completeness(const gl::Data &data) const override;
- virtual FramebufferAttachment *getAttachment(GLenum attachment) const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DefaultFramebuffer);
-};
-
-}
-
-namespace rx
-{
-class RenderTarget;
-
-// TODO: place this in FramebufferD3D.h
-gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT);
-unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment);
-
-}
-
-#endif // LIBGLESV2_FRAMEBUFFER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp b/src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp
deleted file mode 100644
index c498f8a178..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// HandleAllocator.cpp: Implements the gl::HandleAllocator class, which is used
-// to allocate GL handles.
-
-#include "libGLESv2/HandleAllocator.h"
-
-#include "libGLESv2/main.h"
-
-namespace gl
-{
-
-HandleAllocator::HandleAllocator() : mBaseValue(1), mNextValue(1)
-{
-}
-
-HandleAllocator::~HandleAllocator()
-{
-}
-
-void HandleAllocator::setBaseHandle(GLuint value)
-{
- ASSERT(mBaseValue == mNextValue);
- mBaseValue = value;
- mNextValue = value;
-}
-
-GLuint HandleAllocator::allocate()
-{
- if (mFreeValues.size())
- {
- GLuint handle = mFreeValues.back();
- mFreeValues.pop_back();
- return handle;
- }
- return mNextValue++;
-}
-
-void HandleAllocator::release(GLuint handle)
-{
- if (handle == mNextValue - 1)
- {
- // Don't drop below base value
- if(mNextValue > mBaseValue)
- {
- mNextValue--;
- }
- }
- else
- {
- // Only free handles that we own - don't drop below the base value
- if (handle >= mBaseValue)
- {
- mFreeValues.push_back(handle);
- }
- }
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/HandleAllocator.h b/src/3rdparty/angle/src/libGLESv2/HandleAllocator.h
deleted file mode 100644
index a89cc86775..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/HandleAllocator.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// HandleAllocator.h: Defines the gl::HandleAllocator class, which is used to
-// allocate GL handles.
-
-#ifndef LIBGLESV2_HANDLEALLOCATOR_H_
-#define LIBGLESV2_HANDLEALLOCATOR_H_
-
-#include "common/angleutils.h"
-
-#include "angle_gl.h"
-
-#include <vector>
-
-namespace gl
-{
-
-class HandleAllocator
-{
- public:
- HandleAllocator();
- virtual ~HandleAllocator();
-
- void setBaseHandle(GLuint value);
-
- GLuint allocate();
- void release(GLuint handle);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(HandleAllocator);
-
- GLuint mBaseValue;
- GLuint mNextValue;
- typedef std::vector<GLuint> HandleList;
- HandleList mFreeValues;
-};
-
-}
-
-#endif // LIBGLESV2_HANDLEALLOCATOR_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Program.cpp b/src/3rdparty/angle/src/libGLESv2/Program.cpp
deleted file mode 100644
index 3faa8c56f6..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/Program.cpp
+++ /dev/null
@@ -1,668 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// 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 "libGLESv2/Program.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/ResourceManager.h"
-#include "libGLESv2/renderer/Renderer.h"
-
-namespace gl
-{
-const char * const g_fakepath = "C:\\fakepath";
-
-AttributeBindings::AttributeBindings()
-{
-}
-
-AttributeBindings::~AttributeBindings()
-{
-}
-
-InfoLog::InfoLog() : mInfoLog(NULL)
-{
-}
-
-InfoLog::~InfoLog()
-{
- delete[] mInfoLog;
-}
-
-
-int InfoLog::getLength() const
-{
- if (!mInfoLog)
- {
- return 0;
- }
- else
- {
- return strlen(mInfoLog) + 1;
- }
-}
-
-void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog)
-{
- int index = 0;
-
- if (bufSize > 0)
- {
- if (mInfoLog)
- {
- index = std::min(bufSize - 1, (int)strlen(mInfoLog));
- memcpy(infoLog, mInfoLog, index);
- }
-
- infoLog[index] = '\0';
- }
-
- if (length)
- {
- *length = index;
- }
-}
-
-// append a santized 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)
-{
- 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);
-
- append("%s", msg.c_str());
-}
-
-void InfoLog::append(const char *format, ...)
-{
- if (!format)
- {
- return;
- }
-
- va_list vararg;
- va_start(vararg, format);
- size_t infoLength = vsnprintf(NULL, 0, format, vararg);
- va_end(vararg);
-
- char *logPointer = NULL;
-
- if (!mInfoLog)
- {
- mInfoLog = new char[infoLength + 2];
- logPointer = mInfoLog;
- }
- else
- {
- size_t currentlogLength = strlen(mInfoLog);
- char *newLog = new char[currentlogLength + infoLength + 2];
- strcpy(newLog, mInfoLog);
-
- delete[] mInfoLog;
- mInfoLog = newLog;
-
- logPointer = mInfoLog + currentlogLength;
- }
-
- va_start(vararg, format);
- vsnprintf(logPointer, infoLength, format, vararg);
- va_end(vararg);
-
- logPointer[infoLength] = 0;
- strcpy(logPointer + infoLength, "\n");
-}
-
-void InfoLog::reset()
-{
- if (mInfoLog)
- {
- delete [] mInfoLog;
- mInfoLog = NULL;
- }
-}
-
-Program::Program(rx::Renderer *renderer, ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle)
-{
- mFragmentShader = NULL;
- mVertexShader = NULL;
- mProgramBinary.set(NULL);
- mDeleteStatus = false;
- mLinked = false;
- mRefCount = 0;
- mRenderer = renderer;
-
- resetUniformBlockBindings();
-}
-
-Program::~Program()
-{
- unlink(true);
-
- if (mVertexShader != NULL)
- {
- mVertexShader->release();
- }
-
- if (mFragmentShader != NULL)
- {
- mFragmentShader->release();
- }
-}
-
-bool Program::attachShader(Shader *shader)
-{
- if (shader->getType() == GL_VERTEX_SHADER)
- {
- if (mVertexShader)
- {
- return false;
- }
-
- mVertexShader = shader;
- mVertexShader->addRef();
- }
- else if (shader->getType() == GL_FRAGMENT_SHADER)
- {
- if (mFragmentShader)
- {
- return false;
- }
-
- mFragmentShader = shader;
- mFragmentShader->addRef();
- }
- else UNREACHABLE();
-
- return true;
-}
-
-bool Program::detachShader(Shader *shader)
-{
- if (shader->getType() == GL_VERTEX_SHADER)
- {
- if (mVertexShader != shader)
- {
- return false;
- }
-
- mVertexShader->release();
- mVertexShader = NULL;
- }
- else if (shader->getType() == GL_FRAGMENT_SHADER)
- {
- if (mFragmentShader != shader)
- {
- return false;
- }
-
- mFragmentShader->release();
- mFragmentShader = NULL;
- }
- else UNREACHABLE();
-
- return true;
-}
-
-int Program::getAttachedShadersCount() const
-{
- return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0);
-}
-
-void AttributeBindings::bindAttributeLocation(GLuint index, const char *name)
-{
- if (index < MAX_VERTEX_ATTRIBS)
- {
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- mAttributeBinding[i].erase(name);
- }
-
- mAttributeBinding[index].insert(name);
- }
-}
-
-void Program::bindAttributeLocation(GLuint index, const char *name)
-{
- mAttributeBindings.bindAttributeLocation(index, name);
-}
-
-// Links the HLSL code of the vertex and pixel shader by matching up their varyings,
-// compiling them into binaries, determining the attribute mappings, and collecting
-// a list of uniforms
-Error Program::link(const Data &data)
-{
- unlink(false);
-
- mInfoLog.reset();
- resetUniformBlockBindings();
-
- mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
- LinkResult result = mProgramBinary->link(data, mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
- mTransformFeedbackVaryings, mTransformFeedbackBufferMode);
- if (result.error.isError())
- {
- return result.error;
- }
-
- mLinked = result.linkSuccess;
- return gl::Error(GL_NO_ERROR);
-}
-
-int AttributeBindings::getAttributeBinding(const std::string &name) const
-{
- for (int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
- {
- if (mAttributeBinding[location].find(name) != mAttributeBinding[location].end())
- {
- return location;
- }
- }
-
- return -1;
-}
-
-// Returns the program object to an unlinked state, before re-linking, or at destruction
-void Program::unlink(bool destroy)
-{
- if (destroy) // Object being destructed
- {
- if (mFragmentShader)
- {
- mFragmentShader->release();
- mFragmentShader = NULL;
- }
-
- if (mVertexShader)
- {
- mVertexShader->release();
- mVertexShader = NULL;
- }
- }
-
- mProgramBinary.set(NULL);
- mLinked = false;
-}
-
-bool Program::isLinked()
-{
- return mLinked;
-}
-
-ProgramBinary* Program::getProgramBinary() const
-{
- return mProgramBinary.get();
-}
-
-Error Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
-{
- unlink(false);
-
- mInfoLog.reset();
-
- mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
- LinkResult result = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
- if (result.error.isError())
- {
- mProgramBinary.set(NULL);
- return result.error;
- }
-
- mLinked = result.linkSuccess;
- return Error(GL_NO_ERROR);
-}
-
-void Program::release()
-{
- mRefCount--;
-
- if (mRefCount == 0 && mDeleteStatus)
- {
- mResourceManager->deleteProgram(mHandle);
- }
-}
-
-void Program::addRef()
-{
- mRefCount++;
-}
-
-unsigned int Program::getRefCount() const
-{
- return mRefCount;
-}
-
-GLint Program::getProgramBinaryLength() const
-{
- ProgramBinary *programBinary = mProgramBinary.get();
- if (programBinary)
- {
- return programBinary->getLength();
- }
- else
- {
- return 0;
- }
-}
-
-int Program::getInfoLogLength() const
-{
- return mInfoLog.getLength();
-}
-
-void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
-{
- return mInfoLog.getLog(bufSize, length, infoLog);
-}
-
-void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
-{
- int total = 0;
-
- if (mVertexShader)
- {
- if (total < maxCount)
- {
- shaders[total] = mVertexShader->getHandle();
- }
-
- total++;
- }
-
- if (mFragmentShader)
- {
- if (total < maxCount)
- {
- shaders[total] = mFragmentShader->getHandle();
- }
-
- total++;
- }
-
- if (count)
- {
- *count = total;
- }
-}
-
-void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
- {
- programBinary->getActiveAttribute(index, bufsize, length, size, type, name);
- }
- else
- {
- if (bufsize > 0)
- {
- name[0] = '\0';
- }
-
- if (length)
- {
- *length = 0;
- }
-
- *type = GL_NONE;
- *size = 1;
- }
-}
-
-GLint Program::getActiveAttributeCount()
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
- {
- return programBinary->getActiveAttributeCount();
- }
- else
- {
- return 0;
- }
-}
-
-GLint Program::getActiveAttributeMaxLength()
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
- {
- return programBinary->getActiveAttributeMaxLength();
- }
- else
- {
- return 0;
- }
-}
-
-void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
- {
- return programBinary->getActiveUniform(index, bufsize, length, size, type, name);
- }
- else
- {
- if (bufsize > 0)
- {
- name[0] = '\0';
- }
-
- if (length)
- {
- *length = 0;
- }
-
- *size = 0;
- *type = GL_NONE;
- }
-}
-
-GLint Program::getActiveUniformCount()
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
- {
- return programBinary->getActiveUniformCount();
- }
- else
- {
- return 0;
- }
-}
-
-GLint Program::getActiveUniformMaxLength()
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
- {
- return programBinary->getActiveUniformMaxLength();
- }
- else
- {
- return 0;
- }
-}
-
-void Program::flagForDeletion()
-{
- mDeleteStatus = true;
-}
-
-bool Program::isFlaggedForDeletion() const
-{
- return mDeleteStatus;
-}
-
-void Program::validate(const Caps &caps)
-{
- mInfoLog.reset();
-
- ProgramBinary *programBinary = getProgramBinary();
- if (isLinked() && programBinary)
- {
- programBinary->validate(mInfoLog, caps);
- }
- else
- {
- mInfoLog.append("Program has not been successfully linked.");
- }
-}
-
-bool Program::isValidated() const
-{
- ProgramBinary *programBinary = mProgramBinary.get();
- if (programBinary)
- {
- return programBinary->isValidated();
- }
- else
- {
- return false;
- }
-}
-
-GLint Program::getActiveUniformBlockCount()
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
- {
- return static_cast<GLint>(programBinary->getActiveUniformBlockCount());
- }
- else
- {
- return 0;
- }
-}
-
-GLint Program::getActiveUniformBlockMaxLength()
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
- {
- return static_cast<GLint>(programBinary->getActiveUniformBlockMaxLength());
- }
- else
- {
- return 0;
- }
-}
-
-void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
-{
- mUniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
-}
-
-GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
-{
- return mUniformBlockBindings[uniformBlockIndex];
-}
-
-void Program::resetUniformBlockBindings()
-{
- for (unsigned int blockId = 0; blockId < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; blockId++)
- {
- mUniformBlockBindings[blockId] = 0;
- }
-}
-
-void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)
-{
- mTransformFeedbackVaryings.resize(count);
- for (GLsizei i = 0; i < count; i++)
- {
- mTransformFeedbackVaryings[i] = varyings[i];
- }
-
- mTransformFeedbackBufferMode = bufferMode;
-}
-
-void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary && index < programBinary->getTransformFeedbackVaryingCount())
- {
- const LinkedVarying &varying = programBinary->getTransformFeedbackVarying(index);
- GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
- if (length)
- {
- *length = lastNameIdx;
- }
- if (size)
- {
- *size = varying.size;
- }
- if (type)
- {
- *type = varying.type;
- }
- if (name)
- {
- memcpy(name, varying.name.c_str(), lastNameIdx);
- name[lastNameIdx] = '\0';
- }
- }
-}
-
-GLsizei Program::getTransformFeedbackVaryingCount() const
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
- {
- return static_cast<GLsizei>(programBinary->getTransformFeedbackVaryingCount());
- }
- else
- {
- return 0;
- }
-}
-
-GLsizei Program::getTransformFeedbackVaryingMaxLength() const
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
- {
- GLsizei maxSize = 0;
- for (size_t i = 0; i < programBinary->getTransformFeedbackVaryingCount(); i++)
- {
- const LinkedVarying &varying = programBinary->getTransformFeedbackVarying(i);
- maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
- }
-
- return maxSize;
- }
- else
- {
- return 0;
- }
-}
-
-GLenum Program::getTransformFeedbackBufferMode() const
-{
- ProgramBinary *programBinary = getProgramBinary();
- if (programBinary)
- {
- return programBinary->getTransformFeedbackBufferMode();
- }
- else
- {
- return mTransformFeedbackBufferMode;
- }
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/Program.h b/src/3rdparty/angle/src/libGLESv2/Program.h
deleted file mode 100644
index b92349eeef..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/Program.h
+++ /dev/null
@@ -1,151 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// 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 LIBGLESV2_PROGRAM_H_
-#define LIBGLESV2_PROGRAM_H_
-
-#include "common/angleutils.h"
-#include "common/RefCountObject.h"
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/ProgramBinary.h"
-
-#include <GLES2/gl2.h>
-
-#include <vector>
-#include <string>
-#include <set>
-
-namespace rx
-{
-class Renderer;
-}
-
-namespace gl
-{
-struct Caps;
-struct Data;
-class ResourceManager;
-class Shader;
-
-extern const char * const g_fakepath;
-
-class AttributeBindings
-{
- public:
- AttributeBindings();
- ~AttributeBindings();
-
- void bindAttributeLocation(GLuint index, const char *name);
- int getAttributeBinding(const std::string &name) const;
-
- private:
- std::set<std::string> mAttributeBinding[MAX_VERTEX_ATTRIBS];
-};
-
-class InfoLog
-{
- public:
- InfoLog();
- ~InfoLog();
-
- int getLength() const;
- void getLog(GLsizei bufSize, GLsizei *length, char *infoLog);
-
- void appendSanitized(const char *message);
- void append(const char *info, ...);
- void reset();
- private:
- DISALLOW_COPY_AND_ASSIGN(InfoLog);
- char *mInfoLog;
-};
-
-class Program
-{
- public:
- Program(rx::Renderer *renderer, ResourceManager *manager, GLuint handle);
-
- ~Program();
-
- bool attachShader(Shader *shader);
- bool detachShader(Shader *shader);
- int getAttachedShadersCount() const;
-
- void bindAttributeLocation(GLuint index, const char *name);
-
- Error link(const Data &data);
- bool isLinked();
- Error setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
- ProgramBinary *getProgramBinary() const;
-
- int getInfoLogLength() const;
- void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog);
- void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
-
- void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
- GLint getActiveAttributeCount();
- GLint getActiveAttributeMaxLength();
-
- void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
- GLint getActiveUniformCount();
- GLint getActiveUniformMaxLength();
-
- GLint getActiveUniformBlockCount();
- GLint getActiveUniformBlockMaxLength();
-
- void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding);
- GLuint getUniformBlockBinding(GLuint uniformBlockIndex) 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;
-
- void addRef();
- void release();
- unsigned int getRefCount() const;
- void flagForDeletion();
- bool isFlaggedForDeletion() const;
-
- void validate(const Caps &caps);
- bool isValidated() const;
-
- GLint getProgramBinaryLength() const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Program);
-
- void unlink(bool destroy = false);
- void resetUniformBlockBindings();
-
- Shader *mFragmentShader;
- Shader *mVertexShader;
-
- AttributeBindings mAttributeBindings;
-
- GLuint mUniformBlockBindings[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
-
- std::vector<std::string> mTransformFeedbackVaryings;
- GLuint mTransformFeedbackBufferMode;
-
- BindingPointer<ProgramBinary> mProgramBinary;
- bool mLinked;
- bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use
-
- unsigned int mRefCount;
-
- ResourceManager *mResourceManager;
- rx::Renderer *mRenderer;
- const GLuint mHandle;
-
- InfoLog mInfoLog;
-};
-}
-
-#endif // LIBGLESV2_PROGRAM_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.cpp b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
deleted file mode 100644
index cd4fc4e32a..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/Texture.cpp
+++ /dev/null
@@ -1,1012 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// Texture.cpp: Implements the gl::Texture class and its derived classes
-// Texture2D and TextureCubeMap. Implements GL texture objects and related
-// functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
-
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/ImageIndex.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/renderer/Image.h"
-#include "libGLESv2/renderer/d3d/TextureStorage.h"
-
-#include "libEGL/Surface.h"
-
-#include "common/mathutil.h"
-#include "common/utilities.h"
-
-namespace gl
-{
-
-bool IsMipmapFiltered(const gl::SamplerState &samplerState)
-{
- switch (samplerState.minFilter)
- {
- 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;
- }
-}
-
-bool IsPointSampled(const gl::SamplerState &samplerState)
-{
- return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST));
-}
-
-unsigned int Texture::mCurrentTextureSerial = 1;
-
-Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target)
- : RefCountObject(id),
- mTexture(impl),
- mTextureSerial(issueTextureSerial()),
- mUsage(GL_NONE),
- mImmutableLevelCount(0),
- mTarget(target)
-{
-}
-
-Texture::~Texture()
-{
- SafeDelete(mTexture);
-}
-
-GLenum Texture::getTarget() const
-{
- return mTarget;
-}
-
-void Texture::setUsage(GLenum usage)
-{
- mUsage = usage;
- getImplementation()->setUsage(usage);
-}
-
-GLenum Texture::getUsage() const
-{
- return mUsage;
-}
-
-GLint Texture::getBaseLevelWidth() const
-{
- const rx::Image *baseImage = getBaseLevelImage();
- return (baseImage ? baseImage->getWidth() : 0);
-}
-
-GLint Texture::getBaseLevelHeight() const
-{
- const rx::Image *baseImage = getBaseLevelImage();
- return (baseImage ? baseImage->getHeight() : 0);
-}
-
-GLint Texture::getBaseLevelDepth() const
-{
- const rx::Image *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 Texture::getBaseLevelInternalFormat() const
-{
- const rx::Image *baseImage = getBaseLevelImage();
- return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
-}
-
-GLsizei Texture::getWidth(const ImageIndex &index) const
-{
- rx::Image *image = mTexture->getImage(index);
- return image->getWidth();
-}
-
-GLsizei Texture::getHeight(const ImageIndex &index) const
-{
- rx::Image *image = mTexture->getImage(index);
- return image->getHeight();
-}
-
-GLenum Texture::getInternalFormat(const ImageIndex &index) const
-{
- rx::Image *image = mTexture->getImage(index);
- return image->getInternalFormat();
-}
-
-GLenum Texture::getActualFormat(const ImageIndex &index) const
-{
- rx::Image *image = mTexture->getImage(index);
- return image->getActualFormat();
-}
-
-Error Texture::generateMipmaps()
-{
- return getImplementation()->generateMipmaps();
-}
-
-Error Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
-{
- return mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
-}
-
-unsigned int Texture::getTextureSerial() const
-{
- return mTextureSerial;
-}
-
-unsigned int Texture::issueTextureSerial()
-{
- return mCurrentTextureSerial++;
-}
-
-bool Texture::isImmutable() const
-{
- return (mImmutableLevelCount > 0);
-}
-
-int Texture::immutableLevelCount()
-{
- return mImmutableLevelCount;
-}
-
-int Texture::mipLevels() const
-{
- return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
-}
-
-const rx::Image *Texture::getBaseLevelImage() const
-{
- return (getImplementation()->getLayerCount(0) > 0 ? getImplementation()->getImage(0, 0) : NULL);
-}
-
-Texture2D::Texture2D(rx::TextureImpl *impl, GLuint id)
- : Texture(impl, id, GL_TEXTURE_2D)
-{
- mSurface = NULL;
-}
-
-Texture2D::~Texture2D()
-{
- if (mSurface)
- {
- mSurface->setBoundTexture(NULL);
- mSurface = NULL;
- }
-}
-
-GLsizei Texture2D::getWidth(GLint level) const
-{
- if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level, 0)->getWidth();
- else
- return 0;
-}
-
-GLsizei Texture2D::getHeight(GLint level) const
-{
- if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level, 0)->getHeight();
- else
- return 0;
-}
-
-GLenum Texture2D::getInternalFormat(GLint level) const
-{
- if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level, 0)->getInternalFormat();
- else
- return GL_NONE;
-}
-
-GLenum Texture2D::getActualFormat(GLint level) const
-{
- if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level, 0)->getActualFormat();
- else
- return GL_NONE;
-}
-
-Error Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- releaseTexImage();
-
- return mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
-}
-
-void Texture2D::bindTexImage(egl::Surface *surface)
-{
- releaseTexImage();
-
- mTexture->bindTexImage(surface);
-
- mSurface = surface;
- mSurface->setBoundTexture(this);
-}
-
-void Texture2D::releaseTexImage()
-{
- if (mSurface)
- {
- mSurface->setBoundTexture(NULL);
- mSurface = NULL;
-
- mTexture->releaseTexImage();
- }
-}
-
-Error Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize,
- const PixelUnpackState &unpack, const void *pixels)
-{
- releaseTexImage();
-
- return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, unpack, pixels);
-}
-
-Error Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
-}
-
-Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
-}
-
-Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
- Framebuffer *source)
-{
- releaseTexImage();
-
- return mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
-}
-
-Error Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
-{
- Error error = mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
- if (error.isError())
- {
- return error;
- }
-
- mImmutableLevelCount = levels;
-
- return Error(GL_NO_ERROR);
-}
-
-// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
-bool Texture2D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
-{
- GLsizei width = getBaseLevelWidth();
- GLsizei height = getBaseLevelHeight();
-
- if (width <= 0 || height <= 0)
- {
- return false;
- }
-
- if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
- {
- return false;
- }
-
- bool npotSupport = extensions.textureNPOT;
-
- if (!npotSupport)
- {
- if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(width)) ||
- (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(height)))
- {
- return false;
- }
- }
-
- if (IsMipmapFiltered(samplerState))
- {
- if (!npotSupport)
- {
- if (!gl::isPow2(width) || !gl::isPow2(height))
- {
- return false;
- }
- }
-
- if (!isMipmapComplete())
- {
- 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.
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(0));
- if (formatInfo.depthBits > 0 && clientVersion > 2)
- {
- if (samplerState.compareMode == GL_NONE)
- {
- if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
- samplerState.magFilter != GL_NEAREST)
- {
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool Texture2D::isCompressed(GLint level) const
-{
- return GetInternalFormatInfo(getInternalFormat(level)).compressed;
-}
-
-bool Texture2D::isDepth(GLint level) const
-{
- return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
-}
-
-Error Texture2D::generateMipmaps()
-{
- releaseTexImage();
-
- return mTexture->generateMipmaps();
-}
-
-// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
-bool Texture2D::isMipmapComplete() const
-{
- int levelCount = mipLevels();
-
- for (int level = 0; level < levelCount; level++)
- {
- if (!isLevelComplete(level))
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool Texture2D::isLevelComplete(int level) const
-{
- if (isImmutable())
- {
- return true;
- }
-
- const rx::Image *baseImage = getBaseLevelImage();
-
- GLsizei width = baseImage->getWidth();
- GLsizei height = baseImage->getHeight();
-
- if (width <= 0 || height <= 0)
- {
- return false;
- }
-
- // The base image level is complete if the width and height are positive
- if (level == 0)
- {
- return true;
- }
-
- ASSERT(level >= 1 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
- rx::Image *image = mTexture->getImage(level, 0);
-
- if (image->getInternalFormat() != baseImage->getInternalFormat())
- {
- return false;
- }
-
- if (image->getWidth() != std::max(1, width >> level))
- {
- return false;
- }
-
- if (image->getHeight() != std::max(1, height >> level))
- {
- return false;
- }
-
- return true;
-}
-
-TextureCubeMap::TextureCubeMap(rx::TextureImpl *impl, GLuint id)
- : Texture(impl, id, GL_TEXTURE_CUBE_MAP)
-{
-}
-
-TextureCubeMap::~TextureCubeMap()
-{
-}
-
-GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
-{
- if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level, targetToLayerIndex(target))->getWidth();
- else
- return 0;
-}
-
-GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
-{
- if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level, targetToLayerIndex(target))->getHeight();
- else
- return 0;
-}
-
-GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
-{
- if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level, targetToLayerIndex(target))->getInternalFormat();
- else
- return GL_NONE;
-}
-
-GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
-{
- if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mTexture->getImage(level, targetToLayerIndex(target))->getActualFormat();
- else
- return GL_NONE;
-}
-
-Error TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->setImage(target, level, width, height, 1, internalFormat, format, type, unpack, pixels);
-}
-
-Error TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height,
- GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, unpack, pixels);
-}
-
-Error TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
-}
-
-Error TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height, GLenum format,
- GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
-}
-
-// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
-bool TextureCubeMap::isCubeComplete() const
-{
- int baseWidth = getBaseLevelWidth();
- int baseHeight = getBaseLevelHeight();
- GLenum baseFormat = getBaseLevelInternalFormat();
-
- if (baseWidth <= 0 || baseWidth != baseHeight)
- {
- return false;
- }
-
- for (int faceIndex = 1; faceIndex < 6; faceIndex++)
- {
- const rx::Image *faceBaseImage = mTexture->getImage(0, faceIndex);
-
- if (faceBaseImage->getWidth() != baseWidth ||
- faceBaseImage->getHeight() != baseHeight ||
- faceBaseImage->getInternalFormat() != baseFormat )
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
-{
- return GetInternalFormatInfo(getInternalFormat(target, level)).compressed;
-}
-
-bool TextureCubeMap::isDepth(GLenum target, GLint level) const
-{
- return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
-}
-
-Error TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
- GLsizei width, GLsizei height, Framebuffer *source)
-{
- return mTexture->copyImage(target, level, format, x, y, width, height, source);
-}
-
-Error TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
-{
- Error error = mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
- if (error.isError())
- {
- return error;
- }
-
- mImmutableLevelCount = levels;
-
- return Error(GL_NO_ERROR);
-}
-
-// Tests for texture sampling completeness
-bool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
-{
- int size = getBaseLevelWidth();
-
- bool mipmapping = IsMipmapFiltered(samplerState);
-
- if (!textureCaps.get(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)).filterable && !IsPointSampled(samplerState))
- {
- return false;
- }
-
- if (!gl::isPow2(size) && !extensions.textureNPOT)
- {
- if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
- {
- return false;
- }
- }
-
- if (!mipmapping)
- {
- if (!isCubeComplete())
- {
- return false;
- }
- }
- else
- {
- if (!isMipmapComplete()) // Also tests for isCubeComplete()
- {
- return false;
- }
- }
-
- return true;
-}
-
-int TextureCubeMap::targetToLayerIndex(GLenum target)
-{
- META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
- META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
- META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
- META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
- META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
-
- return target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
-}
-
-GLenum TextureCubeMap::layerIndexToTarget(GLint layer)
-{
- META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
- META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
- META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
- META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
- META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
-
- return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
-}
-
-bool TextureCubeMap::isMipmapComplete() const
-{
- if (isImmutable())
- {
- return true;
- }
-
- if (!isCubeComplete())
- {
- return false;
- }
-
- int levelCount = mipLevels();
-
- for (int face = 0; face < 6; face++)
- {
- for (int level = 1; level < levelCount; level++)
- {
- if (!isFaceLevelComplete(face, level))
- {
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
-{
- ASSERT(level >= 0 && faceIndex < 6 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, faceIndex) != NULL);
-
- if (isImmutable())
- {
- return true;
- }
-
- int baseSize = getBaseLevelWidth();
-
- if (baseSize <= 0)
- {
- return false;
- }
-
- // "isCubeComplete" checks for base level completeness and we must call that
- // to determine if any face at level 0 is complete. We omit that check here
- // to avoid re-checking cube-completeness for every face at level 0.
- if (level == 0)
- {
- return true;
- }
-
- // Check that non-zero levels are consistent with the base level.
- const rx::Image *faceLevelImage = mTexture->getImage(level, faceIndex);
-
- if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
- {
- return false;
- }
-
- if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
- {
- return false;
- }
-
- return true;
-}
-
-
-Texture3D::Texture3D(rx::TextureImpl *impl, GLuint id)
- : Texture(impl, id, GL_TEXTURE_3D)
-{
-}
-
-Texture3D::~Texture3D()
-{
-}
-
-GLsizei Texture3D::getWidth(GLint level) const
-{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getWidth() : 0;
-}
-
-GLsizei Texture3D::getHeight(GLint level) const
-{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getHeight() : 0;
-}
-
-GLsizei Texture3D::getDepth(GLint level) const
-{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getDepth() : 0;
-}
-
-GLenum Texture3D::getInternalFormat(GLint level) const
-{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
-}
-
-GLenum Texture3D::getActualFormat(GLint level) const
-{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
-}
-
-bool Texture3D::isCompressed(GLint level) const
-{
- return GetInternalFormatInfo(getInternalFormat(level)).compressed;
-}
-
-bool Texture3D::isDepth(GLint level) const
-{
- return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
-}
-
-Error Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels);
-}
-
-Error Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, unpack, pixels);
-}
-
-Error Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
-}
-
-Error Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
-}
-
-Error Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
-{
- Error error = mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
- if (error.isError())
- {
- return error;
- }
-
- mImmutableLevelCount = levels;
-
- return Error(GL_NO_ERROR);
-}
-
-bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
-{
- GLsizei width = getBaseLevelWidth();
- GLsizei height = getBaseLevelHeight();
- GLsizei depth = getBaseLevelDepth();
-
- if (width <= 0 || height <= 0 || depth <= 0)
- {
- return false;
- }
-
- if (!textureCaps.get(getInternalFormat(0)).filterable && !IsPointSampled(samplerState))
- {
- return false;
- }
-
- if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
- {
- return false;
- }
-
- return true;
-}
-
-bool Texture3D::isMipmapComplete() const
-{
- int levelCount = mipLevels();
-
- for (int level = 0; level < levelCount; level++)
- {
- if (!isLevelComplete(level))
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool Texture3D::isLevelComplete(int level) const
-{
- ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getImage(level, 0) != NULL);
-
- if (isImmutable())
- {
- return true;
- }
-
- GLsizei width = getBaseLevelWidth();
- GLsizei height = getBaseLevelHeight();
- GLsizei depth = getBaseLevelDepth();
-
- if (width <= 0 || height <= 0 || depth <= 0)
- {
- return false;
- }
-
- if (level == 0)
- {
- return true;
- }
-
- rx::Image *levelImage = mTexture->getImage(level, 0);
-
- 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;
-}
-
-Texture2DArray::Texture2DArray(rx::TextureImpl *impl, GLuint id)
- : Texture(impl, id, GL_TEXTURE_2D_ARRAY)
-{
-}
-
-Texture2DArray::~Texture2DArray()
-{
-}
-
-GLsizei Texture2DArray::getWidth(GLint level) const
-{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getWidth() : 0;
-}
-
-GLsizei Texture2DArray::getHeight(GLint level) const
-{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getHeight() : 0;
-}
-
-GLsizei Texture2DArray::getLayers(GLint level) const
-{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mTexture->getLayerCount(level) : 0;
-}
-
-GLenum Texture2DArray::getInternalFormat(GLint level) const
-{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getInternalFormat() : GL_NONE;
-}
-
-GLenum Texture2DArray::getActualFormat(GLint level) const
-{
- return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mTexture->getLayerCount(level) > 0) ? mTexture->getImage(level, 0)->getActualFormat() : GL_NONE;
-}
-
-bool Texture2DArray::isCompressed(GLint level) const
-{
- return GetInternalFormatInfo(getInternalFormat(level)).compressed;
-}
-
-bool Texture2DArray::isDepth(GLint level) const
-{
- return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
-}
-
-Error Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels);
-}
-
-Error Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
- GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, unpack, pixels);
-}
-
-Error Texture2DArray::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
-}
-
-Error Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
-{
- return mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
-}
-
-Error Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
-{
- Error error = mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
- if (error.isError())
- {
- return error;
- }
-
- mImmutableLevelCount = levels;
-
- return Error(GL_NO_ERROR);
-}
-
-bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
-{
- GLsizei width = getBaseLevelWidth();
- GLsizei height = getBaseLevelHeight();
- GLsizei depth = getLayers(0);
-
- if (width <= 0 || height <= 0 || depth <= 0)
- {
- return false;
- }
-
- if (!textureCaps.get(getBaseLevelInternalFormat()).filterable && !IsPointSampled(samplerState))
- {
- return false;
- }
-
- if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
- {
- return false;
- }
-
- return true;
-}
-
-bool Texture2DArray::isMipmapComplete() const
-{
- int levelCount = mipLevels();
-
- for (int level = 1; level < levelCount; level++)
- {
- if (!isLevelComplete(level))
- {
- return false;
- }
- }
-
- return true;
-}
-
-bool Texture2DArray::isLevelComplete(int level) const
-{
- ASSERT(level >= 0 && level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
-
- if (isImmutable())
- {
- return true;
- }
-
- GLsizei width = getBaseLevelWidth();
- GLsizei height = getBaseLevelHeight();
- GLsizei layers = getLayers(0);
-
- if (width <= 0 || height <= 0 || layers <= 0)
- {
- return false;
- }
-
- if (level == 0)
- {
- return true;
- }
-
- if (getInternalFormat(level) != getInternalFormat(0))
- {
- return false;
- }
-
- if (getWidth(level) != std::max(1, width >> level))
- {
- return false;
- }
-
- if (getHeight(level) != std::max(1, height >> level))
- {
- return false;
- }
-
- if (getLayers(level) != layers)
- {
- return false;
- }
-
- return true;
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.h b/src/3rdparty/angle/src/libGLESv2/Texture.h
deleted file mode 100644
index 66d4df8015..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/Texture.h
+++ /dev/null
@@ -1,241 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// Texture.h: Defines the abstract gl::Texture class and its concrete derived
-// classes Texture2D and TextureCubeMap. Implements GL texture objects and
-// related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
-
-#ifndef LIBGLESV2_TEXTURE_H_
-#define LIBGLESV2_TEXTURE_H_
-
-#include "common/debug.h"
-#include "common/RefCountObject.h"
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/Constants.h"
-#include "libGLESv2/renderer/TextureImpl.h"
-#include "libGLESv2/Caps.h"
-
-#include "angle_gl.h"
-
-#include <vector>
-
-namespace egl
-{
-class Surface;
-}
-
-namespace rx
-{
-class TextureStorageInterface;
-class Image;
-}
-
-namespace gl
-{
-class Framebuffer;
-class FramebufferAttachment;
-struct ImageIndex;
-
-bool IsMipmapFiltered(const gl::SamplerState &samplerState);
-
-class Texture : public RefCountObject
-{
- public:
- Texture(rx::TextureImpl *impl, GLuint id, GLenum target);
-
- virtual ~Texture();
-
- GLenum getTarget() const;
-
- const SamplerState &getSamplerState() const { return mSamplerState; }
- SamplerState &getSamplerState() { return mSamplerState; }
-
- void setUsage(GLenum usage);
- GLenum getUsage() const;
-
- GLint getBaseLevelWidth() const;
- GLint getBaseLevelHeight() const;
- GLint getBaseLevelDepth() const;
- GLenum getBaseLevelInternalFormat() const;
-
- GLsizei getWidth(const ImageIndex &index) const;
- GLsizei getHeight(const ImageIndex &index) const;
- GLenum getInternalFormat(const ImageIndex &index) const;
- GLenum getActualFormat(const ImageIndex &index) const;
-
- virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const = 0;
-
- virtual Error generateMipmaps();
-
- virtual Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
-
- // Texture serials provide a unique way of identifying a Texture that isn't a raw pointer.
- // "id" is not good enough, as Textures can be deleted, then re-allocated with the same id.
- unsigned int getTextureSerial() const;
-
- bool isImmutable() const;
- GLsizei immutableLevelCount();
-
- rx::TextureImpl *getImplementation() { return mTexture; }
- const rx::TextureImpl *getImplementation() const { return mTexture; }
-
- static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
-
- protected:
- int mipLevels() const;
- const rx::Image *getBaseLevelImage() const;
- static unsigned int issueTextureSerial();
-
- rx::TextureImpl *mTexture;
-
- SamplerState mSamplerState;
- GLenum mUsage;
-
- GLsizei mImmutableLevelCount;
-
- GLenum mTarget;
-
- const unsigned int mTextureSerial;
- static unsigned int mCurrentTextureSerial;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Texture);
-};
-
-class Texture2D : public Texture
-{
- public:
- Texture2D(rx::TextureImpl *impl, GLuint id);
-
- virtual ~Texture2D();
-
- GLsizei getWidth(GLint level) const;
- GLsizei getHeight(GLint level) const;
- GLenum getInternalFormat(GLint level) const;
- GLenum getActualFormat(GLint level) const;
- bool isCompressed(GLint level) const;
- bool isDepth(GLint level) const;
-
- Error setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
- Error subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
- Error copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
- Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
-
- virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
- virtual void bindTexImage(egl::Surface *surface);
- virtual void releaseTexImage();
-
- virtual Error generateMipmaps();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Texture2D);
-
- bool isMipmapComplete() const;
- bool isLevelComplete(int level) const;
-
- egl::Surface *mSurface;
-};
-
-class TextureCubeMap : public Texture
-{
- public:
- TextureCubeMap(rx::TextureImpl *impl, GLuint id);
-
- virtual ~TextureCubeMap();
-
- GLsizei getWidth(GLenum target, GLint level) const;
- GLsizei getHeight(GLenum target, GLint level) const;
- GLenum getInternalFormat(GLenum target, GLint level) const;
- GLenum getActualFormat(GLenum target, GLint level) const;
- bool isCompressed(GLenum target, GLint level) const;
- bool isDepth(GLenum target, GLint level) const;
-
- Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
- Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
- Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
- Error storage(GLsizei levels, GLenum internalformat, GLsizei size);
-
- virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
-
- bool isCubeComplete() const;
-
- static int targetToLayerIndex(GLenum target);
- static GLenum layerIndexToTarget(GLint layer);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
-
- bool isMipmapComplete() const;
- bool isFaceLevelComplete(int faceIndex, int level) const;
-};
-
-class Texture3D : public Texture
-{
- public:
- Texture3D(rx::TextureImpl *impl, GLuint id);
-
- virtual ~Texture3D();
-
- GLsizei getWidth(GLint level) const;
- GLsizei getHeight(GLint level) const;
- GLsizei getDepth(GLint level) const;
- GLenum getInternalFormat(GLint level) const;
- GLenum getActualFormat(GLint level) const;
- bool isCompressed(GLint level) const;
- bool isDepth(GLint level) const;
-
- Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
- Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
- Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
-
- virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Texture3D);
-
- bool isMipmapComplete() const;
- bool isLevelComplete(int level) const;
-};
-
-class Texture2DArray : public Texture
-{
- public:
- Texture2DArray(rx::TextureImpl *impl, GLuint id);
-
- virtual ~Texture2DArray();
-
- GLsizei getWidth(GLint level) const;
- GLsizei getHeight(GLint level) const;
- GLsizei getLayers(GLint level) const;
- GLenum getInternalFormat(GLint level) const;
- GLenum getActualFormat(GLint level) const;
- bool isCompressed(GLint level) const;
- bool isDepth(GLint level) const;
-
- Error setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
- Error subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- Error subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels);
- Error storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
-
- virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Texture2DArray);
-
- bool isMipmapComplete() const;
- bool isLevelComplete(int level) const;
-};
-
-}
-
-#endif // LIBGLESV2_TEXTURE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp
new file mode 100644
index 0000000000..a6db1585e7
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp
@@ -0,0 +1,1127 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_egl.cpp : Implements the EGL entry points.
+
+#include "libGLESv2/entry_points_egl.h"
+#include "libGLESv2/entry_points_egl_ext.h"
+#include "libGLESv2/entry_points_gles_2_0_ext.h"
+#include "libGLESv2/entry_points_gles_3_0_ext.h"
+#include "libGLESv2/global_state.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/validationEGL.h"
+
+#include "common/debug.h"
+#include "common/version.h"
+
+#include <EGL/eglext.h>
+
+namespace egl
+{
+
+// EGL 1.0
+EGLint EGLAPIENTRY GetError(void)
+{
+ EVENT("()");
+
+ EGLint error = GetGlobalError();
+ SetGlobalError(Error(EGL_SUCCESS));
+ return error;
+}
+
+EGLDisplay EGLAPIENTRY GetDisplay(EGLNativeDisplayType display_id)
+{
+ EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
+
+ return Display::getDisplay(display_id, AttributeMap());
+}
+
+EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)",
+ dpy, major, minor);
+
+ if (dpy == EGL_NO_DISPLAY)
+ {
+ SetGlobalError(Error(EGL_BAD_DISPLAY));
+ return EGL_FALSE;
+ }
+
+ Display *display = static_cast<Display*>(dpy);
+
+ Error error = display->initialize();
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (major) *major = 1;
+ if (minor) *minor = 4;
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY Terminate(EGLDisplay dpy)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy);
+
+ if (dpy == EGL_NO_DISPLAY)
+ {
+ SetGlobalError(Error(EGL_BAD_DISPLAY));
+ return EGL_FALSE;
+ }
+
+ Display *display = static_cast<Display*>(dpy);
+ gl::Context *context = GetGlobalContext();
+
+ if (display->isValidContext(context))
+ {
+ SetGlobalContext(NULL);
+ SetGlobalDisplay(NULL);
+ }
+
+ display->terminate();
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
+
+ Display *display = static_cast<Display*>(dpy);
+ if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS))
+ {
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return NULL;
+ }
+ }
+
+ const char *result;
+ switch (name)
+ {
+ case EGL_CLIENT_APIS:
+ result = "OpenGL_ES";
+ 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:
+ result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")";
+ break;
+ default:
+ SetGlobalError(Error(EGL_BAD_PARAMETER));
+ return NULL;
+ }
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return result;
+}
+
+EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
+ "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
+ dpy, configs, config_size, num_config);
+
+ Display *display = static_cast<Display*>(dpy);
+
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (!num_config)
+ {
+ SetGlobalError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+
+ std::vector<const Config*> filteredConfigs = display->getConfigs(AttributeMap());
+ if (configs)
+ {
+ filteredConfigs.resize(std::min<size_t>(filteredConfigs.size(), config_size));
+ for (size_t i = 0; i < filteredConfigs.size(); i++)
+ {
+ configs[i] = const_cast<Config*>(filteredConfigs[i]);
+ }
+ }
+ *num_config = filteredConfigs.size();
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
+ "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
+ dpy, attrib_list, configs, config_size, num_config);
+
+ Display *display = static_cast<Display*>(dpy);
+
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (!num_config)
+ {
+ SetGlobalError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+
+ std::vector<const Config*> filteredConfigs = display->getConfigs(AttributeMap(attrib_list));
+ if (configs)
+ {
+ filteredConfigs.resize(std::min<size_t>(filteredConfigs.size(), config_size));
+ for (size_t i = 0; i < filteredConfigs.size(); i++)
+ {
+ configs[i] = const_cast<Config*>(filteredConfigs[i]);
+ }
+ }
+ *num_config = filteredConfigs.size();
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
+ dpy, config, attribute, value);
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+
+ Error error = ValidateConfig(display, configuration);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (!display->getConfigAttrib(configuration, attribute, value))
+ {
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
+ "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list);
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+ AttributeMap attributes(attrib_list);
+
+ Error error = ValidateCreateWindowSurface(display, configuration, win, attributes);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ egl::Surface *surface = nullptr;
+ error = display->createWindowSurface(configuration, win, attributes, &surface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
+ dpy, config, attrib_list);
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+ AttributeMap attributes(attrib_list);
+
+ Error error = ValidateCreatePbufferSurface(display, configuration, attributes);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ egl::Surface *surface = nullptr;
+ error = display->createPbufferSurface(configuration, attributes, &surface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
+ "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+
+ Error error = ValidateConfig(display, configuration);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ UNIMPLEMENTED(); // FIXME
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_NO_SURFACE;
+}
+
+EGLBoolean EGLAPIENTRY DestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE)
+ {
+ SetGlobalError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ display->destroySurface((Surface*)surface);
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
+ dpy, surface, attribute, value);
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = (Surface*)surface;
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE)
+ {
+ SetGlobalError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ switch (attribute)
+ {
+ case EGL_VG_ALPHA_FORMAT:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_VG_COLORSPACE:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_CONFIG_ID:
+ *value = eglSurface->getConfig()->configID;
+ break;
+ case EGL_HEIGHT:
+ *value = eglSurface->getHeight();
+ break;
+ case EGL_HORIZONTAL_RESOLUTION:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_LARGEST_PBUFFER:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_MIPMAP_TEXTURE:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_MIPMAP_LEVEL:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_MULTISAMPLE_RESOLVE:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_PIXEL_ASPECT_RATIO:
+ *value = eglSurface->getPixelAspectRatio();
+ break;
+ case EGL_RENDER_BUFFER:
+ *value = eglSurface->getRenderBuffer();
+ break;
+ case EGL_SWAP_BEHAVIOR:
+ *value = eglSurface->getSwapBehavior();
+ break;
+ case EGL_TEXTURE_FORMAT:
+ *value = eglSurface->getTextureFormat();
+ break;
+ case EGL_TEXTURE_TARGET:
+ *value = eglSurface->getTextureTarget();
+ break;
+ case EGL_VERTICAL_RESOLUTION:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_WIDTH:
+ *value = eglSurface->getWidth();
+ break;
+ case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
+ if (!display->getExtensions().postSubBuffer)
+ {
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+ *value = eglSurface->isPostSubBufferSupported();
+ break;
+ case EGL_FIXED_SIZE_ANGLE:
+ if (!display->getExtensions().windowFixedSize)
+ {
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+ *value = eglSurface->isFixedSize();
+ break;
+ default:
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
+ "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+ gl::Context* sharedGLContext = static_cast<gl::Context*>(share_context);
+ AttributeMap attributes(attrib_list);
+
+ Error error = ValidateCreateContext(display, configuration, sharedGLContext, attributes);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_NO_CONTEXT;
+ }
+
+ gl::Context *context = nullptr;
+ error = display->createContext(configuration, sharedGLContext, attributes, &context);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_NO_CONTEXT;
+ }
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return static_cast<EGLContext>(context);
+}
+
+EGLBoolean EGLAPIENTRY DestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
+
+ Display *display = static_cast<Display*>(dpy);
+ gl::Context *context = static_cast<gl::Context*>(ctx);
+
+ Error error = ValidateContext(display, context);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (ctx == EGL_NO_CONTEXT)
+ {
+ SetGlobalError(Error(EGL_BAD_CONTEXT));
+ return EGL_FALSE;
+ }
+
+ if (context == GetGlobalContext())
+ {
+ SetGlobalDisplay(NULL);
+ SetGlobalContext(NULL);
+ }
+
+ display->destroyContext(context);
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
+ dpy, draw, read, ctx);
+
+ Display *display = static_cast<Display*>(dpy);
+ gl::Context *context = static_cast<gl::Context*>(ctx);
+
+ bool noContext = (ctx == EGL_NO_CONTEXT);
+ bool noSurface = (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE);
+ if (noContext != noSurface)
+ {
+ SetGlobalError(Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
+ }
+
+ if (ctx != EGL_NO_CONTEXT)
+ {
+ Error error = ValidateContext(display, context);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+ }
+
+ if (dpy != EGL_NO_DISPLAY && display->isInitialized())
+ {
+ if (display->testDeviceLost())
+ {
+ display->notifyDeviceLost();
+ return EGL_FALSE;
+ }
+
+ if (display->isDeviceLost())
+ {
+ SetGlobalError(Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
+ }
+ }
+
+ Surface *drawSurface = static_cast<Surface*>(draw);
+ if (draw != EGL_NO_SURFACE)
+ {
+ Error error = ValidateSurface(display, drawSurface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+ }
+
+ Surface *readSurface = static_cast<Surface*>(read);
+ if (read != EGL_NO_SURFACE)
+ {
+ Error error = ValidateSurface(display, readSurface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+ }
+
+ if (draw != read)
+ {
+ UNIMPLEMENTED(); // FIXME
+ }
+
+ SetGlobalDisplay(display);
+ SetGlobalDrawSurface(drawSurface);
+ SetGlobalReadSurface(readSurface);
+ SetGlobalContext(context);
+
+ if (context != nullptr && display != nullptr && drawSurface != nullptr)
+ {
+ display->makeCurrent(drawSurface, readSurface, context);
+ }
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw)
+{
+ EVENT("(EGLint readdraw = %d)", readdraw);
+
+ if (readdraw == EGL_READ)
+ {
+ SetGlobalError(Error(EGL_SUCCESS));
+ return GetGlobalReadSurface();
+ }
+ else if (readdraw == EGL_DRAW)
+ {
+ SetGlobalError(Error(EGL_SUCCESS));
+ return GetGlobalDrawSurface();
+ }
+ else
+ {
+ SetGlobalError(Error(EGL_BAD_PARAMETER));
+ return EGL_NO_SURFACE;
+ }
+}
+
+EGLDisplay EGLAPIENTRY GetCurrentDisplay(void)
+{
+ EVENT("()");
+
+ EGLDisplay dpy = GetGlobalDisplay();
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return dpy;
+}
+
+EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
+ dpy, ctx, attribute, value);
+
+ Display *display = static_cast<Display*>(dpy);
+ gl::Context *context = static_cast<gl::Context*>(ctx);
+
+ Error error = ValidateContext(display, context);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ switch (attribute)
+ {
+ case EGL_CONFIG_ID:
+ *value = context->getConfigID();
+ break;
+ case EGL_CONTEXT_CLIENT_TYPE:
+ *value = context->getClientType();
+ break;
+ case EGL_CONTEXT_CLIENT_VERSION:
+ *value = context->getClientVersion();
+ break;
+ case EGL_RENDER_BUFFER:
+ *value = context->getRenderBuffer();
+ break;
+ default:
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY WaitGL(void)
+{
+ EVENT("()");
+
+ UNIMPLEMENTED(); // FIXME
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return 0;
+}
+
+EGLBoolean EGLAPIENTRY WaitNative(EGLint engine)
+{
+ EVENT("(EGLint engine = %d)", engine);
+
+ UNIMPLEMENTED(); // FIXME
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return 0;
+}
+
+EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = (Surface*)surface;
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (display->isDeviceLost())
+ {
+ SetGlobalError(Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE)
+ {
+ SetGlobalError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ error = eglSurface->swap();
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (display->isDeviceLost())
+ {
+ SetGlobalError(Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
+ }
+
+ UNIMPLEMENTED(); // FIXME
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return 0;
+}
+
+// EGL 1.1
+EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (buffer != EGL_BACK_BUFFER)
+ {
+ SetGlobalError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT)
+ {
+ SetGlobalError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ if (eglSurface->getBoundTexture())
+ {
+ SetGlobalError(Error(EGL_BAD_ACCESS));
+ return EGL_FALSE;
+ }
+
+ if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+ {
+ SetGlobalError(Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
+ }
+
+ gl::Context *context = GetGlobalContext();
+ if (context)
+ {
+ gl::Texture *textureObject = context->getTargetTexture(GL_TEXTURE_2D);
+ ASSERT(textureObject != NULL);
+
+ if (textureObject->isImmutable())
+ {
+ SetGlobalError(Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
+ }
+
+ eglSurface->bindTexImage(textureObject, buffer);
+ }
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
+ dpy, surface, attribute, value);
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ UNIMPLEMENTED(); // FIXME
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (buffer != EGL_BACK_BUFFER)
+ {
+ SetGlobalError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT)
+ {
+ SetGlobalError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+ {
+ SetGlobalError(Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
+ }
+
+ gl::Texture *texture = eglSurface->getBoundTexture();
+
+ if (texture)
+ {
+ eglSurface->releaseTexImage(buffer);
+ }
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
+
+ Display *display = static_cast<Display*>(dpy);
+
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ Surface *draw_surface = static_cast<Surface*>(GetGlobalDrawSurface());
+
+ if (draw_surface == NULL)
+ {
+ SetGlobalError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ const egl::Config *surfaceConfig = draw_surface->getConfig();
+ EGLint clampedInterval = std::min(std::max(interval, surfaceConfig->minSwapInterval), surfaceConfig->maxSwapInterval);
+
+ draw_surface->setSwapInterval(clampedInterval);
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+
+// EGL 1.2
+EGLBoolean EGLAPIENTRY BindAPI(EGLenum api)
+{
+ EVENT("(EGLenum api = 0x%X)", api);
+
+ switch (api)
+ {
+ case EGL_OPENGL_API:
+ case EGL_OPENVG_API:
+ SetGlobalError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE; // Not supported by this implementation
+ case EGL_OPENGL_ES_API:
+ break;
+ default:
+ SetGlobalError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+
+ SetGlobalAPI(api);
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLenum EGLAPIENTRY QueryAPI(void)
+{
+ EVENT("()");
+
+ EGLenum API = GetGlobalAPI();
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return API;
+}
+
+EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
+ "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
+ dpy, buftype, buffer, config, attrib_list);
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+ AttributeMap attributes(attrib_list);
+
+ Error error = ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ egl::Surface *surface = nullptr;
+ error = display->createPbufferFromClientBuffer(configuration, buffer, attributes, &surface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLBoolean EGLAPIENTRY ReleaseThread(void)
+{
+ EVENT("()");
+
+ MakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY WaitClient(void)
+{
+ EVENT("()");
+
+ UNIMPLEMENTED(); // FIXME
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return 0;
+}
+
+// EGL 1.4
+EGLContext EGLAPIENTRY GetCurrentContext(void)
+{
+ EVENT("()");
+
+ gl::Context *context = GetGlobalContext();
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return static_cast<EGLContext>(context);
+}
+
+// EGL 1.5
+EGLSync EGLAPIENTRY CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum type = 0x%X, const EGLint* attrib_list = 0x%0.8p)", dpy, type, attrib_list);
+
+ UNIMPLEMENTED();
+ return EGL_NO_SYNC;
+}
+
+EGLBoolean EGLAPIENTRY DestroySync(EGLDisplay dpy, EGLSync sync)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p)", dpy, sync);
+
+ UNIMPLEMENTED();
+ return EGL_FALSE;
+}
+
+EGLint EGLAPIENTRY ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X, EGLTime timeout = %d)", dpy, sync, flags, timeout);
+
+ UNIMPLEMENTED();
+ return 0;
+}
+
+EGLBoolean EGLAPIENTRY GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint attribute = 0x%X, EGLAttrib *value = 0x%0.8p)", dpy, sync, attribute, value);
+
+ UNIMPLEMENTED();
+ return EGL_FALSE;
+}
+
+EGLImage EGLAPIENTRY CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, "
+ "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)",
+ dpy, ctx, target, buffer, attrib_list);
+
+ UNIMPLEMENTED();
+ return EGL_NO_IMAGE;
+}
+
+EGLBoolean EGLAPIENTRY DestroyImage(EGLDisplay dpy, EGLImage image)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image);
+
+ UNIMPLEMENTED();
+ return EGL_FALSE;
+}
+
+EGLDisplay EGLAPIENTRY GetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list)
+{
+ EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
+ platform, native_display, attrib_list);
+
+ UNIMPLEMENTED();
+ return EGL_NO_DISPLAY;
+}
+
+EGLSurface EGLAPIENTRY CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_window = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
+ dpy, config, native_window, attrib_list);
+
+ UNIMPLEMENTED();
+ return EGL_NO_SURFACE;
+}
+
+EGLSurface EGLAPIENTRY CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_pixmap = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
+ dpy, config, native_pixmap, attrib_list);
+
+ UNIMPLEMENTED();
+ return EGL_NO_SURFACE;
+}
+
+EGLBoolean EGLAPIENTRY WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X)", dpy, sync, flags);
+
+ UNIMPLEMENTED();
+ return EGL_FALSE;
+}
+
+__eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *procname)
+{
+ EVENT("(const char *procname = \"%s\")", procname);
+
+ struct Extension
+ {
+ const char *name;
+ __eglMustCastToProperFunctionPointerType address;
+ };
+
+ static const Extension extensions[] =
+ {
+ { "eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)QuerySurfacePointerANGLE },
+ { "eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)PostSubBufferNV },
+ { "eglGetPlatformDisplayEXT", (__eglMustCastToProperFunctionPointerType)GetPlatformDisplayEXT },
+ { "glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)gl::BlitFramebufferANGLE },
+ { "glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)gl::RenderbufferStorageMultisampleANGLE },
+ { "glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)gl::DeleteFencesNV },
+ { "glGenFencesNV", (__eglMustCastToProperFunctionPointerType)gl::GenFencesNV },
+ { "glIsFenceNV", (__eglMustCastToProperFunctionPointerType)gl::IsFenceNV },
+ { "glTestFenceNV", (__eglMustCastToProperFunctionPointerType)gl::TestFenceNV },
+ { "glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)gl::GetFenceivNV },
+ { "glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)gl::FinishFenceNV },
+ { "glSetFenceNV", (__eglMustCastToProperFunctionPointerType)gl::SetFenceNV },
+ { "glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)gl::GetTranslatedShaderSourceANGLE },
+ { "glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)gl::TexStorage2DEXT },
+ { "glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)gl::GetGraphicsResetStatusEXT },
+ { "glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)gl::ReadnPixelsEXT },
+ { "glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)gl::GetnUniformfvEXT },
+ { "glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)gl::GetnUniformivEXT },
+ { "glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)gl::GenQueriesEXT },
+ { "glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)gl::DeleteQueriesEXT },
+ { "glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)gl::IsQueryEXT },
+ { "glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)gl::BeginQueryEXT },
+ { "glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)gl::EndQueryEXT },
+ { "glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)gl::GetQueryivEXT },
+ { "glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)gl::GetQueryObjectuivEXT },
+ { "glDrawBuffersEXT", (__eglMustCastToProperFunctionPointerType)gl::DrawBuffersEXT },
+ { "glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)gl::VertexAttribDivisorANGLE },
+ { "glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)gl::DrawArraysInstancedANGLE },
+ { "glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)gl::DrawElementsInstancedANGLE },
+ { "glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)gl::GetProgramBinaryOES },
+ { "glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)gl::ProgramBinaryOES },
+ { "glGetBufferPointervOES", (__eglMustCastToProperFunctionPointerType)gl::GetBufferPointervOES },
+ { "glMapBufferOES", (__eglMustCastToProperFunctionPointerType)gl::MapBufferOES },
+ { "glUnmapBufferOES", (__eglMustCastToProperFunctionPointerType)gl::UnmapBufferOES },
+ { "glMapBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)gl::MapBufferRangeEXT },
+ { "glFlushMappedBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)gl::FlushMappedBufferRangeEXT },
+ { "", NULL },
+ };
+
+ for (const Extension *extension = &extensions[0]; extension->address != nullptr; extension++)
+ {
+ if (strcmp(procname, extension->name) == 0)
+ {
+ return reinterpret_cast<__eglMustCastToProperFunctionPointerType>(extension->address);
+ }
+ }
+
+ return NULL;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl.h b/src/3rdparty/angle/src/libGLESv2/entry_points_egl.h
new file mode 100644
index 0000000000..259a209684
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl.h
@@ -0,0 +1,74 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_egl.h : Defines the EGL entry points.
+
+#ifndef LIBGLESV2_ENTRYPOINTSEGL_H_
+#define LIBGLESV2_ENTRYPOINTSEGL_H_
+
+#include <EGL/egl.h>
+#include <export.h>
+
+namespace egl
+{
+
+// EGL 1.0
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+ANGLE_EXPORT EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyContext(EGLDisplay dpy, EGLContext ctx);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroySurface(EGLDisplay dpy, EGLSurface surface);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+ANGLE_EXPORT EGLDisplay EGLAPIENTRY GetCurrentDisplay(void);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw);
+ANGLE_EXPORT EGLDisplay EGLAPIENTRY GetDisplay(EGLNativeDisplayType display_id);
+ANGLE_EXPORT EGLint EGLAPIENTRY GetError(void);
+ANGLE_EXPORT __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *procname);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+ANGLE_EXPORT const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY Terminate(EGLDisplay dpy);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY WaitGL(void);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY WaitNative(EGLint engine);
+
+// EGL 1.1
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval);
+
+// EGL 1.2
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY BindAPI(EGLenum api);
+ANGLE_EXPORT EGLenum EGLAPIENTRY QueryAPI(void);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseThread(void);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY WaitClient(void);
+
+// EGL 1.4
+ANGLE_EXPORT EGLContext EGLAPIENTRY GetCurrentContext(void);
+
+// EGL 1.5
+ANGLE_EXPORT EGLSync EGLAPIENTRY CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroySync(EGLDisplay dpy, EGLSync sync);
+ANGLE_EXPORT EGLint EGLAPIENTRY ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
+ANGLE_EXPORT EGLImage EGLAPIENTRY CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyImage(EGLDisplay dpy, EGLImage image);
+ANGLE_EXPORT EGLDisplay EGLAPIENTRY GetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags);
+
+}
+
+#endif // LIBGLESV2_ENTRYPOINTSEGL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp
new file mode 100644
index 0000000000..ded73dbb48
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp
@@ -0,0 +1,271 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_ext.cpp : Implements the EGL extension entry points.
+
+#include "libGLESv2/entry_points_egl_ext.h"
+#include "libGLESv2/global_state.h"
+
+#include "libANGLE/Display.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/validationEGL.h"
+
+#include "common/debug.h"
+
+namespace egl
+{
+
+// EGL_ANGLE_query_surface_pointer
+EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)",
+ dpy, surface, attribute, value);
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (!display->getExtensions().querySurfacePointer)
+ {
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE)
+ {
+ SetGlobalError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ // validate the attribute parameter
+ switch (attribute)
+ {
+ case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
+ if (!display->getExtensions().surfaceD3DTexture2DShareHandle)
+ {
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+ break;
+
+ default:
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+
+ error = eglSurface->querySurfacePointerANGLE(attribute, value);
+ SetGlobalError(error);
+ return (error.isError() ? EGL_FALSE : EGL_TRUE);
+}
+
+
+// EGL_NV_post_sub_buffer
+EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height);
+
+ if (x < 0 || y < 0 || width < 0 || height < 0)
+ {
+ SetGlobalError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ if (display->isDeviceLost())
+ {
+ SetGlobalError(Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE)
+ {
+ SetGlobalError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ if (!display->getExtensions().postSubBuffer)
+ {
+ // Spec is not clear about how this should be handled.
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+ }
+
+ error = eglSurface->postSubBuffer(x, y, width, height);
+ if (error.isError())
+ {
+ SetGlobalError(error);
+ return EGL_FALSE;
+ }
+
+ SetGlobalError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+// EGL_EXT_platform_base
+EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
+{
+ EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
+ platform, native_display, attrib_list);
+
+ const ClientExtensions &clientExtensions = Display::getClientExtensions();
+
+ switch (platform)
+ {
+ case EGL_PLATFORM_ANGLE_ANGLE:
+ if (!clientExtensions.platformANGLE)
+ {
+ SetGlobalError(Error(EGL_BAD_PARAMETER));
+ return EGL_NO_DISPLAY;
+ }
+ break;
+
+ default:
+ SetGlobalError(Error(EGL_BAD_CONFIG));
+ return EGL_NO_DISPLAY;
+ }
+
+ EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
+ EGLint deviceType = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE;
+ bool majorVersionSpecified = false;
+ bool minorVersionSpecified = false;
+ bool enableAutoTrimSpecified = false;
+
+ if (attrib_list)
+ {
+ for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2)
+ {
+ switch (curAttrib[0])
+ {
+ case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
+ switch (curAttrib[1])
+ {
+ 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)
+ {
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_DISPLAY;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
+ case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
+ if (!clientExtensions.platformANGLEOpenGL)
+ {
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_DISPLAY;
+ }
+ break;
+
+ default:
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_DISPLAY;
+ }
+ platformType = curAttrib[1];
+ break;
+
+ case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE:
+ if (curAttrib[1] != EGL_DONT_CARE)
+ {
+ majorVersionSpecified = true;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE:
+ if (curAttrib[1] != EGL_DONT_CARE)
+ {
+ minorVersionSpecified = true;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE:
+ switch (curAttrib[1])
+ {
+ case EGL_TRUE:
+ case EGL_FALSE:
+ break;
+ default:
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_DISPLAY;
+ }
+ enableAutoTrimSpecified = true;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE:
+ if (!clientExtensions.platformANGLED3D)
+ {
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_DISPLAY;
+ }
+
+ switch (curAttrib[1])
+ {
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE:
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE:
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
+ break;
+
+ default:
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_DISPLAY;
+ }
+ deviceType = curAttrib[1];
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (!majorVersionSpecified && minorVersionSpecified)
+ {
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_DISPLAY;
+ }
+
+ if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE &&
+ platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE, "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a device type of "
+ "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."));
+ return EGL_NO_DISPLAY;
+ }
+
+ if (enableAutoTrimSpecified &&
+ platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ SetGlobalError(Error(EGL_BAD_ATTRIBUTE, "EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE requires a device type of "
+ "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."));
+ return EGL_NO_DISPLAY;
+ }
+
+ SetGlobalError(Error(EGL_SUCCESS));
+
+ EGLNativeDisplayType displayId = static_cast<EGLNativeDisplayType>(native_display);
+ return Display::getDisplay(displayId, AttributeMap(attrib_list));
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.h b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.h
new file mode 100644
index 0000000000..9de1027082
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.h
@@ -0,0 +1,30 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_egl_ext.h : Defines the EGL extension entry points.
+
+#ifndef LIBGLESV2_ENTRYPOINTSEGLEXT_H_
+#define LIBGLESV2_ENTRYPOINTSEGLEXT_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <export.h>
+
+namespace egl
+{
+
+// EGL_ANGLE_query_surface_pointer
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+
+// EGL_NV_post_sub_buffer
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
+
+// EGL_EXT_platform_base
+ANGLE_EXPORT EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list);
+
+}
+
+#endif // LIBGLESV2_ENTRYPOINTSEGLEXT_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.cpp
new file mode 100644
index 0000000000..6d3089ba4f
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.cpp
@@ -0,0 +1,4318 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_gles_2_0.cpp : Implements the GLES 2.0 entry points.
+
+#include "libGLESv2/entry_points_gles_2_0.h"
+#include "libGLESv2/global_state.h"
+
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Compiler.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/FramebufferAttachment.h"
+
+#include "libANGLE/validationES.h"
+#include "libANGLE/validationES2.h"
+#include "libANGLE/validationES3.h"
+#include "libANGLE/queryconversions.h"
+
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "common/version.h"
+
+namespace gl
+{
+
+void GL_APIENTRY ActiveTexture(GLenum texture)
+{
+ EVENT("(GLenum texture = 0x%X)", texture);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ context->getState().setActiveSampler(texture - GL_TEXTURE0);
+ }
+}
+
+void GL_APIENTRY AttachShader(GLuint program, GLuint shader)
+{
+ EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Program *programObject = context->getProgram(program);
+ Shader *shaderObject = context->getShader(shader);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ if (!shaderObject)
+ {
+ if (context->getProgram(shader))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ if (!programObject->attachShader(shaderObject))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY BindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+{
+ EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ if (strncmp(name, "gl_", 3) == 0)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ programObject->bindAttributeLocation(index, name);
+ }
+}
+
+void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer)
+{
+ EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidBufferTarget(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (target)
+ {
+ case GL_ARRAY_BUFFER:
+ context->bindArrayBuffer(buffer);
+ return;
+ case GL_ELEMENT_ARRAY_BUFFER:
+ context->bindElementArrayBuffer(buffer);
+ return;
+ case GL_COPY_READ_BUFFER:
+ context->bindCopyReadBuffer(buffer);
+ return;
+ case GL_COPY_WRITE_BUFFER:
+ context->bindCopyWriteBuffer(buffer);
+ return;
+ case GL_PIXEL_PACK_BUFFER:
+ context->bindPixelPackBuffer(buffer);
+ return;
+ case GL_PIXEL_UNPACK_BUFFER:
+ context->bindPixelUnpackBuffer(buffer);
+ return;
+ case GL_UNIFORM_BUFFER:
+ context->bindGenericUniformBuffer(buffer);
+ return;
+ case GL_TRANSFORM_FEEDBACK_BUFFER:
+ context->bindGenericTransformFeedbackBuffer(buffer);
+ return;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY BindFramebuffer(GLenum target, GLuint framebuffer)
+{
+ EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidFramebufferTarget(target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+ {
+ context->bindReadFramebuffer(framebuffer);
+ }
+
+ if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+ {
+ context->bindDrawFramebuffer(framebuffer);
+ }
+ }
+}
+
+void GL_APIENTRY BindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+ EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (target != GL_RENDERBUFFER)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ context->bindRenderbuffer(renderbuffer);
+ }
+}
+
+void GL_APIENTRY BindTexture(GLenum target, GLuint texture)
+{
+ EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Texture *textureObject = context->getTexture(texture);
+
+ if (textureObject && textureObject->getTarget() != target && texture != 0)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ switch (target)
+ {
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_CUBE_MAP:
+ break;
+
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_2D_ARRAY:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ context->bindTexture(target, texture);
+ }
+}
+
+void GL_APIENTRY BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
+ red, green, blue, alpha);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ context->getState().setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha));
+ }
+}
+
+void GL_APIENTRY BlendEquation(GLenum mode)
+{
+ BlendEquationSeparate(mode, mode);
+}
+
+void GL_APIENTRY BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ switch (modeRGB)
+ {
+ case GL_FUNC_ADD:
+ case GL_FUNC_SUBTRACT:
+ case GL_FUNC_REVERSE_SUBTRACT:
+ case GL_MIN:
+ case GL_MAX:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (modeAlpha)
+ {
+ case GL_FUNC_ADD:
+ case GL_FUNC_SUBTRACT:
+ case GL_FUNC_REVERSE_SUBTRACT:
+ case GL_MIN:
+ case GL_MAX:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ context->getState().setBlendEquation(modeRGB, modeAlpha);
+ }
+}
+
+void GL_APIENTRY BlendFunc(GLenum sfactor, GLenum dfactor)
+{
+ BlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
+}
+
+void GL_APIENTRY BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
+ srcRGB, dstRGB, srcAlpha, dstAlpha);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ switch (srcRGB)
+ {
+ 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:
+ case GL_SRC_ALPHA_SATURATE:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (dstRGB)
+ {
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ break;
+
+ case GL_SRC_ALPHA_SATURATE:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (srcAlpha)
+ {
+ 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:
+ case GL_SRC_ALPHA_SATURATE:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (dstAlpha)
+ {
+ case GL_ZERO:
+ case GL_ONE:
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ case GL_SRC_ALPHA:
+ case GL_ONE_MINUS_SRC_ALPHA:
+ case GL_DST_ALPHA:
+ case GL_ONE_MINUS_DST_ALPHA:
+ case GL_CONSTANT_COLOR:
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ case GL_CONSTANT_ALPHA:
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ break;
+
+ case GL_SRC_ALPHA_SATURATE:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ 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)
+ {
+ ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ context->getState().setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
+ }
+}
+
+void GL_APIENTRY BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+ EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
+ target, size, data, usage);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (size < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ switch (usage)
+ {
+ case GL_STREAM_DRAW:
+ case GL_STATIC_DRAW:
+ case GL_DYNAMIC_DRAW:
+ break;
+
+ case GL_STREAM_READ:
+ case GL_STREAM_COPY:
+ case GL_STATIC_READ:
+ case GL_STATIC_COPY:
+ case GL_DYNAMIC_READ:
+ case GL_DYNAMIC_COPY:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (!ValidBufferTarget(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (!buffer)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ Error error = buffer->bufferData(data, size, usage);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+ EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
+ target, offset, size, data);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (size < 0 || offset < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (data == NULL)
+ {
+ return;
+ }
+
+ if (!ValidBufferTarget(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (!buffer)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (buffer->isMapped())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // Check for possible overflow of size + offset
+ if (!rx::IsUnsignedAdditionSafe<size_t>(size, offset))
+ {
+ context->recordError(Error(GL_OUT_OF_MEMORY));
+ return;
+ }
+
+ if (size + offset > buffer->getSize())
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Error error = buffer->bufferSubData(data, size, offset);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+GLenum GL_APIENTRY CheckFramebufferStatus(GLenum target)
+{
+ EVENT("(GLenum target = 0x%X)", target);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidFramebufferTarget(target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return 0;
+ }
+
+ Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ return framebuffer->checkStatus(context->getData());
+ }
+
+ return 0;
+}
+
+void GL_APIENTRY Clear(GLbitfield mask)
+{
+ EVENT("(GLbitfield mask = 0x%X)", mask);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
+ ASSERT(framebufferObject);
+
+ if (framebufferObject->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
+ {
+ context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
+ return;
+ }
+
+ if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Error error = framebufferObject->clear(context->getData(), mask);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
+ red, green, blue, alpha);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ context->getState().setColorClearValue(red, green, blue, alpha);
+ }
+}
+
+void GL_APIENTRY ClearDepthf(GLclampf depth)
+{
+ EVENT("(GLclampf depth = %f)", depth);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ context->getState().setDepthClearValue(depth);
+ }
+}
+
+void GL_APIENTRY ClearStencil(GLint s)
+{
+ EVENT("(GLint s = %d)", s);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ context->getState().setStencilClearValue(s);
+ }
+}
+
+void GL_APIENTRY ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ EVENT("(GLboolean red = %d, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)",
+ red, green, blue, alpha);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ context->getState().setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
+ }
+}
+
+void GL_APIENTRY CompileShader(GLuint shader)
+{
+ EVENT("(GLuint shader = %d)", shader);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Shader *shaderObject = context->getShader(shader);
+
+ if (!shaderObject)
+ {
+ if (context->getProgram(shader))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ shaderObject->compile(context->getCompiler());
+ }
+}
+
+void GL_APIENTRY CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+ GLint border, GLsizei imageSize, const GLvoid* data)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
+ "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
+ target, level, internalformat, width, height, border, imageSize, data);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3 &&
+ !ValidateES2TexImageParameters(context, target, level, internalformat, true, false,
+ 0, 0, width, height, border, GL_NONE, GL_NONE, data))
+ {
+ return;
+ }
+
+ if (context->getClientVersion() >= 3 &&
+ !ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
+ 0, 0, 0, width, height, 1, border, GL_NONE, GL_NONE, data))
+ {
+ return;
+ }
+
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Extents size(width, height, 1);
+ Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ Error error = texture->setCompressedImage(target, level, internalformat, size, context->getState().getUnpackState(),
+ reinterpret_cast<const uint8_t *>(data));
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+ "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
+ "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
+ target, level, xoffset, yoffset, width, height, format, imageSize, data);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3 &&
+ !ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true,
+ xoffset, yoffset, width, height, 0, GL_NONE, GL_NONE, data))
+ {
+ return;
+ }
+
+ if (context->getClientVersion() >= 3 &&
+ !ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
+ xoffset, yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, data))
+ {
+ return;
+ }
+
+ const InternalFormat &formatInfo = GetInternalFormatInfo(format);
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+
+ Box area(xoffset, yoffset, 0, width, height, 1);
+ Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ Error error = texture->setCompressedSubImage(target, level, area, format, context->getState().getUnpackState(),
+ reinterpret_cast<const uint8_t *>(data));
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
+ "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
+ target, level, internalformat, x, y, width, height, border);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3 &&
+ !ValidateES2CopyTexImageParameters(context, target, level, internalformat, false,
+ 0, 0, x, y, width, height, border))
+ {
+ return;
+ }
+
+ if (context->getClientVersion() >= 3 &&
+ !ValidateES3CopyTexImageParameters(context, target, level, internalformat, false,
+ 0, 0, 0, x, y, width, height, border))
+ {
+ return;
+ }
+
+ Rectangle sourceArea(x, y, width, height);
+
+ const Framebuffer *framebuffer = context->getState().getReadFramebuffer();
+ Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+ "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
+ target, level, xoffset, yoffset, x, y, width, height);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3 &&
+ !ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true,
+ xoffset, yoffset, x, y, width, height, 0))
+ {
+ return;
+ }
+
+ if (context->getClientVersion() >= 3 &&
+ !ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true,
+ xoffset, yoffset, 0, x, y, width, height, 0))
+ {
+ return;
+ }
+
+ Offset destOffset(xoffset, yoffset, 0);
+ Rectangle sourceArea(x, y, width, height);
+
+ const Framebuffer *framebuffer = context->getState().getReadFramebuffer();
+ Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+GLuint GL_APIENTRY CreateProgram(void)
+{
+ EVENT("()");
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ return context->createProgram();
+ }
+
+ return 0;
+}
+
+GLuint GL_APIENTRY CreateShader(GLenum type)
+{
+ EVENT("(GLenum type = 0x%X)", type);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ switch (type)
+ {
+ case GL_FRAGMENT_SHADER:
+ case GL_VERTEX_SHADER:
+ return context->createShader(type);
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+void GL_APIENTRY CullFace(GLenum mode)
+{
+ EVENT("(GLenum mode = 0x%X)", mode);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ switch (mode)
+ {
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ context->getState().setCullMode(mode);
+ }
+}
+
+void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+ EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ context->deleteBuffer(buffers[i]);
+ }
+ }
+}
+
+void GL_APIENTRY DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+ EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ if (framebuffers[i] != 0)
+ {
+ context->deleteFramebuffer(framebuffers[i]);
+ }
+ }
+ }
+}
+
+void GL_APIENTRY DeleteProgram(GLuint program)
+{
+ EVENT("(GLuint program = %d)", program);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (program == 0)
+ {
+ return;
+ }
+
+ if (!context->getProgram(program))
+ {
+ if(context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ context->deleteProgram(program);
+ }
+}
+
+void GL_APIENTRY DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+ EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ context->deleteRenderbuffer(renderbuffers[i]);
+ }
+ }
+}
+
+void GL_APIENTRY DeleteShader(GLuint shader)
+{
+ EVENT("(GLuint shader = %d)", shader);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (shader == 0)
+ {
+ return;
+ }
+
+ if (!context->getShader(shader))
+ {
+ if(context->getProgram(shader))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ context->deleteShader(shader);
+ }
+}
+
+void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint* textures)
+{
+ EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ if (textures[i] != 0)
+ {
+ context->deleteTexture(textures[i]);
+ }
+ }
+ }
+}
+
+void GL_APIENTRY DepthFunc(GLenum func)
+{
+ EVENT("(GLenum func = 0x%X)", func);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ 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:
+ context->getState().setDepthFunc(func);
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY DepthMask(GLboolean flag)
+{
+ EVENT("(GLboolean flag = %u)", flag);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ context->getState().setDepthMask(flag != GL_FALSE);
+ }
+}
+
+void GL_APIENTRY DepthRangef(GLclampf zNear, GLclampf zFar)
+{
+ EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ context->getState().setDepthRange(zNear, zFar);
+ }
+}
+
+void GL_APIENTRY DetachShader(GLuint program, GLuint shader)
+{
+ EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Program *programObject = context->getProgram(program);
+ Shader *shaderObject = context->getShader(shader);
+
+ if (!programObject)
+ {
+ Shader *shaderByProgramHandle;
+ shaderByProgramHandle = context->getShader(program);
+ if (!shaderByProgramHandle)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ }
+
+ if (!shaderObject)
+ {
+ Program *programByShaderHandle = context->getProgram(shader);
+ if (!programByShaderHandle)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ }
+
+ if (!programObject->detachShader(shaderObject))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY Disable(GLenum cap)
+{
+ EVENT("(GLenum cap = 0x%X)", cap);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidCap(context, cap))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ context->getState().setEnableFeature(cap, false);
+ }
+}
+
+void GL_APIENTRY DisableVertexAttribArray(GLuint index)
+{
+ EVENT("(GLuint index = %d)", index);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->getState().setEnableVertexAttribArray(index, false);
+ }
+}
+
+void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateDrawArrays(context, mode, first, count, 0))
+ {
+ return;
+ }
+
+ Error error = context->drawArrays(mode, first, count, 0);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
+{
+ EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
+ mode, count, type, indices);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ rx::RangeUI indexRange;
+ if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange))
+ {
+ return;
+ }
+
+ Error error = context->drawElements(mode, count, type, indices, 0, indexRange);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY Enable(GLenum cap)
+{
+ EVENT("(GLenum cap = 0x%X)", cap);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidCap(context, cap))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ context->getState().setEnableFeature(cap, true);
+ }
+}
+
+void GL_APIENTRY EnableVertexAttribArray(GLuint index)
+{
+ EVENT("(GLuint index = %d)", index);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->getState().setEnableVertexAttribArray(index, true);
+ }
+}
+
+void GL_APIENTRY Finish(void)
+{
+ EVENT("()");
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Error error = context->finish();
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY Flush(void)
+{
+ EVENT("()");
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Error error = context->flush();
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
+ "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidFramebufferTarget(target) || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (!ValidateFramebufferRenderbufferParameters(context, target, attachment, renderbuffertarget, renderbuffer))
+ {
+ return;
+ }
+
+ Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (renderbuffer != 0)
+ {
+ Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
+ framebuffer->setRenderbufferAttachment(attachment, renderbufferObject);
+ }
+ else
+ {
+ framebuffer->setNULLAttachment(attachment);
+ }
+ }
+}
+
+void GL_APIENTRY FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
+ "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateFramebufferTexture2D(context, target, attachment, textarget, texture, level))
+ {
+ return;
+ }
+
+ Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (texture != 0)
+ {
+ Texture *textureObj = context->getTexture(texture);
+
+ ImageIndex index = ImageIndex::MakeInvalid();
+
+ if (textarget == GL_TEXTURE_2D)
+ {
+ index = ImageIndex::Make2D(level);
+ }
+ else
+ {
+ ASSERT(IsCubeMapTextureTarget(textarget));
+ index = ImageIndex::MakeCube(textarget, level);
+ }
+
+ framebuffer->setTextureAttachment(attachment, textureObj, index);
+ }
+ else
+ {
+ framebuffer->setNULLAttachment(attachment);
+ }
+ }
+}
+
+void GL_APIENTRY FrontFace(GLenum mode)
+{
+ EVENT("(GLenum mode = 0x%X)", mode);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ switch (mode)
+ {
+ case GL_CW:
+ case GL_CCW:
+ context->getState().setFrontFace(mode);
+ break;
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GenBuffers(GLsizei n, GLuint* buffers)
+{
+ EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ buffers[i] = context->createBuffer();
+ }
+ }
+}
+
+void GL_APIENTRY GenerateMipmap(GLenum target)
+{
+ EVENT("(GLenum target = 0x%X)", target);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidTextureTarget(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Texture *texture = context->getTargetTexture(target);
+
+ if (texture == NULL)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target;
+ GLenum internalFormat = texture->getInternalFormat(baseTarget, 0);
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalFormat);
+
+ // GenerateMipmap should not generate an INVALID_OPERATION for textures created with
+ // unsized formats or that are color renderable and filterable. Since we do not track if
+ // the texture was created with sized or unsized format (only sized formats are stored),
+ // it is not possible to make sure the the LUMA formats can generate mipmaps (they should
+ // be able to) because they aren't color renderable. Simply do a special case for LUMA
+ // textures since they're the only texture format that can be created with unsized formats
+ // that is not color renderable. New unsized formats are unlikely to be added, since ES2
+ // was the last version to use add them.
+ bool isLUMA = internalFormat == GL_LUMINANCE8_EXT ||
+ internalFormat == GL_LUMINANCE8_ALPHA8_EXT ||
+ internalFormat == GL_ALPHA8_EXT;
+
+ if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0 || !formatCaps.filterable ||
+ (!formatCaps.renderable && !isLUMA) || formatInfo.compressed)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // GL_EXT_sRGB does not support mipmap generation on sRGB textures
+ if (context->getClientVersion() == 2 && formatInfo.colorEncoding == GL_SRGB)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // Non-power of 2 ES2 check
+ if (!context->getExtensions().textureNPOT && (!isPow2(texture->getWidth(baseTarget, 0)) || !isPow2(texture->getHeight(baseTarget, 0))))
+ {
+ ASSERT(context->getClientVersion() <= 2 && (target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP));
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // Cube completeness check
+ if (target == GL_TEXTURE_CUBE_MAP && !texture->isCubeComplete())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ Error error = texture->generateMipmaps();
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+ EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ framebuffers[i] = context->createFramebuffer();
+ }
+ }
+}
+
+void GL_APIENTRY GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+ EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ renderbuffers[i] = context->createRenderbuffer();
+ }
+ }
+}
+
+void GL_APIENTRY GenTextures(GLsizei n, GLuint* textures)
+{
+ EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ textures[i] = context->createTexture();
+ }
+ }
+}
+
+void GL_APIENTRY GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+{
+ EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
+ "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
+ program, index, bufsize, length, size, type, name);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (bufsize < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ if (index >= (GLuint)programObject->getActiveAttributeCount())
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ programObject->getActiveAttribute(index, bufsize, length, size, type, name);
+ }
+}
+
+void GL_APIENTRY GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+ EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
+ "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
+ program, index, bufsize, length, size, type, name);
+
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (bufsize < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ if (index >= (GLuint)programObject->getActiveUniformCount())
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ programObject->getActiveUniform(index, bufsize, length, size, type, name);
+ }
+}
+
+void GL_APIENTRY GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+ EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
+ program, maxcount, count, shaders);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (maxcount < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ return programObject->getAttachedShaders(maxcount, count, shaders);
+ }
+}
+
+GLint GL_APIENTRY GetAttribLocation(GLuint program, const GLchar* name)
+{
+ EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return -1;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return -1;
+ }
+ }
+
+ if (!programObject->isLinked())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return -1;
+ }
+
+ return programObject->getAttributeLocation(name);
+ }
+
+ return -1;
+}
+
+void GL_APIENTRY GetBooleanv(GLenum pname, GLboolean* params)
+{
+ EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
+ {
+ return;
+ }
+
+ if (nativeType == GL_BOOL)
+ {
+ context->getBooleanv(pname, params);
+ }
+ else
+ {
+ CastStateValues(context, nativeType, pname, numParams, params);
+ }
+ }
+}
+
+void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidBufferTarget(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (!ValidBufferParameter(context, pname))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (!buffer)
+ {
+ // A null buffer means that "0" is bound to the requested buffer target
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_BUFFER_USAGE:
+ *params = static_cast<GLint>(buffer->getUsage());
+ break;
+ case GL_BUFFER_SIZE:
+ *params = clampCast<GLint>(buffer->getSize());
+ break;
+ case GL_BUFFER_ACCESS_FLAGS:
+ *params = buffer->getAccessFlags();
+ break;
+ case GL_BUFFER_MAPPED:
+ *params = static_cast<GLint>(buffer->isMapped());
+ break;
+ case GL_BUFFER_MAP_OFFSET:
+ *params = clampCast<GLint>(buffer->getMapOffset());
+ break;
+ case GL_BUFFER_MAP_LENGTH:
+ *params = clampCast<GLint>(buffer->getMapLength());
+ break;
+ default: UNREACHABLE(); break;
+ }
+ }
+}
+
+GLenum GL_APIENTRY GetError(void)
+{
+ EVENT("()");
+
+ Context *context = GetGlobalContext();
+
+ if (context)
+ {
+ return context->getError();
+ }
+
+ return GL_NO_ERROR;
+}
+
+void GL_APIENTRY GetFloatv(GLenum pname, GLfloat* params)
+{
+ EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
+ {
+ return;
+ }
+
+ if (nativeType == GL_FLOAT)
+ {
+ context->getFloatv(pname, params);
+ }
+ else
+ {
+ CastStateValues(context, nativeType, pname, numParams, params);
+ }
+ }
+}
+
+void GL_APIENTRY GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+ EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
+ target, attachment, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidFramebufferTarget(target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ int clientVersion = context->getClientVersion();
+
+ switch (pname)
+ {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
+ if (clientVersion < 3 && !context->getExtensions().sRGB)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
+ case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
+ if (clientVersion < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ // Determine if the attachment is a valid enum
+ switch (attachment)
+ {
+ case GL_BACK:
+ case GL_FRONT:
+ case GL_DEPTH:
+ case GL_STENCIL:
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ if (clientVersion < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+
+ case GL_DEPTH_ATTACHMENT:
+ case GL_STENCIL_ATTACHMENT:
+ break;
+
+ default:
+ if (attachment < GL_COLOR_ATTACHMENT0_EXT ||
+ (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+ }
+
+ Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (framebuffer->id() == 0)
+ {
+ if (clientVersion < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ switch (attachment)
+ {
+ case GL_BACK:
+ case GL_DEPTH:
+ case GL_STENCIL:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ }
+ else
+ {
+ if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+ {
+ // Valid attachment query
+ }
+ else
+ {
+ switch (attachment)
+ {
+ case GL_DEPTH_ATTACHMENT:
+ case GL_STENCIL_ATTACHMENT:
+ break;
+
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ if (framebuffer->hasValidDepthStencil())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ }
+ }
+
+ const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment);
+ if (attachmentObject)
+ {
+ ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
+ attachmentObject->type() == GL_TEXTURE ||
+ attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
+
+ switch (pname)
+ {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ *params = attachmentObject->type();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ if (attachmentObject->type() != GL_RENDERBUFFER && attachmentObject->type() != GL_TEXTURE)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = attachmentObject->id();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ if (attachmentObject->type() != GL_TEXTURE)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = attachmentObject->mipLevel();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ if (attachmentObject->type() != GL_TEXTURE)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = attachmentObject->cubeMapFace();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
+ *params = attachmentObject->getRedSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
+ *params = attachmentObject->getGreenSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
+ *params = attachmentObject->getBlueSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
+ *params = attachmentObject->getAlphaSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
+ *params = attachmentObject->getDepthSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
+ *params = attachmentObject->getStencilSize();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
+ if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ *params = attachmentObject->getComponentType();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
+ *params = attachmentObject->getColorEncoding();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
+ if (attachmentObject->type() != GL_TEXTURE)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = attachmentObject->layer();
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ else
+ {
+ // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
+ // is NONE, then querying any other pname will generate INVALID_ENUM.
+
+ // ES 3.0.2 spec pg 235 states that if the attachment type is none,
+ // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
+ // INVALID_OPERATION for all other pnames
+
+ switch (pname)
+ {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ *params = GL_NONE;
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ if (clientVersion < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = 0;
+ break;
+
+ default:
+ if (clientVersion < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ }
+ }
+ }
+}
+
+void GL_APIENTRY GetIntegerv(GLenum pname, GLint* params)
+{
+ EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ GLenum nativeType;
+ unsigned int numParams = 0;
+
+ if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
+ {
+ return;
+ }
+
+ if (nativeType == GL_INT)
+ {
+ context->getIntegerv(pname, params);
+ }
+ else
+ {
+ CastStateValues(context, nativeType, pname, numParams, params);
+ }
+ }
+}
+
+void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+ EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (context->getClientVersion() < 3)
+ {
+ switch (pname)
+ {
+ case GL_ACTIVE_UNIFORM_BLOCKS:
+ case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
+ case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
+ case GL_TRANSFORM_FEEDBACK_VARYINGS:
+ case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+
+ switch (pname)
+ {
+ case GL_DELETE_STATUS:
+ *params = programObject->isFlaggedForDeletion();
+ return;
+ case GL_LINK_STATUS:
+ *params = programObject->isLinked();
+ return;
+ case GL_VALIDATE_STATUS:
+ *params = programObject->isValidated();
+ return;
+ case GL_INFO_LOG_LENGTH:
+ *params = programObject->getInfoLogLength();
+ return;
+ case GL_ATTACHED_SHADERS:
+ *params = programObject->getAttachedShadersCount();
+ return;
+ case GL_ACTIVE_ATTRIBUTES:
+ *params = programObject->getActiveAttributeCount();
+ return;
+ case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+ *params = programObject->getActiveAttributeMaxLength();
+ return;
+ case GL_ACTIVE_UNIFORMS:
+ *params = programObject->getActiveUniformCount();
+ return;
+ case GL_ACTIVE_UNIFORM_MAX_LENGTH:
+ *params = programObject->getActiveUniformMaxLength();
+ return;
+ case GL_PROGRAM_BINARY_LENGTH_OES:
+ *params = programObject->getBinaryLength();
+ return;
+ case GL_ACTIVE_UNIFORM_BLOCKS:
+ *params = programObject->getActiveUniformBlockCount();
+ return;
+ case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
+ *params = programObject->getActiveUniformBlockMaxLength();
+ break;
+ case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
+ *params = programObject->getTransformFeedbackBufferMode();
+ break;
+ case GL_TRANSFORM_FEEDBACK_VARYINGS:
+ *params = programObject->getTransformFeedbackVaryingCount();
+ break;
+ case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
+ *params = programObject->getTransformFeedbackVaryingMaxLength();
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
+ program, bufsize, length, infolog);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (bufsize < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ programObject->getInfoLog(bufsize, length, infolog);
+ }
+}
+
+void GL_APIENTRY GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (target != GL_RENDERBUFFER)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (context->getState().getRenderbufferId() == 0)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ Renderbuffer *renderbuffer = context->getRenderbuffer(context->getState().getRenderbufferId());
+
+ switch (pname)
+ {
+ case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
+ case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
+ case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
+ case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
+ case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
+ case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
+ case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
+ case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
+ case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
+
+ case GL_RENDERBUFFER_SAMPLES_ANGLE:
+ if (!context->getExtensions().framebufferMultisample)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = renderbuffer->getSamples();
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+ EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Shader *shaderObject = context->getShader(shader);
+
+ if (!shaderObject)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_SHADER_TYPE:
+ *params = shaderObject->getType();
+ return;
+ case GL_DELETE_STATUS:
+ *params = shaderObject->isFlaggedForDeletion();
+ return;
+ case GL_COMPILE_STATUS:
+ *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
+ return;
+ case GL_INFO_LOG_LENGTH:
+ *params = shaderObject->getInfoLogLength();
+ return;
+ case GL_SHADER_SOURCE_LENGTH:
+ *params = shaderObject->getSourceLength();
+ return;
+ case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
+ *params = shaderObject->getTranslatedSourceLength();
+ return;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
+ shader, bufsize, length, infolog);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (bufsize < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Shader *shaderObject = context->getShader(shader);
+
+ if (!shaderObject)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ shaderObject->getInfoLog(bufsize, length, infolog);
+ }
+}
+
+void GL_APIENTRY GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+ EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
+ shadertype, precisiontype, range, precision);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ switch (shadertype)
+ {
+ case GL_VERTEX_SHADER:
+ switch (precisiontype)
+ {
+ case GL_LOW_FLOAT:
+ context->getCaps().vertexLowpFloat.get(range, precision);
+ break;
+ case GL_MEDIUM_FLOAT:
+ context->getCaps().vertexMediumpFloat.get(range, precision);
+ break;
+ case GL_HIGH_FLOAT:
+ context->getCaps().vertexHighpFloat.get(range, precision);
+ break;
+
+ case GL_LOW_INT:
+ context->getCaps().vertexLowpInt.get(range, precision);
+ break;
+ case GL_MEDIUM_INT:
+ context->getCaps().vertexMediumpInt.get(range, precision);
+ break;
+ case GL_HIGH_INT:
+ context->getCaps().vertexHighpInt.get(range, precision);
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+ case GL_FRAGMENT_SHADER:
+ switch (precisiontype)
+ {
+ case GL_LOW_FLOAT:
+ context->getCaps().fragmentLowpFloat.get(range, precision);
+ break;
+ case GL_MEDIUM_FLOAT:
+ context->getCaps().fragmentMediumpFloat.get(range, precision);
+ break;
+ case GL_HIGH_FLOAT:
+ context->getCaps().fragmentHighpFloat.get(range, precision);
+ break;
+
+ case GL_LOW_INT:
+ context->getCaps().fragmentLowpInt.get(range, precision);
+ break;
+ case GL_MEDIUM_INT:
+ context->getCaps().fragmentMediumpInt.get(range, precision);
+ break;
+ case GL_HIGH_INT:
+ context->getCaps().fragmentHighpInt.get(range, precision);
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ }
+}
+
+void GL_APIENTRY GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+ EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
+ shader, bufsize, length, source);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (bufsize < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Shader *shaderObject = context->getShader(shader);
+
+ if (!shaderObject)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ shaderObject->getSource(bufsize, length, source);
+ }
+}
+
+const GLubyte *GL_APIENTRY GetString(GLenum name)
+{
+ EVENT("(GLenum name = 0x%X)", name);
+
+ Context *context = GetValidGlobalContext();
+
+ switch (name)
+ {
+ case GL_VENDOR:
+ return (GLubyte*)"Google Inc.";
+
+ case GL_RENDERER:
+ return (GLubyte*)((context != NULL) ? context->getRendererString().c_str() : "ANGLE");
+
+ case GL_VERSION:
+ if (context->getClientVersion() == 2)
+ {
+ return (GLubyte*)"OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")";
+ }
+ else
+ {
+ return (GLubyte*)"OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")";
+ }
+
+ case GL_SHADING_LANGUAGE_VERSION:
+ if (context->getClientVersion() == 2)
+ {
+ return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")";
+ }
+ else
+ {
+ return (GLubyte*)"OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")";
+ }
+
+ case GL_EXTENSIONS:
+ return (GLubyte*)((context != NULL) ? context->getExtensionString().c_str() : "");
+
+ default:
+ if (context)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ }
+ return NULL;
+ }
+}
+
+void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
+{
+ EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Texture *texture = context->getTargetTexture(target);
+
+ if (!texture)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_MAG_FILTER:
+ *params = (GLfloat)texture->getSamplerState().magFilter;
+ break;
+ case GL_TEXTURE_MIN_FILTER:
+ *params = (GLfloat)texture->getSamplerState().minFilter;
+ break;
+ case GL_TEXTURE_WRAP_S:
+ *params = (GLfloat)texture->getSamplerState().wrapS;
+ break;
+ case GL_TEXTURE_WRAP_T:
+ *params = (GLfloat)texture->getSamplerState().wrapT;
+ break;
+ case GL_TEXTURE_WRAP_R:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLfloat)texture->getSamplerState().wrapR;
+ break;
+ case GL_TEXTURE_IMMUTABLE_FORMAT:
+ // Exposed to ES2.0 through EXT_texture_storage, no client version validation.
+ *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
+ break;
+ case GL_TEXTURE_IMMUTABLE_LEVELS:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLfloat)texture->immutableLevelCount();
+ break;
+ case GL_TEXTURE_USAGE_ANGLE:
+ *params = (GLfloat)texture->getUsage();
+ break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (!context->getExtensions().textureFilterAnisotropic)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLfloat)texture->getSamplerState().maxAnisotropy;
+ break;
+ case GL_TEXTURE_SWIZZLE_R:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLfloat)texture->getSamplerState().swizzleRed;
+ break;
+ case GL_TEXTURE_SWIZZLE_G:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLfloat)texture->getSamplerState().swizzleGreen;
+ break;
+ case GL_TEXTURE_SWIZZLE_B:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLfloat)texture->getSamplerState().swizzleBlue;
+ break;
+ case GL_TEXTURE_SWIZZLE_A:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLfloat)texture->getSamplerState().swizzleAlpha;
+ break;
+ case GL_TEXTURE_BASE_LEVEL:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLfloat)texture->getSamplerState().baseLevel;
+ break;
+ case GL_TEXTURE_MAX_LEVEL:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLfloat)texture->getSamplerState().maxLevel;
+ break;
+ case GL_TEXTURE_MIN_LOD:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = texture->getSamplerState().minLod;
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = texture->getSamplerState().maxLod;
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Texture *texture = context->getTargetTexture(target);
+
+ if (!texture)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_MAG_FILTER:
+ *params = texture->getSamplerState().magFilter;
+ break;
+ case GL_TEXTURE_MIN_FILTER:
+ *params = texture->getSamplerState().minFilter;
+ break;
+ case GL_TEXTURE_WRAP_S:
+ *params = texture->getSamplerState().wrapS;
+ break;
+ case GL_TEXTURE_WRAP_T:
+ *params = texture->getSamplerState().wrapT;
+ break;
+ case GL_TEXTURE_WRAP_R:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = texture->getSamplerState().wrapR;
+ break;
+ case GL_TEXTURE_IMMUTABLE_FORMAT:
+ // Exposed to ES2.0 through EXT_texture_storage, no client version validation.
+ *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_TEXTURE_IMMUTABLE_LEVELS:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = static_cast<GLint>(texture->immutableLevelCount());
+ break;
+ case GL_TEXTURE_USAGE_ANGLE:
+ *params = texture->getUsage();
+ break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (!context->getExtensions().textureFilterAnisotropic)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLint)texture->getSamplerState().maxAnisotropy;
+ break;
+ case GL_TEXTURE_SWIZZLE_R:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = texture->getSamplerState().swizzleRed;
+ break;
+ case GL_TEXTURE_SWIZZLE_G:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = texture->getSamplerState().swizzleGreen;
+ break;
+ case GL_TEXTURE_SWIZZLE_B:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = texture->getSamplerState().swizzleBlue;
+ break;
+ case GL_TEXTURE_SWIZZLE_A:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = texture->getSamplerState().swizzleAlpha;
+ break;
+ case GL_TEXTURE_BASE_LEVEL:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = texture->getSamplerState().baseLevel;
+ break;
+ case GL_TEXTURE_MAX_LEVEL:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = texture->getSamplerState().maxLevel;
+ break;
+ case GL_TEXTURE_MIN_LOD:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLint)texture->getSamplerState().minLod;
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ *params = (GLint)texture->getSamplerState().maxLod;
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+ EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateGetUniformfv(context, program, location, params))
+ {
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+ ASSERT(programObject);
+
+ programObject->getUniformfv(location, params);
+ }
+}
+
+void GL_APIENTRY GetUniformiv(GLuint program, GLint location, GLint* params)
+{
+ EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateGetUniformiv(context, program, location, params))
+ {
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+ ASSERT(programObject);
+
+ programObject->getUniformiv(location, params);
+ }
+}
+
+GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar* name)
+{
+ EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (strstr(name, "gl_") == name)
+ {
+ return -1;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return -1;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return -1;
+ }
+ }
+
+ if (!programObject->isLinked())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return -1;
+ }
+
+ return programObject->getUniformLocation(name);
+ }
+
+ return -1;
+}
+
+void GL_APIENTRY GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+ EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (!ValidateGetVertexAttribParameters(context, pname))
+ {
+ return;
+ }
+
+ if (pname == GL_CURRENT_VERTEX_ATTRIB)
+ {
+ const VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
+ for (int i = 0; i < 4; ++i)
+ {
+ params[i] = currentValueData.FloatValues[i];
+ }
+ }
+ else
+ {
+ const VertexAttribute &attribState = context->getState().getVertexArray()->getVertexAttribute(index);
+ *params = QuerySingleVertexAttributeParameter<GLfloat>(attribState, pname);
+ }
+ }
+}
+
+void GL_APIENTRY GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+ EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (!ValidateGetVertexAttribParameters(context, pname))
+ {
+ return;
+ }
+
+ if (pname == GL_CURRENT_VERTEX_ATTRIB)
+ {
+ const VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
+ for (int i = 0; i < 4; ++i)
+ {
+ float currentValue = currentValueData.FloatValues[i];
+ params[i] = iround<GLint>(currentValue);
+ }
+ }
+ else
+ {
+ const VertexAttribute &attribState = context->getState().getVertexArray()->getVertexAttribute(index);
+ *params = QuerySingleVertexAttributeParameter<GLint>(attribState, pname);
+ }
+ }
+}
+
+void GL_APIENTRY GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
+{
+ EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ *pointer = const_cast<GLvoid*>(context->getState().getVertexAttribPointer(index));
+ }
+}
+
+void GL_APIENTRY Hint(GLenum target, GLenum mode)
+{
+ EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ switch (mode)
+ {
+ case GL_FASTEST:
+ case GL_NICEST:
+ case GL_DONT_CARE:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (target)
+ {
+ case GL_GENERATE_MIPMAP_HINT:
+ context->getState().setGenerateMipmapHint(mode);
+ break;
+
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+ context->getState().setFragmentShaderDerivativeHint(mode);
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+GLboolean GL_APIENTRY IsBuffer(GLuint buffer)
+{
+ EVENT("(GLuint buffer = %d)", buffer);
+
+ Context *context = GetValidGlobalContext();
+ if (context && buffer)
+ {
+ Buffer *bufferObject = context->getBuffer(buffer);
+
+ if (bufferObject)
+ {
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+GLboolean GL_APIENTRY IsEnabled(GLenum cap)
+{
+ EVENT("(GLenum cap = 0x%X)", cap);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidCap(context, cap))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return GL_FALSE;
+ }
+
+ return context->getState().getEnableFeature(cap);
+ }
+
+ return false;
+}
+
+GLboolean GL_APIENTRY IsFramebuffer(GLuint framebuffer)
+{
+ EVENT("(GLuint framebuffer = %d)", framebuffer);
+
+ Context *context = GetValidGlobalContext();
+ if (context && framebuffer)
+ {
+ Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
+
+ if (framebufferObject)
+ {
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+GLboolean GL_APIENTRY IsProgram(GLuint program)
+{
+ EVENT("(GLuint program = %d)", program);
+
+ Context *context = GetValidGlobalContext();
+ if (context && program)
+ {
+ Program *programObject = context->getProgram(program);
+
+ if (programObject)
+ {
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+GLboolean GL_APIENTRY IsRenderbuffer(GLuint renderbuffer)
+{
+ EVENT("(GLuint renderbuffer = %d)", renderbuffer);
+
+ Context *context = GetValidGlobalContext();
+ if (context && renderbuffer)
+ {
+ Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
+
+ if (renderbufferObject)
+ {
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+GLboolean GL_APIENTRY IsShader(GLuint shader)
+{
+ EVENT("(GLuint shader = %d)", shader);
+
+ Context *context = GetValidGlobalContext();
+ if (context && shader)
+ {
+ Shader *shaderObject = context->getShader(shader);
+
+ if (shaderObject)
+ {
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+GLboolean GL_APIENTRY IsTexture(GLuint texture)
+{
+ EVENT("(GLuint texture = %d)", texture);
+
+ Context *context = GetValidGlobalContext();
+ if (context && texture)
+ {
+ Texture *textureObject = context->getTexture(texture);
+
+ if (textureObject)
+ {
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+void GL_APIENTRY LineWidth(GLfloat width)
+{
+ EVENT("(GLfloat width = %f)", width);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (width <= 0.0f)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->getState().setLineWidth(width);
+ }
+}
+
+void GL_APIENTRY LinkProgram(GLuint program)
+{
+ EVENT("(GLuint program = %d)", program);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ Error error = programObject->link(context->getData());
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY PixelStorei(GLenum pname, GLint param)
+{
+ EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ switch (pname)
+ {
+ case GL_UNPACK_IMAGE_HEIGHT:
+ case GL_UNPACK_SKIP_IMAGES:
+ case GL_UNPACK_ROW_LENGTH:
+ 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:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+
+ if (param < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE, "Cannot use negative values in PixelStorei"));
+ return;
+ }
+
+ State &state = context->getState();
+
+ switch (pname)
+ {
+ case GL_UNPACK_ALIGNMENT:
+ if (param != 1 && param != 2 && param != 4 && param != 8)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ state.setUnpackAlignment(param);
+ break;
+
+ case GL_PACK_ALIGNMENT:
+ if (param != 1 && param != 2 && param != 4 && param != 8)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ state.setPackAlignment(param);
+ break;
+
+ case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+ state.setPackReverseRowOrder(param != 0);
+ break;
+
+ case GL_UNPACK_ROW_LENGTH:
+ ASSERT(context->getClientVersion() >= 3);
+ state.setUnpackRowLength(param);
+ break;
+
+ case GL_UNPACK_IMAGE_HEIGHT:
+ ASSERT(context->getClientVersion() >= 3);
+ state.getUnpackState().imageHeight = param;
+ break;
+
+ case GL_UNPACK_SKIP_IMAGES:
+ ASSERT(context->getClientVersion() >= 3);
+ state.getUnpackState().skipImages = param;
+ break;
+
+ case GL_UNPACK_SKIP_ROWS:
+ ASSERT(context->getClientVersion() >= 3);
+ state.getUnpackState().skipRows = param;
+ break;
+
+ case GL_UNPACK_SKIP_PIXELS:
+ ASSERT(context->getClientVersion() >= 3);
+ state.getUnpackState().skipPixels = param;
+ break;
+
+ case GL_PACK_ROW_LENGTH:
+ ASSERT(context->getClientVersion() >= 3);
+ state.getPackState().rowLength = param;
+ break;
+
+ case GL_PACK_SKIP_ROWS:
+ ASSERT(context->getClientVersion() >= 3);
+ state.getPackState().skipRows = param;
+ break;
+
+ case GL_PACK_SKIP_PIXELS:
+ ASSERT(context->getClientVersion() >= 3);
+ state.getPackState().skipPixels = param;
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units)
+{
+ EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ context->getState().setPolygonOffsetParams(factor, units);
+ }
+}
+
+void GL_APIENTRY ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLvoid* pixels)
+{
+ EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
+ "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
+ x, y, width, height, format, type, pixels);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (width < 0 || height < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (!ValidateReadPixelsParameters(context, x, y, width, height,
+ format, type, NULL, pixels))
+ {
+ return;
+ }
+
+ Framebuffer *framebufferObject = context->getState().getReadFramebuffer();
+ ASSERT(framebufferObject);
+
+ Rectangle area(x, y, width, height);
+ Error error = framebufferObject->readPixels(context->getState(), area, format, type, pixels);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY ReleaseShaderCompiler(void)
+{
+ EVENT("()");
+
+ Context *context = GetValidGlobalContext();
+
+ if (context)
+ {
+ Compiler *compiler = context->getCompiler();
+ Error error = compiler->release();
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+ target, internalformat, width, height);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateRenderbufferStorageParametersANGLE(context, target, 0, internalformat,
+ width, height))
+ {
+ return;
+ }
+
+ Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
+ Error error = renderbuffer->setStorage(internalformat, width, height);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY SampleCoverage(GLclampf value, GLboolean invert)
+{
+ EVENT("(GLclampf value = %f, GLboolean invert = %u)", value, invert);
+
+ Context* context = GetValidGlobalContext();
+
+ if (context)
+ {
+ context->getState().setSampleCoverageParams(clamp01(value), invert == GL_TRUE);
+ }
+}
+
+void GL_APIENTRY Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
+
+ Context* context = GetValidGlobalContext();
+ if (context)
+ {
+ if (width < 0 || height < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->getState().setScissorParams(x, y, width, height);
+ }
+}
+
+void GL_APIENTRY ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+{
+ EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
+ "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
+ n, shaders, binaryformat, binary, length);
+
+ Context* context = GetValidGlobalContext();
+ if (context)
+ {
+ const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
+ if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) == shaderBinaryFormats.end())
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ // No binary shader formats are supported.
+ UNIMPLEMENTED();
+ }
+}
+
+void GL_APIENTRY ShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length)
+{
+ EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
+ shader, count, string, length);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (count < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Shader *shaderObject = context->getShader(shader);
+
+ if (!shaderObject)
+ {
+ if (context->getProgram(shader))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ shaderObject->setSource(count, string, length);
+ }
+}
+
+void GL_APIENTRY StencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ StencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
+}
+
+void GL_APIENTRY StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ switch (face)
+ {
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ 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:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
+ {
+ context->getState().setStencilParams(func, ref, mask);
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+ {
+ context->getState().setStencilBackParams(func, ref, mask);
+ }
+ }
+}
+
+void GL_APIENTRY StencilMask(GLuint mask)
+{
+ StencilMaskSeparate(GL_FRONT_AND_BACK, mask);
+}
+
+void GL_APIENTRY StencilMaskSeparate(GLenum face, GLuint mask)
+{
+ EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ switch (face)
+ {
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
+ {
+ context->getState().setStencilWritemask(mask);
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+ {
+ context->getState().setStencilBackWritemask(mask);
+ }
+ }
+}
+
+void GL_APIENTRY StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ StencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
+}
+
+void GL_APIENTRY StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
+ face, fail, zfail, zpass);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ switch (face)
+ {
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (fail)
+ {
+ 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:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (zfail)
+ {
+ 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:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (zpass)
+ {
+ 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:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
+ {
+ context->getState().setStencilOperations(fail, zfail, zpass);
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+ {
+ context->getState().setStencilBackOperations(fail, zfail, zpass);
+ }
+ }
+}
+
+void GL_APIENTRY TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+ GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
+ "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
+ target, level, internalformat, width, height, border, format, type, pixels);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3 &&
+ !ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
+ 0, 0, width, height, border, format, type, pixels))
+ {
+ return;
+ }
+
+ if (context->getClientVersion() >= 3 &&
+ !ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
+ 0, 0, 0, width, height, 1, border, format, type, pixels))
+ {
+ return;
+ }
+
+ Extents size(width, height, 1);
+ Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ Error error = texture->setImage(target, level, internalformat, size, format, type, context->getState().getUnpackState(),
+ reinterpret_cast<const uint8_t *>(pixels));
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
+ {
+ return;
+ }
+
+ Texture *texture = context->getTargetTexture(target);
+
+ if (!texture)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_WRAP_S: texture->getSamplerState().wrapS = uiround<GLenum>(param); break;
+ case GL_TEXTURE_WRAP_T: texture->getSamplerState().wrapT = uiround<GLenum>(param); break;
+ case GL_TEXTURE_WRAP_R: texture->getSamplerState().wrapR = uiround<GLenum>(param); break;
+ case GL_TEXTURE_MIN_FILTER: texture->getSamplerState().minFilter = uiround<GLenum>(param); break;
+ case GL_TEXTURE_MAG_FILTER: texture->getSamplerState().magFilter = uiround<GLenum>(param); break;
+ case GL_TEXTURE_USAGE_ANGLE: texture->setUsage(uiround<GLenum>(param)); break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->getSamplerState().maxAnisotropy = std::min(param, context->getExtensions().maxTextureAnisotropy); break;
+ case GL_TEXTURE_COMPARE_MODE: texture->getSamplerState().compareMode = uiround<GLenum>(param); break;
+ case GL_TEXTURE_COMPARE_FUNC: texture->getSamplerState().compareFunc = uiround<GLenum>(param); break;
+ case GL_TEXTURE_SWIZZLE_R: texture->getSamplerState().swizzleRed = uiround<GLenum>(param); break;
+ case GL_TEXTURE_SWIZZLE_G: texture->getSamplerState().swizzleGreen = uiround<GLenum>(param); break;
+ case GL_TEXTURE_SWIZZLE_B: texture->getSamplerState().swizzleBlue = uiround<GLenum>(param); break;
+ case GL_TEXTURE_SWIZZLE_A: texture->getSamplerState().swizzleAlpha = uiround<GLenum>(param); break;
+ case GL_TEXTURE_BASE_LEVEL: texture->getSamplerState().baseLevel = iround<GLint>(param); break;
+ case GL_TEXTURE_MAX_LEVEL: texture->getSamplerState().maxLevel = iround<GLint>(param); break;
+ case GL_TEXTURE_MIN_LOD: texture->getSamplerState().minLod = param; break;
+ case GL_TEXTURE_MAX_LOD: texture->getSamplerState().maxLod = param; break;
+ default: UNREACHABLE(); break;
+ }
+ }
+}
+
+void GL_APIENTRY TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
+{
+ TexParameterf(target, pname, (GLfloat)*params);
+}
+
+void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateTexParamParameters(context, pname, param))
+ {
+ return;
+ }
+
+ Texture *texture = context->getTargetTexture(target);
+
+ if (!texture)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_WRAP_S: texture->getSamplerState().wrapS = (GLenum)param; break;
+ case GL_TEXTURE_WRAP_T: texture->getSamplerState().wrapT = (GLenum)param; break;
+ case GL_TEXTURE_WRAP_R: texture->getSamplerState().wrapR = (GLenum)param; break;
+ case GL_TEXTURE_MIN_FILTER: texture->getSamplerState().minFilter = (GLenum)param; break;
+ case GL_TEXTURE_MAG_FILTER: texture->getSamplerState().magFilter = (GLenum)param; break;
+ case GL_TEXTURE_USAGE_ANGLE: texture->setUsage((GLenum)param); break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->getSamplerState().maxAnisotropy = std::min((float)param, context->getExtensions().maxTextureAnisotropy); break;
+ case GL_TEXTURE_COMPARE_MODE: texture->getSamplerState().compareMode = (GLenum)param; break;
+ case GL_TEXTURE_COMPARE_FUNC: texture->getSamplerState().compareFunc = (GLenum)param; break;
+ case GL_TEXTURE_SWIZZLE_R: texture->getSamplerState().swizzleRed = (GLenum)param; break;
+ case GL_TEXTURE_SWIZZLE_G: texture->getSamplerState().swizzleGreen = (GLenum)param; break;
+ case GL_TEXTURE_SWIZZLE_B: texture->getSamplerState().swizzleBlue = (GLenum)param; break;
+ case GL_TEXTURE_SWIZZLE_A: texture->getSamplerState().swizzleAlpha = (GLenum)param; break;
+ case GL_TEXTURE_BASE_LEVEL: texture->getSamplerState().baseLevel = param; break;
+ case GL_TEXTURE_MAX_LEVEL: texture->getSamplerState().maxLevel = param; break;
+ case GL_TEXTURE_MIN_LOD: texture->getSamplerState().minLod = (GLfloat)param; break;
+ case GL_TEXTURE_MAX_LOD: texture->getSamplerState().maxLod = (GLfloat)param; break;
+ default: UNREACHABLE(); break;
+ }
+ }
+}
+
+void GL_APIENTRY TexParameteriv(GLenum target, GLenum pname, const GLint* params)
+{
+ TexParameteri(target, pname, *params);
+}
+
+void GL_APIENTRY TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid* pixels)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+ "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
+ "const GLvoid* pixels = 0x%0.8p)",
+ target, level, xoffset, yoffset, width, height, format, type, pixels);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3 &&
+ !ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true,
+ xoffset, yoffset, width, height, 0, format, type, pixels))
+ {
+ return;
+ }
+
+ if (context->getClientVersion() >= 3 &&
+ !ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
+ xoffset, yoffset, 0, width, height, 1, 0, format, type, pixels))
+ {
+ return;
+ }
+
+ // Zero sized uploads are valid but no-ops
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
+
+ Box area(xoffset, yoffset, 0, width, height, 1);
+ Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
+ Error error = texture->setSubImage(target, level, area, format, type, context->getState().getUnpackState(),
+ reinterpret_cast<const uint8_t *>(pixels));
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY Uniform1f(GLint location, GLfloat x)
+{
+ Uniform1fv(location, 1, &x);
+}
+
+void GL_APIENTRY Uniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_FLOAT, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform1fv(location, count, v);
+ }
+}
+
+void GL_APIENTRY Uniform1i(GLint location, GLint x)
+{
+ Uniform1iv(location, 1, &x);
+}
+
+void GL_APIENTRY Uniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_INT, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform1iv(location, count, v);
+ }
+}
+
+void GL_APIENTRY Uniform2f(GLint location, GLfloat x, GLfloat y)
+{
+ GLfloat xy[2] = {x, y};
+
+ Uniform2fv(location, 1, xy);
+}
+
+void GL_APIENTRY Uniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_FLOAT_VEC2, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform2fv(location, count, v);
+ }
+}
+
+void GL_APIENTRY Uniform2i(GLint location, GLint x, GLint y)
+{
+ GLint xy[2] = {x, y};
+
+ Uniform2iv(location, 1, xy);
+}
+
+void GL_APIENTRY Uniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_INT_VEC2, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform2iv(location, count, v);
+ }
+}
+
+void GL_APIENTRY Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLfloat xyz[3] = {x, y, z};
+
+ Uniform3fv(location, 1, xyz);
+}
+
+void GL_APIENTRY Uniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_FLOAT_VEC3, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform3fv(location, count, v);
+ }
+}
+
+void GL_APIENTRY Uniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+ GLint xyz[3] = {x, y, z};
+
+ Uniform3iv(location, 1, xyz);
+}
+
+void GL_APIENTRY Uniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_INT_VEC3, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform3iv(location, count, v);
+ }
+}
+
+void GL_APIENTRY Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLfloat xyzw[4] = {x, y, z, w};
+
+ Uniform4fv(location, 1, xyzw);
+}
+
+void GL_APIENTRY Uniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_FLOAT_VEC4, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform4fv(location, count, v);
+ }
+}
+
+void GL_APIENTRY Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+ GLint xyzw[4] = {x, y, z, w};
+
+ Uniform4iv(location, 1, xyzw);
+}
+
+void GL_APIENTRY Uniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_INT_VEC4, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform4iv(location, count, v);
+ }
+}
+
+void GL_APIENTRY UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
+ location, count, transpose, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniformMatrix2fv(location, count, transpose, value);
+ }
+}
+
+void GL_APIENTRY UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
+ location, count, transpose, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniformMatrix3fv(location, count, transpose, value);
+ }
+}
+
+void GL_APIENTRY UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
+ location, count, transpose, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniformMatrix4fv(location, count, transpose, value);
+ }
+}
+
+void GL_APIENTRY UseProgram(GLuint program)
+{
+ EVENT("(GLuint program = %d)", program);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject && program != 0)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ if (program != 0 && !programObject->isLinked())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ context->useProgram(program);
+ }
+}
+
+void GL_APIENTRY ValidateProgram(GLuint program)
+{
+ EVENT("(GLuint program = %d)", program);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ programObject->validate(context->getCaps());
+ }
+}
+
+void GL_APIENTRY VertexAttrib1f(GLuint index, GLfloat x)
+{
+ EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ GLfloat vals[4] = { x, 0, 0, 1 };
+ context->getState().setVertexAttribf(index, vals);
+ }
+}
+
+void GL_APIENTRY VertexAttrib1fv(GLuint index, const GLfloat* values)
+{
+ EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ GLfloat vals[4] = { values[0], 0, 0, 1 };
+ context->getState().setVertexAttribf(index, vals);
+ }
+}
+
+void GL_APIENTRY VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
+{
+ EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ GLfloat vals[4] = { x, y, 0, 1 };
+ context->getState().setVertexAttribf(index, vals);
+ }
+}
+
+void GL_APIENTRY VertexAttrib2fv(GLuint index, const GLfloat* values)
+{
+ EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ GLfloat vals[4] = { values[0], values[1], 0, 1 };
+ context->getState().setVertexAttribf(index, vals);
+ }
+}
+
+void GL_APIENTRY VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+ EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ GLfloat vals[4] = { x, y, z, 1 };
+ context->getState().setVertexAttribf(index, vals);
+ }
+}
+
+void GL_APIENTRY VertexAttrib3fv(GLuint index, const GLfloat* values)
+{
+ EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ GLfloat vals[4] = { values[0], values[1], values[2], 1 };
+ context->getState().setVertexAttribf(index, vals);
+ }
+}
+
+void GL_APIENTRY VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ GLfloat vals[4] = { x, y, z, w };
+ context->getState().setVertexAttribf(index, vals);
+ }
+}
+
+void GL_APIENTRY VertexAttrib4fv(GLuint index, const GLfloat* values)
+{
+ EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->getState().setVertexAttribf(index, values);
+ }
+}
+
+void GL_APIENTRY VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+ EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
+ "GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
+ index, size, type, normalized, stride, ptr);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (size < 1 || size > 4)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ switch (type)
+ {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_FIXED:
+ case GL_FLOAT:
+ break;
+
+ case GL_HALF_FLOAT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (stride < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // [OpenGL ES 3.0.2] Section 2.8 page 24:
+ // An INVALID_OPERATION error is generated when a non-zero vertex array object
+ // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
+ // and the pointer argument is not NULL.
+ if (context->getState().getVertexArray()->id() != 0 && context->getState().getArrayBufferId() == 0 && ptr != NULL)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type,
+ normalized == GL_TRUE, false, stride, ptr);
+ }
+}
+
+void GL_APIENTRY Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (width < 0 || height < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->getState().setViewportParams(x, y, width, height);
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.h b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.h
new file mode 100644
index 0000000000..eee5fb5468
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.h
@@ -0,0 +1,163 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_gles_2_0.h : Defines the GLES 2.0 entry points.
+
+#ifndef LIBGLESV2_ENTRYPOINTGLES20_H_
+#define LIBGLESV2_ENTRYPOINTGLES20_H_
+
+#include <GLES2/gl2.h>
+#include <export.h>
+
+namespace gl
+{
+
+ANGLE_EXPORT void GL_APIENTRY ActiveTexture(GLenum texture);
+ANGLE_EXPORT void GL_APIENTRY AttachShader(GLuint program, GLuint shader);
+ANGLE_EXPORT void GL_APIENTRY BindAttribLocation(GLuint program, GLuint index, const GLchar* name);
+ANGLE_EXPORT void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer);
+ANGLE_EXPORT void GL_APIENTRY BindFramebuffer(GLenum target, GLuint framebuffer);
+ANGLE_EXPORT void GL_APIENTRY BindRenderbuffer(GLenum target, GLuint renderbuffer);
+ANGLE_EXPORT void GL_APIENTRY BindTexture(GLenum target, GLuint texture);
+ANGLE_EXPORT void GL_APIENTRY BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ANGLE_EXPORT void GL_APIENTRY BlendEquation(GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ANGLE_EXPORT void GL_APIENTRY BlendFunc(GLenum sfactor, GLenum dfactor);
+ANGLE_EXPORT void GL_APIENTRY BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ANGLE_EXPORT void GL_APIENTRY BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+ANGLE_EXPORT void GL_APIENTRY BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+ANGLE_EXPORT GLenum GL_APIENTRY CheckFramebufferStatus(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY Clear(GLbitfield mask);
+ANGLE_EXPORT void GL_APIENTRY ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ANGLE_EXPORT void GL_APIENTRY ClearDepthf(GLfloat depth);
+ANGLE_EXPORT void GL_APIENTRY ClearStencil(GLint s);
+ANGLE_EXPORT void GL_APIENTRY ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ANGLE_EXPORT void GL_APIENTRY CompileShader(GLuint shader);
+ANGLE_EXPORT void GL_APIENTRY CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+ANGLE_EXPORT void GL_APIENTRY CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
+ANGLE_EXPORT void GL_APIENTRY CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+ANGLE_EXPORT void GL_APIENTRY CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+ANGLE_EXPORT GLuint GL_APIENTRY CreateProgram(void);
+ANGLE_EXPORT GLuint GL_APIENTRY CreateShader(GLenum type);
+ANGLE_EXPORT void GL_APIENTRY CullFace(GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint* buffers);
+ANGLE_EXPORT void GL_APIENTRY DeleteFramebuffers(GLsizei n, const GLuint* framebuffers);
+ANGLE_EXPORT void GL_APIENTRY DeleteProgram(GLuint program);
+ANGLE_EXPORT void GL_APIENTRY DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
+ANGLE_EXPORT void GL_APIENTRY DeleteShader(GLuint shader);
+ANGLE_EXPORT void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint* textures);
+ANGLE_EXPORT void GL_APIENTRY DepthFunc(GLenum func);
+ANGLE_EXPORT void GL_APIENTRY DepthMask(GLboolean flag);
+ANGLE_EXPORT void GL_APIENTRY DepthRangef(GLfloat n, GLfloat f);
+ANGLE_EXPORT void GL_APIENTRY DetachShader(GLuint program, GLuint shader);
+ANGLE_EXPORT void GL_APIENTRY Disable(GLenum cap);
+ANGLE_EXPORT void GL_APIENTRY DisableVertexAttribArray(GLuint index);
+ANGLE_EXPORT void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count);
+ANGLE_EXPORT void GL_APIENTRY DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+ANGLE_EXPORT void GL_APIENTRY Enable(GLenum cap);
+ANGLE_EXPORT void GL_APIENTRY EnableVertexAttribArray(GLuint index);
+ANGLE_EXPORT void GL_APIENTRY Finish(void);
+ANGLE_EXPORT void GL_APIENTRY Flush(void);
+ANGLE_EXPORT void GL_APIENTRY FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+ANGLE_EXPORT void GL_APIENTRY FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+ANGLE_EXPORT void GL_APIENTRY FrontFace(GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY GenBuffers(GLsizei n, GLuint* buffers);
+ANGLE_EXPORT void GL_APIENTRY GenerateMipmap(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GenFramebuffers(GLsizei n, GLuint* framebuffers);
+ANGLE_EXPORT void GL_APIENTRY GenRenderbuffers(GLsizei n, GLuint* renderbuffers);
+ANGLE_EXPORT void GL_APIENTRY GenTextures(GLsizei n, GLuint* textures);
+ANGLE_EXPORT void GL_APIENTRY GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+ANGLE_EXPORT void GL_APIENTRY GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+ANGLE_EXPORT void GL_APIENTRY GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+ANGLE_EXPORT GLint GL_APIENTRY GetAttribLocation(GLuint program, const GLchar* name);
+ANGLE_EXPORT void GL_APIENTRY GetBooleanv(GLenum pname, GLboolean* params);
+ANGLE_EXPORT void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
+ANGLE_EXPORT GLenum GL_APIENTRY GetError(void);
+ANGLE_EXPORT void GL_APIENTRY GetFloatv(GLenum pname, GLfloat* params);
+ANGLE_EXPORT void GL_APIENTRY GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+ANGLE_EXPORT void GL_APIENTRY GetIntegerv(GLenum pname, GLint* params);
+ANGLE_EXPORT void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint* params);
+ANGLE_EXPORT void GL_APIENTRY GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+ANGLE_EXPORT void GL_APIENTRY GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
+ANGLE_EXPORT void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint* params);
+ANGLE_EXPORT void GL_APIENTRY GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+ANGLE_EXPORT void GL_APIENTRY GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+ANGLE_EXPORT void GL_APIENTRY GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+ANGLE_EXPORT const GLubyte *GL_APIENTRY GetString(GLenum name);
+ANGLE_EXPORT void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
+ANGLE_EXPORT void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params);
+ANGLE_EXPORT void GL_APIENTRY GetUniformfv(GLuint program, GLint location, GLfloat* params);
+ANGLE_EXPORT void GL_APIENTRY GetUniformiv(GLuint program, GLint location, GLint* params);
+ANGLE_EXPORT GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar* name);
+ANGLE_EXPORT void GL_APIENTRY GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
+ANGLE_EXPORT void GL_APIENTRY GetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
+ANGLE_EXPORT void GL_APIENTRY GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer);
+ANGLE_EXPORT void GL_APIENTRY Hint(GLenum target, GLenum mode);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsBuffer(GLuint buffer);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsEnabled(GLenum cap);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsFramebuffer(GLuint framebuffer);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsProgram(GLuint program);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsRenderbuffer(GLuint renderbuffer);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsShader(GLuint shader);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsTexture(GLuint texture);
+ANGLE_EXPORT void GL_APIENTRY LineWidth(GLfloat width);
+ANGLE_EXPORT void GL_APIENTRY LinkProgram(GLuint program);
+ANGLE_EXPORT void GL_APIENTRY PixelStorei(GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units);
+ANGLE_EXPORT void GL_APIENTRY ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+ANGLE_EXPORT void GL_APIENTRY ReleaseShaderCompiler(void);
+ANGLE_EXPORT void GL_APIENTRY RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY SampleCoverage(GLfloat value, GLboolean invert);
+ANGLE_EXPORT void GL_APIENTRY Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+ANGLE_EXPORT void GL_APIENTRY ShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length);
+ANGLE_EXPORT void GL_APIENTRY StencilFunc(GLenum func, GLint ref, GLuint mask);
+ANGLE_EXPORT void GL_APIENTRY StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ANGLE_EXPORT void GL_APIENTRY StencilMask(GLuint mask);
+ANGLE_EXPORT void GL_APIENTRY StencilMaskSeparate(GLenum face, GLuint mask);
+ANGLE_EXPORT void GL_APIENTRY StencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+ANGLE_EXPORT void GL_APIENTRY StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+ANGLE_EXPORT void GL_APIENTRY TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+ANGLE_EXPORT void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY TexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
+ANGLE_EXPORT void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY TexParameteriv(GLenum target, GLenum pname, const GLint* params);
+ANGLE_EXPORT void GL_APIENTRY TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
+ANGLE_EXPORT void GL_APIENTRY Uniform1f(GLint location, GLfloat x);
+ANGLE_EXPORT void GL_APIENTRY Uniform1fv(GLint location, GLsizei count, const GLfloat* v);
+ANGLE_EXPORT void GL_APIENTRY Uniform1i(GLint location, GLint x);
+ANGLE_EXPORT void GL_APIENTRY Uniform1iv(GLint location, GLsizei count, const GLint* v);
+ANGLE_EXPORT void GL_APIENTRY Uniform2f(GLint location, GLfloat x, GLfloat y);
+ANGLE_EXPORT void GL_APIENTRY Uniform2fv(GLint location, GLsizei count, const GLfloat* v);
+ANGLE_EXPORT void GL_APIENTRY Uniform2i(GLint location, GLint x, GLint y);
+ANGLE_EXPORT void GL_APIENTRY Uniform2iv(GLint location, GLsizei count, const GLint* v);
+ANGLE_EXPORT void GL_APIENTRY Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z);
+ANGLE_EXPORT void GL_APIENTRY Uniform3fv(GLint location, GLsizei count, const GLfloat* v);
+ANGLE_EXPORT void GL_APIENTRY Uniform3i(GLint location, GLint x, GLint y, GLint z);
+ANGLE_EXPORT void GL_APIENTRY Uniform3iv(GLint location, GLsizei count, const GLint* v);
+ANGLE_EXPORT void GL_APIENTRY Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ANGLE_EXPORT void GL_APIENTRY Uniform4fv(GLint location, GLsizei count, const GLfloat* v);
+ANGLE_EXPORT void GL_APIENTRY Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w);
+ANGLE_EXPORT void GL_APIENTRY Uniform4iv(GLint location, GLsizei count, const GLint* v);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ANGLE_EXPORT void GL_APIENTRY UseProgram(GLuint program);
+ANGLE_EXPORT void GL_APIENTRY ValidateProgram(GLuint program);
+ANGLE_EXPORT void GL_APIENTRY VertexAttrib1f(GLuint indx, GLfloat x);
+ANGLE_EXPORT void GL_APIENTRY VertexAttrib1fv(GLuint indx, const GLfloat* values);
+ANGLE_EXPORT void GL_APIENTRY VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
+ANGLE_EXPORT void GL_APIENTRY VertexAttrib2fv(GLuint indx, const GLfloat* values);
+ANGLE_EXPORT void GL_APIENTRY VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ANGLE_EXPORT void GL_APIENTRY VertexAttrib3fv(GLuint indx, const GLfloat* values);
+ANGLE_EXPORT void GL_APIENTRY VertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ANGLE_EXPORT void GL_APIENTRY VertexAttrib4fv(GLuint indx, const GLfloat* values);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+ANGLE_EXPORT void GL_APIENTRY Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+
+}
+
+#endif // LIBGLESV2_ENTRYPOINTGLES20_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp
new file mode 100644
index 0000000000..8be6ae7d2f
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -0,0 +1,1058 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_gles_2_0_ext.cpp : Implements the GLES 2.0 extension entry points.
+
+#include "libGLESv2/entry_points_gles_2_0_ext.h"
+#include "libGLESv2/global_state.h"
+
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Fence.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/Query.h"
+
+#include "libANGLE/validationES.h"
+#include "libANGLE/validationES2.h"
+#include "libANGLE/validationES3.h"
+
+#include "common/debug.h"
+#include "common/utilities.h"
+
+namespace gl
+{
+
+void GL_APIENTRY BeginQueryEXT(GLenum target, GLuint id)
+{
+ EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateBeginQuery(context, target, id))
+ {
+ return;
+ }
+
+ Error error = context->beginQuery(target, id);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint* fences)
+{
+ EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ context->deleteFenceNV(fences[i]);
+ }
+ }
+}
+
+void GL_APIENTRY DeleteQueriesEXT(GLsizei n, const GLuint *ids)
+{
+ EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ context->deleteQuery(ids[i]);
+ }
+ }
+}
+
+void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+{
+ EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateDrawArraysInstancedANGLE(context, mode, first, count, primcount))
+ {
+ return;
+ }
+
+ Error error = context->drawArrays(mode, first, count, primcount);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
+{
+ EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
+ mode, count, type, indices, primcount);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ rx::RangeUI indexRange;
+ if (!ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount, &indexRange))
+ {
+ return;
+ }
+
+ Error error = context->drawElements(mode, count, type, indices, primcount, indexRange);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY EndQueryEXT(GLenum target)
+{
+ EVENT("GLenum target = 0x%X)", target);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateEndQuery(context, target))
+ {
+ return;
+ }
+
+ Error error = context->endQuery(target);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY FinishFenceNV(GLuint fence)
+{
+ EVENT("(GLuint fence = %d)", fence);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ FenceNV *fenceObject = context->getFenceNV(fence);
+
+ if (fenceObject == NULL)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (fenceObject->isFence() != GL_TRUE)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ fenceObject->finishFence();
+ }
+}
+
+void GL_APIENTRY GenFencesNV(GLsizei n, GLuint* fences)
+{
+ EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ fences[i] = context->createFenceNV();
+ }
+ }
+}
+
+void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint* ids)
+{
+ EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (GLsizei i = 0; i < n; i++)
+ {
+ ids[i] = context->createQuery();
+ }
+ }
+}
+
+void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+ EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ FenceNV *fenceObject = context->getFenceNV(fence);
+
+ if (fenceObject == NULL)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (fenceObject->isFence() != GL_TRUE)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ 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)
+ {
+ Error error = fenceObject->testFence(&status);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+ *params = status;
+ break;
+ }
+
+ case GL_FENCE_CONDITION_NV:
+ {
+ *params = static_cast<GLint>(fenceObject->getCondition());
+ break;
+ }
+
+ default:
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+ }
+}
+
+GLenum GL_APIENTRY GetGraphicsResetStatusEXT(void)
+{
+ EVENT("()");
+
+ Context *context = GetGlobalContext();
+
+ if (context)
+ {
+ return context->getResetStatus();
+ }
+
+ return GL_NO_ERROR;
+}
+
+void GL_APIENTRY GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
+{
+ EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidQueryType(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_CURRENT_QUERY_EXT:
+ params[0] = context->getState().getActiveQueryId(target);
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
+{
+ EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Query *queryObject = context->getQuery(id, false, GL_NONE);
+
+ if (!queryObject)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (context->getState().getActiveQueryId(queryObject->getType()) == id)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ switch(pname)
+ {
+ case GL_QUERY_RESULT_EXT:
+ {
+ Error error = queryObject->getResult(params);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+ break;
+
+ case GL_QUERY_RESULT_AVAILABLE_EXT:
+ {
+ Error error = queryObject->isResultAvailable(params);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+ EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
+ shader, bufsize, length, source);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (bufsize < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Shader *shaderObject = context->getShader(shader);
+
+ if (!shaderObject)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // Only returns extra info if ANGLE_GENERATE_SHADER_DEBUG_INFO is defined
+ shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source);
+ }
+}
+
+void GL_APIENTRY GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
+{
+ EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
+ program, location, bufSize, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateGetnUniformfvEXT(context, program, location, bufSize, params))
+ {
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+ ASSERT(programObject);
+
+ programObject->getUniformfv(location, params);
+ }
+}
+
+void GL_APIENTRY GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
+{
+ EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
+ program, location, bufSize, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateGetnUniformivEXT(context, program, location, bufSize, params))
+ {
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+ ASSERT(programObject);
+
+ programObject->getUniformiv(location, params);
+ }
+}
+
+GLboolean GL_APIENTRY IsFenceNV(GLuint fence)
+{
+ EVENT("(GLuint fence = %d)", fence);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ FenceNV *fenceObject = context->getFenceNV(fence);
+
+ if (fenceObject == NULL)
+ {
+ return GL_FALSE;
+ }
+
+ return fenceObject->isFence();
+ }
+
+ return GL_FALSE;
+}
+
+GLboolean GL_APIENTRY IsQueryEXT(GLuint id)
+{
+ EVENT("(GLuint id = %d)", id);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
+ }
+
+ return GL_FALSE;
+}
+
+void GL_APIENTRY ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLsizei bufSize,
+ GLvoid *data)
+{
+ EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
+ "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
+ x, y, width, height, format, type, bufSize, data);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (width < 0 || height < 0 || bufSize < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (!ValidateReadPixelsParameters(context, x, y, width, height,
+ format, type, &bufSize, data))
+ {
+ return;
+ }
+
+ Framebuffer *framebufferObject = context->getState().getReadFramebuffer();
+ ASSERT(framebufferObject);
+
+ Rectangle area(x, y, width, height);
+ Error error = framebufferObject->readPixels(context->getState(), area, format, type, data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+ target, samples, internalformat, width, height);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateRenderbufferStorageParametersANGLE(context, target, samples, internalformat,
+ width, height))
+ {
+ return;
+ }
+
+ Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
+ Error error = renderbuffer->setStorageMultisample(samples, internalformat, width, height);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY SetFenceNV(GLuint fence, GLenum condition)
+{
+ EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (condition != GL_ALL_COMPLETED_NV)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ FenceNV *fenceObject = context->getFenceNV(fence);
+
+ if (fenceObject == NULL)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ Error error = fenceObject->setFence(condition);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+GLboolean GL_APIENTRY TestFenceNV(GLuint fence)
+{
+ EVENT("(GLuint fence = %d)", fence);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ FenceNV *fenceObject = context->getFenceNV(fence);
+
+ if (fenceObject == NULL)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_TRUE;
+ }
+
+ if (fenceObject->isFence() != GL_TRUE)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_TRUE;
+ }
+
+ GLboolean result;
+ Error error = fenceObject->testFence(&result);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return GL_TRUE;
+ }
+
+ return result;
+ }
+
+ return GL_TRUE;
+}
+
+void GL_APIENTRY TexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+ target, levels, internalformat, width, height);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!context->getExtensions().textureStorage)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (context->getClientVersion() < 3 &&
+ !ValidateES2TexStorageParameters(context, target, levels, internalformat, width, height))
+ {
+ return;
+ }
+
+ if (context->getClientVersion() >= 3 &&
+ !ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
+ {
+ return;
+ }
+
+ Extents size(width, height, 1);
+ Texture *texture = context->getTargetTexture(target);
+ Error error = texture->setStorage(target, levels, internalformat, size);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+{
+ EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->setVertexAttribDivisor(index, divisor);
+ }
+}
+
+void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
+ "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
+ "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
+ srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1, mask, filter,
+ true))
+ {
+ return;
+ }
+
+ Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
+ ASSERT(readFramebuffer);
+
+ Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
+ ASSERT(drawFramebuffer);
+
+ Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
+ Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
+
+ Error error = drawFramebuffer->blit(context->getState(), srcArea, dstArea, mask, filter, readFramebuffer);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
+ "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
+ "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
+ target, level, internalformat, width, height, depth, border, format, type, pixels);
+
+ UNIMPLEMENTED(); // FIXME
+}
+
+void GL_APIENTRY GetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)
+{
+ EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)",
+ program, bufSize, length, binaryFormat, binary);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject || !programObject->isLinked())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ Error error = programObject->saveBinary(binaryFormat, binary, bufSize, length);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY ProgramBinaryOES(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
+{
+ EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)",
+ program, binaryFormat, binary, length);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
+ if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) == programBinaryFormats.end())
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+ if (!programObject)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ Error error = programObject->loadBinary(binaryFormat, binary, length);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs)
+{
+ EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (n < 0 || static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ ASSERT(context->getState().getDrawFramebuffer());
+
+ if (context->getState().getDrawFramebuffer()->id() == 0)
+ {
+ if (n != 1)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ }
+ else
+ {
+ for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
+ {
+ const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
+ if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ }
+ }
+
+ Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
+ ASSERT(framebuffer);
+
+ framebuffer->setDrawBuffers(n, bufs);
+ }
+}
+
+void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, void** params)
+{
+ EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidBufferTarget(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (pname != GL_BUFFER_MAP_POINTER)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (!buffer || !buffer->isMapped())
+ {
+ *params = NULL;
+ }
+ else
+ {
+ *params = buffer->getMapPointer();
+ }
+ }
+}
+
+void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access)
+{
+ EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidBufferTarget(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return NULL;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (buffer == NULL)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return NULL;
+ }
+
+ if (access != GL_WRITE_ONLY_OES)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return NULL;
+ }
+
+ if (buffer->isMapped())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return NULL;
+ }
+
+ Error error = buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return NULL;
+ }
+
+ return buffer->getMapPointer();
+ }
+
+ return NULL;
+}
+
+GLboolean GL_APIENTRY UnmapBufferOES(GLenum target)
+{
+ EVENT("(GLenum target = 0x%X)", target);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidBufferTarget(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return GL_FALSE;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (buffer == NULL || !buffer->isMapped())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
+ }
+
+ // TODO: detect if we had corruption. if so, throw an error and return false.
+
+ Error error = buffer->unmap();
+ if (error.isError())
+ {
+ context->recordError(error);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+ }
+
+ return GL_FALSE;
+}
+
+void *GL_APIENTRY MapBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+{
+ EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
+ target, offset, length, access);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidBufferTarget(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return NULL;
+ }
+
+ if (offset < 0 || length < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return NULL;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (buffer == NULL)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return NULL;
+ }
+
+ // Check for buffer overflow
+ size_t offsetSize = static_cast<size_t>(offset);
+ size_t lengthSize = static_cast<size_t>(length);
+
+ if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
+ offsetSize + lengthSize > static_cast<size_t>(buffer->getSize()))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return NULL;
+ }
+
+ // Check for invalid bits in the mask
+ GLbitfield allAccessBits = 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 (access & ~(allAccessBits))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return NULL;
+ }
+
+ if (length == 0 || buffer->isMapped())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return NULL;
+ }
+
+ // Check for invalid bit combinations
+ if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return NULL;
+ }
+
+ 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->recordError(Error(GL_INVALID_OPERATION));
+ return NULL;
+ }
+
+ if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return NULL;
+ }
+
+ Error error = buffer->mapRange(offset, length, access);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return NULL;
+ }
+
+ return buffer->getMapPointer();
+ }
+
+ return NULL;
+}
+
+void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length)
+{
+ EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (offset < 0 || length < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (!ValidBufferTarget(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (buffer == NULL)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // Check for buffer overflow
+ size_t offsetSize = static_cast<size_t>(offset);
+ size_t lengthSize = static_cast<size_t>(length);
+
+ if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
+ offsetSize + lengthSize > static_cast<size_t>(buffer->getMapLength()))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ // We do not currently support a non-trivial implementation of FlushMappedBufferRange
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.h b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.h
new file mode 100644
index 0000000000..816519fe1f
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.h
@@ -0,0 +1,78 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_gles_2_0_ext.h : Defines the GLES 2.0 extension entry points.
+
+#ifndef LIBGLESV2_ENTRYPOINTGLES20EXT_H_
+#define LIBGLESV2_ENTRYPOINTGLES20EXT_H_
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <export.h>
+
+namespace gl
+{
+
+// GL_ANGLE_framebuffer_blit
+ANGLE_EXPORT void GL_APIENTRY 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 RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+
+// GL_NV_fence
+ANGLE_EXPORT void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint* fences);
+ANGLE_EXPORT void GL_APIENTRY GenFencesNV(GLsizei n, GLuint* fences);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsFenceNV(GLuint fence);
+ANGLE_EXPORT GLboolean GL_APIENTRY TestFenceNV(GLuint fence);
+ANGLE_EXPORT void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY FinishFenceNV(GLuint fence);
+ANGLE_EXPORT void GL_APIENTRY SetFenceNV(GLuint fence, GLenum condition);
+
+// GL_ANGLE_translated_shader_source
+ANGLE_EXPORT void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source);
+
+// GL_EXT_texture_storage
+ANGLE_EXPORT void GL_APIENTRY TexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+
+// GL_EXT_robustness
+ANGLE_EXPORT GLenum GL_APIENTRY GetGraphicsResetStatusEXT(void);
+ANGLE_EXPORT void GL_APIENTRY ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+ANGLE_EXPORT void GL_APIENTRY GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, float *params);
+ANGLE_EXPORT void GL_APIENTRY GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint *params);
+
+// GL_EXT_occlusion_query_boolean
+ANGLE_EXPORT void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY DeleteQueriesEXT(GLsizei n, const GLuint *ids);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsQueryEXT(GLuint id);
+ANGLE_EXPORT void GL_APIENTRY BeginQueryEXT(GLenum target, GLuint id);
+ANGLE_EXPORT void GL_APIENTRY EndQueryEXT(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GetQueryivEXT(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params);
+
+// GL_EXT_draw_buffers
+ANGLE_EXPORT void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs);
+
+// GL_ANGLE_instanced_arrays
+ANGLE_EXPORT void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+ANGLE_EXPORT void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
+
+// GL_OES_get_program_binary
+ANGLE_EXPORT void GL_APIENTRY GetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+ANGLE_EXPORT void GL_APIENTRY ProgramBinaryOES(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length);
+
+// GL_OES_mapbuffer
+ANGLE_EXPORT void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access);
+ANGLE_EXPORT GLboolean GL_APIENTRY UnmapBufferOES(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, GLvoid **params);
+
+// GL_EXT_map_buffer_range
+ANGLE_EXPORT void *GL_APIENTRY MapBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+ANGLE_EXPORT void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length);
+
+}
+
+#endif // LIBGLESV2_ENTRYPOINTGLES20EXT_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.cpp
new file mode 100644
index 0000000000..d8bdcd2e50
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.cpp
@@ -0,0 +1,3394 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_gles_3_0.cpp : Implements the GLES 3.0 entry points.
+
+#include "libGLESv2/entry_points_gles_3_0.h"
+#include "libGLESv2/entry_points_gles_2_0_ext.h"
+#include "libGLESv2/global_state.h"
+
+#include "libANGLE/formatutils.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Fence.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Query.h"
+#include "libANGLE/VertexArray.h"
+
+#include "libANGLE/validationES.h"
+#include "libANGLE/validationES3.h"
+#include "libANGLE/queryconversions.h"
+
+#include "common/debug.h"
+
+namespace gl
+{
+
+void GL_APIENTRY ReadBuffer(GLenum mode)
+{
+ EVENT("(GLenum mode = 0x%X)", mode);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateReadBuffer(context, mode))
+ {
+ return;
+ }
+
+ Framebuffer *readFBO = context->getState().getReadFramebuffer();
+ readFBO->setReadBuffer(mode);
+ }
+}
+
+void GL_APIENTRY DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices)
+{
+ EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, "
+ "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ rx::RangeUI indexRange;
+ if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange))
+ {
+ return;
+ }
+ if (indexRange.end > end || indexRange.start < start)
+ {
+ // GL spec says that behavior in this case is undefined - generating an error is fine.
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // As long as index validation is done, it doesn't matter whether the context receives a drawElements or
+ // a drawRangeElements call - the GL back-end is free to choose to call drawRangeElements based on the
+ // validated index range. If index validation is removed, adding drawRangeElements to the context interface
+ // should be reconsidered.
+ Error error = context->drawElements(mode, count, type, indices, 0, indexRange);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
+ "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, "
+ "GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
+ target, level, internalformat, width, height, depth, border, format, type, pixels);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // validateES3TexImageFormat sets the error code if there is an error
+ if (!ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
+ 0, 0, 0, width, height, depth, border, format, type, pixels))
+ {
+ return;
+ }
+
+ Extents size(width, height, depth);
+ Texture *texture = context->getTargetTexture(target);
+ Error error = texture->setImage(target, level, internalformat, size, format, type, context->getState().getUnpackState(),
+ reinterpret_cast<const uint8_t *>(pixels));
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+ "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
+ "GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
+ target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // validateES3TexImageFormat sets the error code if there is an error
+ if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
+ xoffset, yoffset, zoffset, width, height, depth, 0,
+ format, type, pixels))
+ {
+ return;
+ }
+
+ // Zero sized uploads are valid but no-ops
+ if (width == 0 || height == 0 || depth == 0)
+ {
+ return;
+ }
+
+ Box area(xoffset, yoffset, zoffset, width, height, depth);
+ Texture *texture = context->getTargetTexture(target);
+ Error error = texture->setSubImage(target, level, area, format, type, context->getState().getUnpackState(),
+ reinterpret_cast<const uint8_t *>(pixels));
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+ "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
+ target, level, xoffset, yoffset, zoffset, x, y, width, height);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset,
+ x, y, width, height, 0))
+ {
+ return;
+ }
+
+ Offset destOffset(xoffset, yoffset, zoffset);
+ Rectangle sourceArea(x, y, width, height);
+
+ const Framebuffer *framebuffer = context->getState().getReadFramebuffer();
+ Texture *texture = context->getTargetTexture(target);
+ Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
+ "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, "
+ "const GLvoid* data = 0x%0.8p)",
+ target, level, internalformat, width, height, depth, border, imageSize, data);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ // validateES3TexImageFormat sets the error code if there is an error
+ if (!ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
+ 0, 0, 0, width, height, depth, border, GL_NONE, GL_NONE, data))
+ {
+ return;
+ }
+
+ Extents size(width, height, depth);
+ Texture *texture = context->getTargetTexture(target);
+ Error error = texture->setCompressedImage(target, level, internalformat, size, context->getState().getUnpackState(),
+ reinterpret_cast<const uint8_t *>(data));
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+ EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
+ "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
+ "GLenum format = 0x%X, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
+ target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ const InternalFormat &formatInfo = GetInternalFormatInfo(format);
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (!data)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ // validateES3TexImageFormat sets the error code if there is an error
+ if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
+ 0, 0, 0, width, height, depth, 0, GL_NONE, GL_NONE, data))
+ {
+ return;
+ }
+
+ // Zero sized uploads are valid but no-ops
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
+
+ Box area(xoffset, yoffset, zoffset, width, height, depth);
+ Texture *texture = context->getTargetTexture(target);
+ Error error = texture->setCompressedSubImage(target, level, area, format, context->getState().getUnpackState(),
+ reinterpret_cast<const uint8_t *>(data));
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GenQueries(GLsizei n, GLuint* ids)
+{
+ EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (GLsizei i = 0; i < n; i++)
+ {
+ ids[i] = context->createQuery();
+ }
+ }
+}
+
+void GL_APIENTRY DeleteQueries(GLsizei n, const GLuint* ids)
+{
+ EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (GLsizei i = 0; i < n; i++)
+ {
+ context->deleteQuery(ids[i]);
+ }
+ }
+}
+
+GLboolean GL_APIENTRY IsQuery(GLuint id)
+{
+ EVENT("(GLuint id = %u)", id);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
+ }
+
+ return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
+ }
+
+ return GL_FALSE;
+}
+
+void GL_APIENTRY BeginQuery(GLenum target, GLuint id)
+{
+ EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateBeginQuery(context, target, id))
+ {
+ return;
+ }
+
+ Error error = context->beginQuery(target, id);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY EndQuery(GLenum target)
+{
+ EVENT("(GLenum target = 0x%X)", target);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateEndQuery(context, target))
+ {
+ return;
+ }
+
+ Error error = context->endQuery(target);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint* params)
+{
+ EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidQueryType(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_CURRENT_QUERY:
+ params[0] = static_cast<GLint>(context->getState().getActiveQueryId(target));
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
+{
+ EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ Query *queryObject = context->getQuery(id, false, GL_NONE);
+
+ if (!queryObject)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (context->getState().getActiveQueryId(queryObject->getType()) == id)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ switch(pname)
+ {
+ case GL_QUERY_RESULT_EXT:
+ {
+ Error error = queryObject->getResult(params);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+ break;
+
+ case GL_QUERY_RESULT_AVAILABLE_EXT:
+ {
+ Error error = queryObject->isResultAvailable(params);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+GLboolean GL_APIENTRY UnmapBuffer(GLenum target)
+{
+ EVENT("(GLenum target = 0x%X)", target);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
+ }
+
+ return UnmapBufferOES(target);
+ }
+
+ return GL_FALSE;
+}
+
+void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
+{
+ EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ GetBufferPointervOES(target, pname, params);
+ }
+}
+
+void GL_APIENTRY DrawBuffers(GLsizei n, const GLenum* bufs)
+{
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ DrawBuffersEXT(n, bufs);
+ }
+}
+
+void GL_APIENTRY UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
+ location, count, transpose, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniformMatrix2x3fv(location, count, transpose, value);
+ }
+}
+
+void GL_APIENTRY UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
+ location, count, transpose, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniformMatrix3x2fv(location, count, transpose, value);
+ }
+}
+
+void GL_APIENTRY UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
+ location, count, transpose, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniformMatrix2x4fv(location, count, transpose, value);
+ }
+}
+
+void GL_APIENTRY UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
+ location, count, transpose, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniformMatrix4x2fv(location, count, transpose, value);
+ }
+}
+
+void GL_APIENTRY UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
+ location, count, transpose, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniformMatrix3x4fv(location, count, transpose, value);
+ }
+}
+
+void GL_APIENTRY UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
+ location, count, transpose, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniformMatrix4x3fv(location, count, transpose, value);
+ }
+}
+
+void GL_APIENTRY BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
+{
+ EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = %d, "
+ "GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
+ srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1, mask, filter,
+ false))
+ {
+ return;
+ }
+
+ Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
+ ASSERT(readFramebuffer);
+
+ Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
+ ASSERT(drawFramebuffer);
+
+ Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
+ Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
+
+ Error error = drawFramebuffer->blit(context->getState(), srcArea, dstArea, mask, filter, readFramebuffer);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+ target, samples, internalformat, width, height);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateES3RenderbufferStorageParameters(context, target, samples, internalformat, width, height))
+ {
+ return;
+ }
+
+ Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
+ renderbuffer->setStorageMultisample(samples, internalformat, width, height);
+ }
+}
+
+void GL_APIENTRY FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
+{
+ EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)",
+ target, attachment, texture, level, layer);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateFramebufferTextureLayer(context, target, attachment, texture,
+ level, layer))
+ {
+ return;
+ }
+
+ Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (texture != 0)
+ {
+ Texture *textureObject = context->getTexture(texture);
+
+ ImageIndex index = ImageIndex::MakeInvalid();
+
+ if (textureObject->getTarget() == GL_TEXTURE_3D)
+ {
+ index = ImageIndex::Make3D(level, layer);
+ }
+ else
+ {
+ ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY);
+ index = ImageIndex::Make2DArray(level, layer);
+ }
+
+ framebuffer->setTextureAttachment(attachment, textureObject, index);
+ }
+ else
+ {
+ framebuffer->setNULLAttachment(attachment);
+ }
+ }
+}
+
+GLvoid *GL_APIENTRY MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
+{
+ EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
+ target, offset, length, access);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return NULL;
+ }
+
+ return MapBufferRangeEXT(target, offset, length, access);
+ }
+
+ return NULL;
+}
+
+void GL_APIENTRY FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
+{
+ EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ FlushMappedBufferRangeEXT(target, offset, length);
+ }
+}
+
+void GL_APIENTRY BindVertexArray(GLuint array)
+{
+ EVENT("(GLuint array = %u)", array);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ VertexArray *vao = context->getVertexArray(array);
+
+ if (!vao)
+ {
+ // The default VAO should always exist
+ ASSERT(array != 0);
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ context->bindVertexArray(array);
+ }
+}
+
+void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint* arrays)
+{
+ EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
+ {
+ if (arrays[arrayIndex] != 0)
+ {
+ context->deleteVertexArray(arrays[arrayIndex]);
+ }
+ }
+ }
+}
+
+void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint* arrays)
+{
+ EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (n < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
+ {
+ arrays[arrayIndex] = context->createVertexArray();
+ }
+ }
+}
+
+GLboolean GL_APIENTRY IsVertexArray(GLuint array)
+{
+ EVENT("(GLuint array = %u)", array);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
+ }
+
+ if (array == 0)
+ {
+ return GL_FALSE;
+ }
+
+ VertexArray *vao = context->getVertexArray(array);
+
+ return (vao != NULL ? GL_TRUE : GL_FALSE);
+ }
+
+ return GL_FALSE;
+}
+
+void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint* data)
+{
+ EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)",
+ target, index, data);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ const Caps &caps = context->getCaps();
+ switch (target)
+ {
+ case GL_TRANSFORM_FEEDBACK_BUFFER_START:
+ case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
+ case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ if (index >= caps.maxTransformFeedbackSeparateAttributes)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ case GL_UNIFORM_BUFFER_START:
+ case GL_UNIFORM_BUFFER_SIZE:
+ case GL_UNIFORM_BUFFER_BINDING:
+ if (index >= caps.maxCombinedUniformBlocks)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (!(context->getIndexedIntegerv(target, index, data)))
+ {
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (numParams == 0)
+ {
+ return; // it is known that pname is valid, but there are no parameters to return
+ }
+
+ if (nativeType == GL_INT_64_ANGLEX)
+ {
+ GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<int>::min());
+ GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<int>::max());
+ GLint64 *int64Params = new GLint64[numParams];
+
+ context->getIndexedInteger64v(target, index, int64Params);
+
+ for (unsigned int i = 0; i < numParams; ++i)
+ {
+ GLint64 clampedValue = std::max(std::min(int64Params[i], maxIntValue), minIntValue);
+ data[i] = static_cast<GLint>(clampedValue);
+ }
+
+ delete [] int64Params;
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+ }
+}
+
+void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode)
+{
+ EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ switch (primitiveMode)
+ {
+ case GL_TRIANGLES:
+ case GL_LINES:
+ case GL_POINTS:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ ASSERT(transformFeedback != NULL);
+
+ if (transformFeedback->isStarted())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (transformFeedback->isPaused())
+ {
+ transformFeedback->resume();
+ }
+ else
+ {
+ transformFeedback->start(primitiveMode);
+ }
+ }
+}
+
+void GL_APIENTRY EndTransformFeedback(void)
+{
+ EVENT("(void)");
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ ASSERT(transformFeedback != NULL);
+
+ if (!transformFeedback->isStarted())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ transformFeedback->stop();
+ }
+}
+
+void GL_APIENTRY BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+{
+ EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)",
+ target, index, buffer, offset, size);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ const Caps &caps = context->getCaps();
+ switch (target)
+ {
+ case GL_TRANSFORM_FEEDBACK_BUFFER:
+ if (index >= caps.maxTransformFeedbackSeparateAttributes)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ case GL_UNIFORM_BUFFER:
+ if (index >= caps.maxUniformBufferBindings)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (buffer != 0 && size <= 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ switch (target)
+ {
+ case GL_TRANSFORM_FEEDBACK_BUFFER:
+ {
+ // size and offset must be a multiple of 4
+ if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ // Cannot bind a transform feedback buffer if the current transform feedback is active (3.0.4 pg 91 section 2.15.2)
+ TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback();
+ if (curTransformFeedback && curTransformFeedback->isStarted())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
+ context->bindGenericTransformFeedbackBuffer(buffer);
+ break;
+ }
+
+ case GL_UNIFORM_BUFFER:
+
+ // it is an error to bind an offset not a multiple of the alignment
+ if (buffer != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->bindIndexedUniformBuffer(buffer, index, offset, size);
+ context->bindGenericUniformBuffer(buffer);
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+ }
+}
+
+void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer)
+{
+ EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)",
+ target, index, buffer);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ const Caps &caps = context->getCaps();
+ switch (target)
+ {
+ case GL_TRANSFORM_FEEDBACK_BUFFER:
+ if (index >= caps.maxTransformFeedbackSeparateAttributes)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ case GL_UNIFORM_BUFFER:
+ if (index >= caps.maxUniformBufferBindings)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ switch (target)
+ {
+ case GL_TRANSFORM_FEEDBACK_BUFFER:
+ {
+ // Cannot bind a transform feedback buffer if the current transform feedback is active (3.0.4 pg 91 section 2.15.2)
+ TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback();
+ if (curTransformFeedback && curTransformFeedback->isStarted())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0);
+ context->bindGenericTransformFeedbackBuffer(buffer);
+ break;
+ }
+ case GL_UNIFORM_BUFFER:
+ context->bindIndexedUniformBuffer(buffer, index, 0, 0);
+ context->bindGenericUniformBuffer(buffer);
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+ }
+}
+
+void GL_APIENTRY TransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
+{
+ EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)",
+ program, count, varyings, bufferMode);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (count < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ const Caps &caps = context->getCaps();
+ switch (bufferMode)
+ {
+ case GL_INTERLEAVED_ATTRIBS:
+ break;
+ case GL_SEPARATE_ATTRIBS:
+ if (static_cast<GLuint>(count) > caps.maxTransformFeedbackSeparateAttributes)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (!ValidProgram(context, program))
+ {
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+ ASSERT(programObject);
+
+ programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
+ }
+}
+
+void GL_APIENTRY GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
+{
+ EVENT("(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, "
+ "GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
+ program, index, bufSize, length, size, type, name);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (bufSize < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (!ValidProgram(context, program))
+ {
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+ ASSERT(programObject);
+
+ if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
+ }
+}
+
+void GL_APIENTRY VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
+{
+ EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)",
+ index, size, type, stride, pointer);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (size < 1 || size > 4)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ switch (type)
+ {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (stride < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // [OpenGL ES 3.0.2] Section 2.8 page 24:
+ // An INVALID_OPERATION error is generated when a non-zero vertex array object
+ // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
+ // and the pointer argument is not NULL.
+ if (context->getState().getVertexArray()->id() != 0 && context->getState().getArrayBufferId() == 0 && pointer != NULL)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type, false, true,
+ stride, pointer);
+ }
+}
+
+void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
+{
+ EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
+ index, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (!ValidateGetVertexAttribParameters(context, pname))
+ {
+ return;
+ }
+
+ if (pname == GL_CURRENT_VERTEX_ATTRIB)
+ {
+ const VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
+ for (int i = 0; i < 4; ++i)
+ {
+ params[i] = currentValueData.IntValues[i];
+ }
+ }
+ else
+ {
+ const VertexAttribute &attribState = context->getState().getVertexArray()->getVertexAttribute(index);
+ *params = QuerySingleVertexAttributeParameter<GLint>(attribState, pname);
+ }
+ }
+}
+
+void GL_APIENTRY GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
+{
+ EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)",
+ index, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (!ValidateGetVertexAttribParameters(context, pname))
+ {
+ return;
+ }
+
+ if (pname == GL_CURRENT_VERTEX_ATTRIB)
+ {
+ const VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
+ for (int i = 0; i < 4; ++i)
+ {
+ params[i] = currentValueData.UnsignedIntValues[i];
+ }
+ }
+ else
+ {
+ const VertexAttribute &attribState = context->getState().getVertexArray()->getVertexAttribute(index);
+ *params = QuerySingleVertexAttributeParameter<GLuint>(attribState, pname);
+ }
+ }
+}
+
+void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+{
+ EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
+ index, x, y, z, w);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ GLint vals[4] = { x, y, z, w };
+ context->getState().setVertexAttribi(index, vals);
+ }
+}
+
+void GL_APIENTRY VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+{
+ EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)",
+ index, x, y, z, w);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ GLuint vals[4] = { x, y, z, w };
+ context->getState().setVertexAttribu(index, vals);
+ }
+}
+
+void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint* v)
+{
+ EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->getState().setVertexAttribi(index, v);
+ }
+}
+
+void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint* v)
+{
+ EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->getState().setVertexAttribu(index, v);
+ }
+}
+
+void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint* params)
+{
+ EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)",
+ program, location, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateGetUniformuiv(context, program, location, params))
+ {
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+ ASSERT(programObject);
+
+ programObject->getUniformuiv(location, params);
+ }
+}
+
+GLint GL_APIENTRY GetFragDataLocation(GLuint program, const GLchar *name)
+{
+ EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)",
+ program, name);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return -1;
+ }
+
+ if (program == 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return -1;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject || !programObject->isLinked())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return -1;
+ }
+
+ return programObject->getFragDataLocation(name);
+ }
+
+ return 0;
+}
+
+void GL_APIENTRY Uniform1ui(GLint location, GLuint v0)
+{
+ Uniform1uiv(location, 1, &v0);
+}
+
+void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1)
+{
+ const GLuint xy[] = { v0, v1 };
+ Uniform2uiv(location, 1, xy);
+}
+
+void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ const GLuint xyz[] = { v0, v1, v2 };
+ Uniform3uiv(location, 1, xyz);
+}
+
+void GL_APIENTRY Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ const GLuint xyzw[] = { v0, v1, v2, v3 };
+ Uniform4uiv(location, 1, xyzw);
+}
+
+void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
+ location, count, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform1uiv(location, count, value);
+ }
+}
+
+void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
+ location, count, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform2uiv(location, count, value);
+ }
+}
+
+void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)",
+ location, count, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform3uiv(location, count, value);
+ }
+}
+
+void GL_APIENTRY Uniform4uiv(GLint location, GLsizei count, const GLuint* value)
+{
+ EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
+ location, count, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC4, location, count))
+ {
+ return;
+ }
+
+ Program *program = context->getState().getProgram();
+ program->setUniform4uiv(location, count, value);
+ }
+}
+
+void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value)
+{
+ EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint* value = 0x%0.8p)",
+ buffer, drawbuffer, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateClearBuffer(context))
+ {
+ return;
+ }
+
+ switch (buffer)
+ {
+ case GL_COLOR:
+ if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ case GL_STENCIL:
+ if (drawbuffer != 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
+ ASSERT(framebufferObject);
+
+ Error error = framebufferObject->clearBufferiv(context->getState(), buffer, drawbuffer, value);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value)
+{
+ EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint* value = 0x%0.8p)",
+ buffer, drawbuffer, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateClearBuffer(context))
+ {
+ return;
+ }
+
+ switch (buffer)
+ {
+ case GL_COLOR:
+ if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
+ ASSERT(framebufferObject);
+
+ Error error = framebufferObject->clearBufferuiv(context->getState(), buffer, drawbuffer, value);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value)
+{
+ EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat* value = 0x%0.8p)",
+ buffer, drawbuffer, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateClearBuffer(context))
+ {
+ return;
+ }
+
+ switch (buffer)
+ {
+ case GL_COLOR:
+ if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ case GL_DEPTH:
+ if (drawbuffer != 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
+ ASSERT(framebufferObject);
+
+ Error error = framebufferObject->clearBufferfv(context->getState(), buffer, drawbuffer, value);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+{
+ EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth, GLint stencil = %d)",
+ buffer, drawbuffer, depth, stencil);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (!ValidateClearBuffer(context))
+ {
+ return;
+ }
+
+ switch (buffer)
+ {
+ case GL_DEPTH_STENCIL:
+ if (drawbuffer != 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
+ ASSERT(framebufferObject);
+
+ Error error = framebufferObject->clearBufferfi(context->getState(), buffer, drawbuffer, depth, stencil);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index)
+{
+ EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return NULL;
+ }
+
+ if (name != GL_EXTENSIONS)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return NULL;
+ }
+
+ if (index >= context->getExtensionStringCount())
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return NULL;
+ }
+
+ return reinterpret_cast<const GLubyte*>(context->getExtensionString(index).c_str());
+ }
+
+ return NULL;
+}
+
+void GL_APIENTRY CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
+{
+ EVENT("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)",
+ readTarget, writeTarget, readOffset, writeOffset, size);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidBufferTarget(context, readTarget) || !ValidBufferTarget(context, writeTarget))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Buffer *readBuffer = context->getState().getTargetBuffer(readTarget);
+ Buffer *writeBuffer = context->getState().getTargetBuffer(writeTarget);
+
+ if (!readBuffer || !writeBuffer)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // Verify that readBuffer and writeBuffer are not currently mapped
+ if (readBuffer->isMapped() || writeBuffer->isMapped())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (readOffset < 0 || writeOffset < 0 || size < 0 ||
+ static_cast<unsigned int>(readOffset + size) > readBuffer->getSize() ||
+ static_cast<unsigned int>(writeOffset + size) > writeBuffer->getSize())
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (readBuffer == writeBuffer && std::abs(readOffset - writeOffset) < size)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ // if size is zero, the copy is a successful no-op
+ if (size > 0)
+ {
+ Error error = writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+ }
+}
+
+void GL_APIENTRY GetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices)
+{
+ EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLchar* const* uniformNames = 0x%0.8p, GLuint* uniformIndices = 0x%0.8p)",
+ program, uniformCount, uniformNames, uniformIndices);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (uniformCount < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ 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 GL_APIENTRY GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params)
+{
+ EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLuint* uniformIndices = 0x%0.8p, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
+ program, uniformCount, uniformIndices, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (uniformCount < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ switch (pname)
+ {
+ case GL_UNIFORM_TYPE:
+ case GL_UNIFORM_SIZE:
+ case GL_UNIFORM_NAME_LENGTH:
+ 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->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (uniformCount > programObject->getActiveUniformCount())
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+ {
+ const GLuint index = uniformIndices[uniformId];
+
+ if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+ {
+ const GLuint index = uniformIndices[uniformId];
+ params[uniformId] = programObject->getActiveUniformi(index, pname);
+ }
+ }
+}
+
+GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName)
+{
+ EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_INVALID_INDEX;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_INVALID_INDEX;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return GL_INVALID_INDEX;
+ }
+ }
+
+ return programObject->getUniformBlockIndex(uniformBlockName);
+ }
+
+ return 0;
+}
+
+void GL_APIENTRY GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params)
+{
+ EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
+ program, uniformBlockIndex, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_UNIFORM_BLOCK_BINDING:
+ *params = static_cast<GLint>(programObject->getUniformBlockBinding(uniformBlockIndex));
+ break;
+
+ 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:
+ programObject->getActiveUniformBlockiv(uniformBlockIndex, pname, params);
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName)
+{
+ EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* uniformBlockName = 0x%0.8p)",
+ program, uniformBlockIndex, bufSize, length, uniformBlockName);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
+ }
+}
+
+void GL_APIENTRY UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
+{
+ EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)",
+ program, uniformBlockIndex, uniformBlockBinding);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Program *programObject = context->getProgram(program);
+
+ if (!programObject)
+ {
+ if (context->getShader(program))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+ else
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ }
+
+ // if never linked, there won't be any uniform blocks
+ if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
+ }
+}
+
+void GL_APIENTRY DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
+{
+ EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
+ mode, first, count, instanceCount);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateDrawArraysInstanced(context, mode, first, count, instanceCount))
+ {
+ return;
+ }
+
+ Error error = context->drawArrays(mode, first, count, instanceCount);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount)
+{
+ EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei instanceCount = %d)",
+ mode, count, type, indices, instanceCount);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ rx::RangeUI indexRange;
+ if (!ValidateDrawElementsInstanced(context, mode, count, type, indices, instanceCount, &indexRange))
+ {
+ return;
+ }
+
+ Error error = context->drawElements(mode, count, type, indices, instanceCount, indexRange);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+GLsync GL_APIENTRY FenceSync_(GLenum condition, GLbitfield flags)
+{
+ EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return 0;
+ }
+
+ if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return 0;
+ }
+
+ if (flags != 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return 0;
+ }
+
+ GLsync fenceSync = context->createFenceSync();
+
+ FenceSync *fenceSyncObject = context->getFenceSync(fenceSync);
+ Error error = fenceSyncObject->set(condition);
+ if (error.isError())
+ {
+ context->deleteFenceSync(fenceSync);
+ context->recordError(error);
+ return NULL;
+ }
+
+ return fenceSync;
+ }
+
+ return NULL;
+}
+
+GLboolean GL_APIENTRY IsSync(GLsync sync)
+{
+ EVENT("(GLsync sync = 0x%0.8p)", sync);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
+ }
+
+ return (context->getFenceSync(sync) != NULL);
+ }
+
+ return GL_FALSE;
+}
+
+void GL_APIENTRY DeleteSync(GLsync sync)
+{
+ EVENT("(GLsync sync = 0x%0.8p)", sync);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (sync != static_cast<GLsync>(0) && !context->getFenceSync(sync))
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->deleteFenceSync(sync);
+ }
+}
+
+GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
+ sync, flags, timeout);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_WAIT_FAILED;
+ }
+
+ if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return GL_WAIT_FAILED;
+ }
+
+ FenceSync *fenceSync = context->getFenceSync(sync);
+
+ if (!fenceSync)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return GL_WAIT_FAILED;
+ }
+
+ GLenum result = GL_WAIT_FAILED;
+ Error error = fenceSync->clientWait(flags, timeout, &result);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return GL_WAIT_FAILED;
+ }
+
+ return result;
+ }
+
+ return GL_FALSE;
+}
+
+void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
+ sync, flags, timeout);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (flags != 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ if (timeout != GL_TIMEOUT_IGNORED)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ FenceSync *fenceSync = context->getFenceSync(sync);
+
+ if (!fenceSync)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ Error error = fenceSync->serverWait(flags, timeout);
+ if (error.isError())
+ {
+ context->recordError(error);
+ }
+ }
+}
+
+void GL_APIENTRY GetInteger64v(GLenum pname, GLint64* params)
+{
+ EVENT("(GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
+ pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
+ {
+ return;
+ }
+
+ if (nativeType == GL_INT_64_ANGLEX)
+ {
+ context->getInteger64v(pname, params);
+ }
+ else
+ {
+ CastStateValues(context, nativeType, pname, numParams, params);
+ }
+ }
+}
+
+void GL_APIENTRY GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values)
+{
+ EVENT("(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLint* values = 0x%0.8p)",
+ sync, pname, bufSize, length, values);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (bufSize < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ FenceSync *fenceSync = context->getFenceSync(sync);
+
+ if (!fenceSync)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_OBJECT_TYPE: values[0] = static_cast<GLint>(GL_SYNC_FENCE); break;
+ case GL_SYNC_CONDITION: values[0] = static_cast<GLint>(fenceSync->getCondition()); break;
+ case GL_SYNC_FLAGS: values[0] = 0; break;
+
+ case GL_SYNC_STATUS:
+ {
+ Error error = fenceSync->getStatus(values);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ break;
+ }
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64* data)
+{
+ EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64* data = 0x%0.8p)",
+ target, index, data);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ const Caps &caps = context->getCaps();
+ switch (target)
+ {
+ case GL_TRANSFORM_FEEDBACK_BUFFER_START:
+ case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
+ case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ if (index >= caps.maxTransformFeedbackSeparateAttributes)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ case GL_UNIFORM_BUFFER_START:
+ case GL_UNIFORM_BUFFER_SIZE:
+ case GL_UNIFORM_BUFFER_BINDING:
+ if (index >= caps.maxUniformBufferBindings)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (!(context->getIndexedInteger64v(target, index, data)))
+ {
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (numParams == 0)
+ return; // it is known that pname is valid, but there are no parameters to return
+
+ if (nativeType == GL_INT)
+ {
+ GLint *intParams = new GLint[numParams];
+
+ context->getIndexedIntegerv(target, index, intParams);
+
+ for (unsigned int i = 0; i < numParams; ++i)
+ {
+ data[i] = static_cast<GLint64>(intParams[i]);
+ }
+
+ delete [] intParams;
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+ }
+}
+
+void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params)
+{
+ EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
+ target, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidBufferTarget(context, target))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (!ValidBufferParameter(context, pname))
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (!buffer)
+ {
+ // A null buffer means that "0" is bound to the requested buffer target
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_BUFFER_USAGE:
+ *params = static_cast<GLint64>(buffer->getUsage());
+ break;
+ case GL_BUFFER_SIZE:
+ *params = buffer->getSize();
+ break;
+ case GL_BUFFER_ACCESS_FLAGS:
+ *params = static_cast<GLint64>(buffer->getAccessFlags());
+ break;
+ case GL_BUFFER_MAPPED:
+ *params = static_cast<GLint64>(buffer->isMapped());
+ break;
+ case GL_BUFFER_MAP_OFFSET:
+ *params = buffer->getMapOffset();
+ break;
+ case GL_BUFFER_MAP_LENGTH:
+ *params = buffer->getMapLength();
+ break;
+ default: UNREACHABLE(); break;
+ }
+ }
+}
+
+void GL_APIENTRY GenSamplers(GLsizei count, GLuint* samplers)
+{
+ EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (count < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ samplers[i] = context->createSampler();
+ }
+ }
+}
+
+void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint* samplers)
+{
+ EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (count < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ context->deleteSampler(samplers[i]);
+ }
+ }
+}
+
+GLboolean GL_APIENTRY IsSampler(GLuint sampler)
+{
+ EVENT("(GLuint sampler = %u)", sampler);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
+ }
+
+ return context->isSampler(sampler);
+ }
+
+ return GL_FALSE;
+}
+
+void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler)
+{
+ EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (sampler != 0 && !context->isSampler(sampler))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (unit >= context->getCaps().maxCombinedTextureImageUnits)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->bindSampler(unit, sampler);
+ }
+}
+
+void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+{
+ EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateSamplerObjectParameter(context, pname))
+ {
+ return;
+ }
+
+ if (!ValidateTexParamParameters(context, pname, param))
+ {
+ return;
+ }
+
+ if (!context->isSampler(sampler))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ context->samplerParameteri(sampler, pname, param);
+ }
+}
+
+void GL_APIENTRY SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param)
+{
+ SamplerParameteri(sampler, pname, *param);
+}
+
+void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+{
+ EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateSamplerObjectParameter(context, pname))
+ {
+ return;
+ }
+
+ if (!ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
+ {
+ return;
+ }
+
+ if (!context->isSampler(sampler))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ context->samplerParameterf(sampler, pname, param);
+ }
+}
+
+void GL_APIENTRY SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param)
+{
+ SamplerParameterf(sampler, pname, *param);
+}
+
+void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params)
+{
+ EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateSamplerObjectParameter(context, pname))
+ {
+ return;
+ }
+
+ if (!context->isSampler(sampler))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ *params = context->getSamplerParameteri(sampler, pname);
+ }
+}
+
+void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
+{
+ EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateSamplerObjectParameter(context, pname))
+ {
+ return;
+ }
+
+ if (!context->isSampler(sampler))
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ *params = context->getSamplerParameterf(sampler, pname);
+ }
+}
+
+void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor)
+{
+ EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (index >= MAX_VERTEX_ATTRIBS)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ context->setVertexAttribDivisor(index, divisor);
+ }
+}
+
+void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id)
+{
+ EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ 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)
+ TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback();
+ if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section 2.14.1)
+ if (context->getTransformFeedback(id) == NULL)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ context->bindTransformFeedback(id);
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
+{
+ EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ context->deleteTransformFeedback(ids[i]);
+ }
+ }
+}
+
+void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint* ids)
+{
+ EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ for (int i = 0; i < n; i++)
+ {
+ ids[i] = context->createTransformFeedback();
+ }
+ }
+}
+
+GLboolean GL_APIENTRY IsTransformFeedback(GLuint id)
+{
+ EVENT("(GLuint id = %u)", id);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return GL_FALSE;
+ }
+
+ return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE);
+ }
+
+ return GL_FALSE;
+}
+
+void GL_APIENTRY PauseTransformFeedback(void)
+{
+ EVENT("(void)");
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ ASSERT(transformFeedback != NULL);
+
+ // Current transform feedback must be started and not paused in order to pause (3.0.2 pg 86)
+ if (!transformFeedback->isStarted() || transformFeedback->isPaused())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ transformFeedback->pause();
+ }
+}
+
+void GL_APIENTRY ResumeTransformFeedback(void)
+{
+ EVENT("(void)");
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ ASSERT(transformFeedback != NULL);
+
+ // Current transform feedback must be started and paused in order to resume (3.0.2 pg 86)
+ if (!transformFeedback->isStarted() || !transformFeedback->isPaused())
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ transformFeedback->resume();
+ }
+}
+
+void GL_APIENTRY GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)
+{
+ EVENT("(GLuint program = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLenum* binaryFormat = 0x%0.8p, GLvoid* binary = 0x%0.8p)",
+ program, bufSize, length, binaryFormat, binary);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // TODO: Pipe through to the OES extension for now, needs proper validation
+ return GetProgramBinaryOES(program, bufSize, length, binaryFormat, binary);
+ }
+}
+
+void GL_APIENTRY ProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length)
+{
+ EVENT("(GLuint program = %u, GLenum binaryFormat = 0x%X, const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
+ program, binaryFormat, binary, length);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // TODO: Pipe through to the OES extension for now, needs proper validation
+ return ProgramBinaryOES(program, binaryFormat, binary, length);
+ }
+}
+
+void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value)
+{
+ EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)",
+ program, pname, value);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ // glProgramParameteri
+ UNIMPLEMENTED();
+ }
+}
+
+void GL_APIENTRY InvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments)
+{
+ EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p)",
+ target, numAttachments, attachments);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
+ {
+ return;
+ }
+
+ Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (framebuffer->checkStatus(context->getData()) == GL_FRAMEBUFFER_COMPLETE)
+ {
+ Error error = framebuffer->invalidate(numAttachments, attachments);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+ }
+}
+
+void GL_APIENTRY InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p, GLint x = %d, "
+ "GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
+ target, numAttachments, attachments, x, y, width, height);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
+ {
+ return;
+ }
+
+ Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (framebuffer->checkStatus(context->getData()) == GL_FRAMEBUFFER_COMPLETE)
+ {
+ Rectangle area(x, y, width, height);
+ Error error = framebuffer->invalidateSub(numAttachments, attachments, area);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+ }
+}
+
+void GL_APIENTRY TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+ target, levels, internalformat, width, height);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
+ {
+ return;
+ }
+
+ Extents size(width, height, 1);
+ Texture *texture = context->getTargetTexture(target);
+ Error error = texture->setStorage(target, levels, internalformat, size);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+{
+ EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
+ "GLsizei height = %d, GLsizei depth = %d)",
+ target, levels, internalformat, width, height, depth);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, depth))
+ {
+ return;
+ }
+
+ Extents size(width, height, depth);
+ Texture *texture = context->getTargetTexture(target);
+ Error error = texture->setStorage(target, levels, internalformat, size);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
+ }
+}
+
+void GL_APIENTRY GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
+{
+ EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, "
+ "GLint* params = 0x%0.8p)",
+ target, internalformat, pname, bufSize, params);
+
+ Context *context = GetValidGlobalContext();
+ if (context)
+ {
+ if (context->getClientVersion() < 3)
+ {
+ context->recordError(Error(GL_INVALID_OPERATION));
+ return;
+ }
+
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
+ if (!formatCaps.renderable)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (target != GL_RENDERBUFFER)
+ {
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+
+ if (bufSize < 0)
+ {
+ context->recordError(Error(GL_INVALID_VALUE));
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_NUM_SAMPLE_COUNTS:
+ if (bufSize != 0)
+ {
+ *params = formatCaps.sampleCounts.size();
+ }
+ break;
+
+ case GL_SAMPLES:
+ {
+ size_t returnCount = std::min<size_t>(bufSize, formatCaps.sampleCounts.size());
+ auto sampleReverseIt = formatCaps.sampleCounts.rbegin();
+ for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex)
+ {
+ params[sampleIndex] = *sampleReverseIt++;;
+ }
+ }
+ break;
+
+ default:
+ context->recordError(Error(GL_INVALID_ENUM));
+ return;
+ }
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.h b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.h
new file mode 100644
index 0000000000..09ca0e4641
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.h
@@ -0,0 +1,125 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_gles_3_0.h : Defines the GLES 3.0 entry points.
+
+#ifndef LIBGLESV2_ENTRYPOINTGLES30_H_
+#define LIBGLESV2_ENTRYPOINTGLES30_H_
+
+#include <GLES3/gl3.h>
+#include <export.h>
+
+namespace gl
+{
+
+ANGLE_EXPORT void GL_APIENTRY ReadBuffer(GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
+ANGLE_EXPORT void GL_APIENTRY TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+ANGLE_EXPORT void GL_APIENTRY TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+ANGLE_EXPORT void GL_APIENTRY CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+ANGLE_EXPORT void GL_APIENTRY CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+ANGLE_EXPORT void GL_APIENTRY GenQueries(GLsizei n, GLuint* ids);
+ANGLE_EXPORT void GL_APIENTRY DeleteQueries(GLsizei n, const GLuint* ids);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsQuery(GLuint id);
+ANGLE_EXPORT void GL_APIENTRY BeginQuery(GLenum target, GLuint id);
+ANGLE_EXPORT void GL_APIENTRY EndQuery(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint* params);
+ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params);
+ANGLE_EXPORT GLboolean GL_APIENTRY UnmapBuffer(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params);
+ANGLE_EXPORT void GL_APIENTRY DrawBuffers(GLsizei n, const GLenum* bufs);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ANGLE_EXPORT void GL_APIENTRY UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ANGLE_EXPORT void GL_APIENTRY 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 RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+ANGLE_EXPORT GLvoid* GL_APIENTRY MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+ANGLE_EXPORT void GL_APIENTRY FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
+ANGLE_EXPORT void GL_APIENTRY BindVertexArray(GLuint array);
+ANGLE_EXPORT void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint* arrays);
+ANGLE_EXPORT void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint* arrays);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsVertexArray(GLuint array);
+ANGLE_EXPORT void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint* data);
+ANGLE_EXPORT void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode);
+ANGLE_EXPORT void GL_APIENTRY EndTransformFeedback(void);
+ANGLE_EXPORT void GL_APIENTRY BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+ANGLE_EXPORT void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer);
+ANGLE_EXPORT void GL_APIENTRY TransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+ANGLE_EXPORT void GL_APIENTRY GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params);
+ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint* v);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint* v);
+ANGLE_EXPORT void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint* params);
+ANGLE_EXPORT GLint GL_APIENTRY GetFragDataLocation(GLuint program, const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY Uniform1ui(GLint location, GLuint v0);
+ANGLE_EXPORT void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1);
+ANGLE_EXPORT void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
+ANGLE_EXPORT void GL_APIENTRY Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ANGLE_EXPORT void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint* value);
+ANGLE_EXPORT void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint* value);
+ANGLE_EXPORT void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint* value);
+ANGLE_EXPORT void GL_APIENTRY Uniform4uiv(GLint location, GLsizei count, const GLuint* value);
+ANGLE_EXPORT void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value);
+ANGLE_EXPORT void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value);
+ANGLE_EXPORT void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value);
+ANGLE_EXPORT void GL_APIENTRY ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+ANGLE_EXPORT const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index);
+ANGLE_EXPORT void GL_APIENTRY CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+ANGLE_EXPORT void GL_APIENTRY GetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices);
+ANGLE_EXPORT void GL_APIENTRY GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+ANGLE_EXPORT GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName);
+ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+ANGLE_EXPORT void GL_APIENTRY UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+ANGLE_EXPORT void GL_APIENTRY DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+ANGLE_EXPORT void GL_APIENTRY DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount);
+ANGLE_EXPORT GLsync GL_APIENTRY FenceSync_(GLenum condition, GLbitfield flags);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsSync(GLsync sync);
+ANGLE_EXPORT void GL_APIENTRY DeleteSync(GLsync sync);
+ANGLE_EXPORT GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ANGLE_EXPORT void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ANGLE_EXPORT void GL_APIENTRY GetInteger64v(GLenum pname, GLint64* params);
+ANGLE_EXPORT void GL_APIENTRY GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
+ANGLE_EXPORT void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64* data);
+ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params);
+ANGLE_EXPORT void GL_APIENTRY GenSamplers(GLsizei count, GLuint* samplers);
+ANGLE_EXPORT void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint* samplers);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsSampler(GLuint sampler);
+ANGLE_EXPORT void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler);
+ANGLE_EXPORT void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param);
+ANGLE_EXPORT void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param);
+ANGLE_EXPORT void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params);
+ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params);
+ANGLE_EXPORT void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor);
+ANGLE_EXPORT void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id);
+ANGLE_EXPORT void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint* ids);
+ANGLE_EXPORT void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint* ids);
+ANGLE_EXPORT GLboolean GL_APIENTRY IsTransformFeedback(GLuint id);
+ANGLE_EXPORT void GL_APIENTRY PauseTransformFeedback(void);
+ANGLE_EXPORT void GL_APIENTRY ResumeTransformFeedback(void);
+ANGLE_EXPORT void GL_APIENTRY GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+ANGLE_EXPORT void GL_APIENTRY ProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
+ANGLE_EXPORT void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value);
+ANGLE_EXPORT void GL_APIENTRY InvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments);
+ANGLE_EXPORT void GL_APIENTRY InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ANGLE_EXPORT void GL_APIENTRY GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
+
+}
+
+#endif // LIBGLESV2_ENTRYPOINTGLES30_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.cpp
new file mode 100644
index 0000000000..6f6983fd91
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.cpp
@@ -0,0 +1,14 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_gles_3_0_ext.cpp : Implements the GLES 3.0 extension entry points.
+
+#include "libGLESv2/entry_points_gles_3_0_ext.h"
+#include "libGLESv2/global_state.h"
+
+namespace gl
+{
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.h b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.h
new file mode 100644
index 0000000000..fec4c1298a
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.h
@@ -0,0 +1,23 @@
+//
+// Copyright(c) 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.
+//
+
+// entry_points_gles_3_0_ext.h : Defines the GLES 3.0 extension entry points.
+
+#ifndef LIBGLESV2_ENTRYPOINTGLES30EXT_H_
+#define LIBGLESV2_ENTRYPOINTGLES30EXT_H_
+
+#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
+#include <export.h>
+
+namespace gl
+{
+
+// No GLES 3.0 extensions yet
+
+}
+
+#endif // LIBGLESV2_ENTRYPOINTGLES30EXT_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/formatutils.h b/src/3rdparty/angle/src/libGLESv2/formatutils.h
deleted file mode 100644
index 25106a52e5..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/formatutils.h
+++ /dev/null
@@ -1,106 +0,0 @@
-//
-// Copyright (c) 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 LIBGLESV2_FORMATUTILS_H_
-#define LIBGLESV2_FORMATUTILS_H_
-
-#include "libGLESv2/Caps.h"
-#include "libGLESv2/angletypes.h"
-
-#include "angle_gl.h"
-
-#include <cstddef>
-#include <cstdint>
-
-typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
- const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
- uint8_t *destData, size_t destRowPitch, size_t destDepthPitch);
-
-typedef void (*LoadImageFunction)(size_t width, size_t height, size_t depth,
- const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch,
- uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
-
-typedef void (*InitializeTextureDataFunction)(size_t width, size_t height, size_t depth,
- uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch);
-
-typedef void (*ColorReadFunction)(const uint8_t *source, uint8_t *dest);
-typedef void (*ColorWriteFunction)(const uint8_t *source, uint8_t *dest);
-typedef void (*ColorCopyFunction)(const uint8_t *source, uint8_t *dest);
-
-typedef void (*VertexCopyFunction)(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
-
-namespace gl
-{
-
-struct FormatType
-{
- FormatType();
-
- GLenum internalFormat;
- ColorWriteFunction colorWriteFunction;
-};
-const FormatType &GetFormatTypeInfo(GLenum format, GLenum type);
-
-struct Type
-{
- Type();
-
- GLuint bytes;
- bool specialInterpretation;
-};
-const Type &GetTypeInfo(GLenum type);
-
-struct InternalFormat
-{
- InternalFormat();
-
- 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;
-
- GLenum format;
- GLenum type;
-
- GLenum componentType;
- GLenum colorEncoding;
-
- typedef bool (*SupportCheckFunction)(GLuint, const Extensions &);
- SupportCheckFunction textureSupport;
- SupportCheckFunction renderSupport;
- SupportCheckFunction filterSupport;
-
- GLuint computeRowPitch(GLenum type, GLsizei width, GLint alignment) const;
- GLuint computeDepthPitch(GLenum type, GLsizei width, GLsizei height, GLint alignment) const;
- GLuint computeBlockSize(GLenum type, GLsizei width, GLsizei height) const;
-};
-const InternalFormat &GetInternalFormatInfo(GLenum internalFormat);
-
-GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);
-
-typedef std::set<GLenum> FormatSet;
-const FormatSet &GetAllSizedInternalFormats();
-
-}
-
-#endif // LIBGLESV2_FORMATUTILS_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/global_state.cpp b/src/3rdparty/angle/src/libGLESv2/global_state.cpp
new file mode 100644
index 0000000000..686f0bf49b
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/global_state.cpp
@@ -0,0 +1,235 @@
+//
+// Copyright(c) 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 "libANGLE/Context.h"
+#include "libANGLE/Error.h"
+
+#include "common/debug.h"
+#include "common/platform.h"
+#include "common/tls.h"
+
+namespace
+{
+
+static TLSIndex currentTLS = TLS_INVALID_INDEX;
+
+struct Current
+{
+ EGLint error;
+ EGLenum API;
+ egl::Display *display;
+ egl::Surface *drawSurface;
+ egl::Surface *readSurface;
+ gl::Context *context;
+};
+
+Current *AllocateCurrent()
+{
+ ASSERT(currentTLS != TLS_INVALID_INDEX);
+ if (currentTLS == TLS_INVALID_INDEX)
+ {
+ return NULL;
+ }
+
+ Current *current = new Current();
+ current->error = EGL_SUCCESS;
+ current->API = EGL_OPENGL_ES_API;
+ current->display = reinterpret_cast<egl::Display*>(EGL_NO_DISPLAY);
+ current->drawSurface = reinterpret_cast<egl::Surface*>(EGL_NO_SURFACE);
+ current->readSurface = reinterpret_cast<egl::Surface*>(EGL_NO_SURFACE);
+ current->context = reinterpret_cast<gl::Context*>(EGL_NO_CONTEXT);
+
+ if (!SetTLSValue(currentTLS, current))
+ {
+ ERR("Could not set thread local storage.");
+ return NULL;
+ }
+
+ return current;
+}
+
+void DeallocateCurrent()
+{
+ Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
+ SafeDelete(current);
+ SetTLSValue(currentTLS, NULL);
+}
+
+Current *GetCurrentData()
+{
+ // Create a TLS index if one has not been created for this DLL
+ if (currentTLS == TLS_INVALID_INDEX)
+ {
+ currentTLS = CreateTLSIndex();
+ }
+
+ Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
+
+ // ANGLE issue 488: when the dll is loaded after thread initialization,
+ // thread local storage (current) might not exist yet.
+ return (current ? current : AllocateCurrent());
+}
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
+{
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ currentTLS = CreateTLSIndex();
+ if (currentTLS == TLS_INVALID_INDEX)
+ {
+ return FALSE;
+ }
+ AllocateCurrent();
+ break;
+
+ case DLL_THREAD_ATTACH:
+ AllocateCurrent();
+ break;
+
+ case DLL_THREAD_DETACH:
+ DeallocateCurrent();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ DeallocateCurrent();
+ if (currentTLS != TLS_INVALID_INDEX)
+ {
+ DestroyTLSIndex(currentTLS);
+ currentTLS = TLS_INVALID_INDEX;
+ }
+ break;
+ }
+
+ return TRUE;
+}
+#endif
+
+}
+
+namespace gl
+{
+
+Context *GetGlobalContext()
+{
+ Current *current = GetCurrentData();
+
+ return current->context;
+}
+
+Context *GetValidGlobalContext()
+{
+ gl::Context *context = GetGlobalContext();
+ if (context)
+ {
+ if (context->isContextLost())
+ {
+ context->recordError(gl::Error(GL_OUT_OF_MEMORY, "Context has been lost."));
+ return nullptr;
+ }
+ else
+ {
+ return context;
+ }
+ }
+ return nullptr;
+}
+
+}
+
+namespace egl
+{
+
+void SetGlobalError(const Error &error)
+{
+ Current *current = GetCurrentData();
+
+ current->error = error.getCode();
+}
+
+EGLint GetGlobalError()
+{
+ Current *current = GetCurrentData();
+
+ return current->error;
+}
+
+EGLenum GetGlobalAPI()
+{
+ Current *current = GetCurrentData();
+
+ return current->API;
+}
+
+void SetGlobalAPI(EGLenum API)
+{
+ Current *current = GetCurrentData();
+
+ current->API = API;
+}
+
+void SetGlobalDisplay(Display *dpy)
+{
+ Current *current = GetCurrentData();
+
+ current->display = dpy;
+}
+
+Display *GetGlobalDisplay()
+{
+ Current *current = GetCurrentData();
+
+ return current->display;
+}
+
+void SetGlobalDrawSurface(Surface *surface)
+{
+ Current *current = GetCurrentData();
+
+ current->drawSurface = surface;
+}
+
+Surface *GetGlobalDrawSurface()
+{
+ Current *current = GetCurrentData();
+
+ return current->drawSurface;
+}
+
+void SetGlobalReadSurface(Surface *surface)
+{
+ Current *current = GetCurrentData();
+
+ current->readSurface = surface;
+}
+
+Surface *GetGlobalReadSurface()
+{
+ Current *current = GetCurrentData();
+
+ return current->readSurface;
+}
+
+void SetGlobalContext(gl::Context *context)
+{
+ Current *current = GetCurrentData();
+
+ current->context = context;
+}
+
+gl::Context *GetGlobalContext()
+{
+ Current *current = GetCurrentData();
+
+ return current->context;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/global_state.h b/src/3rdparty/angle/src/libGLESv2/global_state.h
new file mode 100644
index 0000000000..db202539cb
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/global_state.h
@@ -0,0 +1,49 @@
+//
+// Copyright(c) 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 <EGL/egl.h>
+
+namespace gl
+{
+class Context;
+
+Context *GetGlobalContext();
+Context *GetValidGlobalContext();
+
+}
+
+namespace egl
+{
+class Error;
+class Display;
+class Surface;
+
+void SetGlobalError(const Error &error);
+EGLint GetGlobalError();
+
+void SetGlobalAPI(EGLenum API);
+EGLenum GetGlobalAPI();
+
+void SetGlobalDisplay(Display *dpy);
+Display *GetGlobalDisplay();
+
+void SetGlobalDrawSurface(Surface *surface);
+Surface *GetGlobalDrawSurface();
+
+void SetGlobalReadSurface(Surface *surface);
+Surface *GetGlobalReadSurface();
+
+void SetGlobalContext(gl::Context *context);
+gl::Context *GetGlobalContext();
+
+}
+
+#endif // LIBGLESV2_GLOBALSTATE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
index 587950a139..e69e04aa60 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
@@ -6,8977 +6,1416 @@
// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
-#undef GL_APICALL
-#define GL_APICALL
-#define GL_GLEXT_PROTOTYPES
-
-#include "common/version.h"
-#include "common/utilities.h"
-
-#include "libGLESv2/main.h"
-#include "libGLESv2/formatutils.h"
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/Fence.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/Program.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/Texture.h"
-#include "libGLESv2/Query.h"
-#include "libGLESv2/Context.h"
-#include "libGLESv2/VertexArray.h"
-#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/TransformFeedback.h"
-#include "libGLESv2/FramebufferAttachment.h"
-
-#include "libGLESv2/validationES.h"
-#include "libGLESv2/validationES2.h"
-#include "libGLESv2/validationES3.h"
-#include "libGLESv2/queryconversions.h"
+#include "libGLESv2/entry_points_gles_2_0.h"
+#include "libGLESv2/entry_points_gles_2_0_ext.h"
+#include "libGLESv2/entry_points_gles_3_0.h"
+#include "libGLESv2/entry_points_gles_3_0_ext.h"
+
+#include "common/event_tracer.h"
extern "C"
{
-// OpenGL ES 2.0 functions
-
void GL_APIENTRY glActiveTexture(GLenum texture)
{
- EVENT("(GLenum texture = 0x%X)", texture);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- context->getState().setActiveSampler(texture - GL_TEXTURE0);
- }
+ return gl::ActiveTexture(texture);
}
void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
{
- EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Program *programObject = context->getProgram(program);
- gl::Shader *shaderObject = context->getShader(shader);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- if (!shaderObject)
- {
- if (context->getProgram(shader))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- if (!programObject->attachShader(shaderObject))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- }
-}
-
-void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint id)
-{
- EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateBeginQuery(context, target, id))
- {
- return;
- }
-
- gl::Error error = context->beginQuery(target, id);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::AttachShader(program, shader);
}
void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
{
- EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- if (strncmp(name, "gl_", 3) == 0)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- programObject->bindAttributeLocation(index, name);
- }
+ return gl::BindAttribLocation(program, index, name);
}
void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
{
- EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!gl::ValidBufferTarget(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (target)
- {
- case GL_ARRAY_BUFFER:
- context->bindArrayBuffer(buffer);
- return;
- case GL_ELEMENT_ARRAY_BUFFER:
- context->bindElementArrayBuffer(buffer);
- return;
- case GL_COPY_READ_BUFFER:
- context->bindCopyReadBuffer(buffer);
- return;
- case GL_COPY_WRITE_BUFFER:
- context->bindCopyWriteBuffer(buffer);
- return;
- case GL_PIXEL_PACK_BUFFER:
- context->bindPixelPackBuffer(buffer);
- return;
- case GL_PIXEL_UNPACK_BUFFER:
- context->bindPixelUnpackBuffer(buffer);
- return;
- case GL_UNIFORM_BUFFER:
- context->bindGenericUniformBuffer(buffer);
- return;
- case GL_TRANSFORM_FEEDBACK_BUFFER:
- context->bindGenericTransformFeedbackBuffer(buffer);
- return;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::BindBuffer(target, buffer);
}
void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
{
- EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!gl::ValidFramebufferTarget(target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
- {
- context->bindReadFramebuffer(framebuffer);
- }
-
- if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
- {
- context->bindDrawFramebuffer(framebuffer);
- }
- }
+ return gl::BindFramebuffer(target, framebuffer);
}
void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
{
- EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (target != GL_RENDERBUFFER)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- context->bindRenderbuffer(renderbuffer);
- }
+ return gl::BindRenderbuffer(target, renderbuffer);
}
void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
{
- EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Texture *textureObject = context->getTexture(texture);
-
- if (textureObject && textureObject->getTarget() != target && texture != 0)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- switch (target)
- {
- case GL_TEXTURE_2D:
- case GL_TEXTURE_CUBE_MAP:
- break;
-
- case GL_TEXTURE_3D:
- case GL_TEXTURE_2D_ARRAY:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- context->bindTexture(target, texture);
- }
+ return gl::BindTexture(target, texture);
}
-void GL_APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+void GL_APIENTRY glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
- EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
- red, green, blue, alpha);
-
- gl::Context* context = gl::getNonLostContext();
-
- if (context)
- {
- context->getState().setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
- }
+ return gl::BlendColor(red, green, blue, alpha);
}
void GL_APIENTRY glBlendEquation(GLenum mode)
{
- glBlendEquationSeparate(mode, mode);
+ return gl::BlendEquation(mode);
}
void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
{
- EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- switch (modeRGB)
- {
- case GL_FUNC_ADD:
- case GL_FUNC_SUBTRACT:
- case GL_FUNC_REVERSE_SUBTRACT:
- case GL_MIN:
- case GL_MAX:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (modeAlpha)
- {
- case GL_FUNC_ADD:
- case GL_FUNC_SUBTRACT:
- case GL_FUNC_REVERSE_SUBTRACT:
- case GL_MIN:
- case GL_MAX:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- context->getState().setBlendEquation(modeRGB, modeAlpha);
- }
+ return gl::BlendEquationSeparate(modeRGB, modeAlpha);
}
void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
{
- glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
+ return gl::BlendFunc(sfactor, dfactor);
}
void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
- EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
- srcRGB, dstRGB, srcAlpha, dstAlpha);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- switch (srcRGB)
- {
- 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:
- case GL_SRC_ALPHA_SATURATE:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (dstRGB)
- {
- case GL_ZERO:
- case GL_ONE:
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- break;
-
- case GL_SRC_ALPHA_SATURATE:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (srcAlpha)
- {
- 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:
- case GL_SRC_ALPHA_SATURATE:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (dstAlpha)
- {
- case GL_ZERO:
- case GL_ONE:
- case GL_SRC_COLOR:
- case GL_ONE_MINUS_SRC_COLOR:
- case GL_DST_COLOR:
- case GL_ONE_MINUS_DST_COLOR:
- case GL_SRC_ALPHA:
- case GL_ONE_MINUS_SRC_ALPHA:
- case GL_DST_ALPHA:
- case GL_ONE_MINUS_DST_ALPHA:
- case GL_CONSTANT_COLOR:
- case GL_ONE_MINUS_CONSTANT_COLOR:
- case GL_CONSTANT_ALPHA:
- case GL_ONE_MINUS_CONSTANT_ALPHA:
- break;
-
- case GL_SRC_ALPHA_SATURATE:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- 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)
- {
- ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- context->getState().setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
- }
+ return gl::BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
- EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
- target, size, data, usage);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (size < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- switch (usage)
- {
- case GL_STREAM_DRAW:
- case GL_STATIC_DRAW:
- case GL_DYNAMIC_DRAW:
- break;
-
- case GL_STREAM_READ:
- case GL_STREAM_COPY:
- case GL_STATIC_READ:
- case GL_STATIC_COPY:
- case GL_DYNAMIC_READ:
- case GL_DYNAMIC_COPY:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (!gl::ValidBufferTarget(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Buffer *buffer = context->getState().getTargetBuffer(target);
-
- if (!buffer)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- gl::Error error = buffer->bufferData(data, size, usage);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::BufferData(target, size, data, usage);
}
void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
{
- EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
- target, offset, size, data);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (size < 0 || offset < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (data == NULL)
- {
- return;
- }
-
- if (!gl::ValidBufferTarget(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Buffer *buffer = context->getState().getTargetBuffer(target);
-
- if (!buffer)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (buffer->isMapped())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // Check for possible overflow of size + offset
- if (!rx::IsUnsignedAdditionSafe<size_t>(size, offset))
- {
- context->recordError(gl::Error(GL_OUT_OF_MEMORY));
- return;
- }
-
- if (size + offset > buffer->getSize())
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Error error = buffer->bufferSubData(data, size, offset);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::BufferSubData(target, offset, size, data);
}
GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
{
- EVENT("(GLenum target = 0x%X)", target);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!gl::ValidFramebufferTarget(target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return 0;
- }
-
- gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
- ASSERT(framebuffer);
-
- return framebuffer->completeness(context->getData());
- }
-
- return 0;
+ return gl::CheckFramebufferStatus(target);
}
void GL_APIENTRY glClear(GLbitfield mask)
{
- EVENT("(GLbitfield mask = 0x%X)", mask);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
- ASSERT(framebufferObject);
-
- if (framebufferObject->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
- {
- context->recordError(gl::Error(GL_INVALID_FRAMEBUFFER_OPERATION));
- return;
- }
-
- if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Error error = context->clear(mask);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::Clear(mask);
}
-void GL_APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+void GL_APIENTRY glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
- EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
- red, green, blue, alpha);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- context->getState().setClearColor(red, green, blue, alpha);
- }
+ return gl::ClearColor(red, green, blue, alpha);
}
-void GL_APIENTRY glClearDepthf(GLclampf depth)
+void GL_APIENTRY glClearDepthf(GLfloat depth)
{
- EVENT("(GLclampf depth = %f)", depth);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- context->getState().setClearDepth(depth);
- }
+ return gl::ClearDepthf(depth);
}
void GL_APIENTRY glClearStencil(GLint s)
{
- EVENT("(GLint s = %d)", s);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- context->getState().setClearStencil(s);
- }
+ return gl::ClearStencil(s);
}
void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
{
- EVENT("(GLboolean red = %d, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)",
- red, green, blue, alpha);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- context->getState().setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
- }
+ return gl::ColorMask(red, green, blue, alpha);
}
void GL_APIENTRY glCompileShader(GLuint shader)
{
- EVENT("(GLuint shader = %d)", shader);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Shader *shaderObject = context->getShader(shader);
-
- if (!shaderObject)
- {
- if (context->getProgram(shader))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- shaderObject->compile(context->getData());
- }
-}
-
-void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
- GLint border, GLsizei imageSize, const GLvoid* data)
-{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
- "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
- target, level, internalformat, width, height, border, imageSize, data);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3 &&
- !ValidateES2TexImageParameters(context, target, level, internalformat, true, false,
- 0, 0, width, height, border, GL_NONE, GL_NONE, data))
- {
- return;
- }
-
- if (context->getClientVersion() >= 3 &&
- !ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
- 0, 0, 0, width, height, 1, border, GL_NONE, GL_NONE, data))
- {
- return;
- }
-
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
- if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- switch (target)
- {
- case GL_TEXTURE_2D:
- {
- gl::Texture2D *texture = context->getTexture2D();
- gl::Error error = texture->setCompressedImage(level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
- gl::Error error = texture->setCompressedImage(target, level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
-}
-
-void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize, const GLvoid* data)
-{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
- "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
- "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
- target, level, xoffset, yoffset, width, height, format, imageSize, data);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3 &&
- !ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true,
- xoffset, yoffset, width, height, 0, GL_NONE, GL_NONE, data))
- {
- return;
- }
-
- if (context->getClientVersion() >= 3 &&
- !ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
- xoffset, yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, data))
- {
- return;
- }
-
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
- if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- switch (target)
- {
- case GL_TEXTURE_2D:
- {
- gl::Texture2D *texture = context->getTexture2D();
- gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, context->getState().getUnpackState(), data);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
- gl::Error error = texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, context->getState().getUnpackState(), data);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::CompileShader(shader);
+}
+
+void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* 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 GLvoid* 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)
{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
- "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
- target, level, internalformat, x, y, width, height, border);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3 &&
- !ValidateES2CopyTexImageParameters(context, target, level, internalformat, false,
- 0, 0, x, y, width, height, border))
- {
- return;
- }
-
- if (context->getClientVersion() >= 3 &&
- !ValidateES3CopyTexImageParameters(context, target, level, internalformat, false,
- 0, 0, 0, x, y, width, height, border))
- {
- return;
- }
-
- gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
-
- switch (target)
- {
- case GL_TEXTURE_2D:
- {
- gl::Texture2D *texture = context->getTexture2D();
- gl::Error error = texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
- gl::Error error = texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ 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)
{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
- "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
- target, level, xoffset, yoffset, x, y, width, height);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3 &&
- !ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true,
- xoffset, yoffset, x, y, width, height, 0))
- {
- return;
- }
-
- if (context->getClientVersion() >= 3 &&
- !ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true,
- xoffset, yoffset, 0, x, y, width, height, 0))
- {
- return;
- }
-
- gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
-
- switch (target)
- {
- case GL_TEXTURE_2D:
- {
- gl::Texture2D *texture = context->getTexture2D();
- gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
- gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
}
GLuint GL_APIENTRY glCreateProgram(void)
{
- EVENT("()");
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- return context->createProgram();
- }
-
- return 0;
+ return gl::CreateProgram();
}
GLuint GL_APIENTRY glCreateShader(GLenum type)
{
- EVENT("(GLenum type = 0x%X)", type);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- switch (type)
- {
- case GL_FRAGMENT_SHADER:
- case GL_VERTEX_SHADER:
- return context->createShader(type);
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return 0;
- }
- }
-
- return 0;
+ return gl::CreateShader(type);
}
void GL_APIENTRY glCullFace(GLenum mode)
{
- EVENT("(GLenum mode = 0x%X)", mode);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- switch (mode)
- {
- case GL_FRONT:
- case GL_BACK:
- case GL_FRONT_AND_BACK:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- context->getState().setCullMode(mode);
- }
+ return gl::CullFace(mode);
}
void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
{
- EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < n; i++)
- {
- context->deleteBuffer(buffers[i]);
- }
- }
-}
-
-void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
-{
- EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < n; i++)
- {
- context->deleteFenceNV(fences[i]);
- }
- }
+ return gl::DeleteBuffers(n, buffers);
}
void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
{
- EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < n; i++)
- {
- if (framebuffers[i] != 0)
- {
- context->deleteFramebuffer(framebuffers[i]);
- }
- }
- }
+ return gl::DeleteFramebuffers(n, framebuffers);
}
void GL_APIENTRY glDeleteProgram(GLuint program)
{
- EVENT("(GLuint program = %d)", program);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (program == 0)
- {
- return;
- }
-
- if (!context->getProgram(program))
- {
- if(context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- context->deleteProgram(program);
- }
-}
-
-void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
-{
- EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < n; i++)
- {
- context->deleteQuery(ids[i]);
- }
- }
+ return gl::DeleteProgram(program);
}
void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
{
- EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < n; i++)
- {
- context->deleteRenderbuffer(renderbuffers[i]);
- }
- }
+ return gl::DeleteRenderbuffers(n, renderbuffers);
}
void GL_APIENTRY glDeleteShader(GLuint shader)
{
- EVENT("(GLuint shader = %d)", shader);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (shader == 0)
- {
- return;
- }
-
- if (!context->getShader(shader))
- {
- if(context->getProgram(shader))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- context->deleteShader(shader);
- }
+ return gl::DeleteShader(shader);
}
void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
{
- EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < n; i++)
- {
- if (textures[i] != 0)
- {
- context->deleteTexture(textures[i]);
- }
- }
- }
+ return gl::DeleteTextures(n, textures);
}
void GL_APIENTRY glDepthFunc(GLenum func)
{
- EVENT("(GLenum func = 0x%X)", func);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- 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:
- context->getState().setDepthFunc(func);
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::DepthFunc(func);
}
void GL_APIENTRY glDepthMask(GLboolean flag)
{
- EVENT("(GLboolean flag = %u)", flag);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- context->getState().setDepthMask(flag != GL_FALSE);
- }
+ return gl::DepthMask(flag);
}
-void GL_APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
+void GL_APIENTRY glDepthRangef(GLfloat n, GLfloat f)
{
- EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- context->getState().setDepthRange(zNear, zFar);
- }
+ return gl::DepthRangef(n, f);
}
void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)
{
- EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Program *programObject = context->getProgram(program);
- gl::Shader *shaderObject = context->getShader(shader);
-
- if (!programObject)
- {
- gl::Shader *shaderByProgramHandle;
- shaderByProgramHandle = context->getShader(program);
- if (!shaderByProgramHandle)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- }
-
- if (!shaderObject)
- {
- gl::Program *programByShaderHandle = context->getProgram(shader);
- if (!programByShaderHandle)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- }
-
- if (!programObject->detachShader(shaderObject))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- }
+ return gl::DetachShader(program, shader);
}
void GL_APIENTRY glDisable(GLenum cap)
{
- EVENT("(GLenum cap = 0x%X)", cap);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidCap(context, cap))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- context->getState().setEnableFeature(cap, false);
- }
+ return gl::Disable(cap);
}
void GL_APIENTRY glDisableVertexAttribArray(GLuint index)
{
- EVENT("(GLuint index = %d)", index);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->getState().setEnableVertexAttribArray(index, false);
- }
+ return gl::DisableVertexAttribArray(index);
}
void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
{
- EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateDrawArrays(context, mode, first, count, 0))
- {
- return;
- }
-
- gl::Error error = context->drawArrays(mode, first, count, 0);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
-}
-
-void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
-{
- EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateDrawArraysInstancedANGLE(context, mode, first, count, primcount))
- {
- return;
- }
-
- gl::Error error = context->drawArrays(mode, first, count, primcount);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::DrawArrays(mode, first, count);
}
void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
{
- EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
- mode, count, type, indices);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- rx::RangeUI indexRange;
- if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange))
- {
- return;
- }
-
- gl::Error error = context->drawElements(mode, count, type, indices, 0, indexRange);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
-}
-
-void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount)
-{
- EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)",
- mode, count, type, indices, primcount);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- rx::RangeUI indexRange;
- if (!ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount, &indexRange))
- {
- return;
- }
-
- gl::Error error = context->drawElements(mode, count, type, indices, primcount, indexRange);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::DrawElements(mode, count, type, indices);
}
void GL_APIENTRY glEnable(GLenum cap)
{
- EVENT("(GLenum cap = 0x%X)", cap);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidCap(context, cap))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- context->getState().setEnableFeature(cap, true);
- }
+ return gl::Enable(cap);
}
void GL_APIENTRY glEnableVertexAttribArray(GLuint index)
{
- EVENT("(GLuint index = %d)", index);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->getState().setEnableVertexAttribArray(index, true);
- }
-}
-
-void GL_APIENTRY glEndQueryEXT(GLenum target)
-{
- EVENT("GLenum target = 0x%X)", target);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateEndQuery(context, target))
- {
- return;
- }
-
- gl::Error error = context->endQuery(target);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
-}
-
-void GL_APIENTRY glFinishFenceNV(GLuint fence)
-{
- EVENT("(GLuint fence = %d)", fence);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::FenceNV *fenceObject = context->getFenceNV(fence);
-
- if (fenceObject == NULL)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (fenceObject->isFence() != GL_TRUE)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- fenceObject->finishFence();
- }
+ return gl::EnableVertexAttribArray(index);
}
void GL_APIENTRY glFinish(void)
{
- EVENT("()");
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Error error = context->sync(true);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::Finish();
}
void GL_APIENTRY glFlush(void)
{
- EVENT("()");
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Error error = context->sync(false);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::Flush();
}
void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
- EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
- "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!gl::ValidFramebufferTarget(target) || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (!gl::ValidateFramebufferRenderbufferParameters(context, target, attachment, renderbuffertarget, renderbuffer))
- {
- return;
- }
-
- gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
- ASSERT(framebuffer);
-
- if (renderbuffer != 0)
- {
- gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
- framebuffer->setRenderbufferAttachment(attachment, renderbufferObject);
- }
- else
- {
- framebuffer->setNULLAttachment(attachment);
- }
- }
+ return gl::FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
}
void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
- EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
- "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateFramebufferTexture2D(context, target, attachment, textarget, texture, level))
- {
- return;
- }
-
- gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
- ASSERT(framebuffer);
-
- if (texture != 0)
- {
- gl::Texture *textureObj = context->getTexture(texture);
- gl::ImageIndex index(textarget, level, gl::ImageIndex::ENTIRE_LEVEL);
- framebuffer->setTextureAttachment(attachment, textureObj, index);
- }
- else
- {
- framebuffer->setNULLAttachment(attachment);
- }
- }
+ return gl::FramebufferTexture2D(target, attachment, textarget, texture, level);
}
void GL_APIENTRY glFrontFace(GLenum mode)
{
- EVENT("(GLenum mode = 0x%X)", mode);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- switch (mode)
- {
- case GL_CW:
- case GL_CCW:
- context->getState().setFrontFace(mode);
- break;
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::FrontFace(mode);
}
void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
{
- EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < n; i++)
- {
- buffers[i] = context->createBuffer();
- }
- }
+ return gl::GenBuffers(n, buffers);
}
void GL_APIENTRY glGenerateMipmap(GLenum target)
{
- EVENT("(GLenum target = 0x%X)", target);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidTextureTarget(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Texture *texture = context->getTargetTexture(target);
-
- if (texture == NULL)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- GLenum internalFormat = texture->getBaseLevelInternalFormat();
- const gl::TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
-
- // GenerateMipmap should not generate an INVALID_OPERATION for textures created with
- // unsized formats or that are color renderable and filterable. Since we do not track if
- // the texture was created with sized or unsized format (only sized formats are stored),
- // it is not possible to make sure the the LUMA formats can generate mipmaps (they should
- // be able to) because they aren't color renderable. Simply do a special case for LUMA
- // textures since they're the only texture format that can be created with unsized formats
- // that is not color renderable. New unsized formats are unlikely to be added, since ES2
- // was the last version to use add them.
- bool isLUMA = internalFormat == GL_LUMINANCE8_EXT ||
- internalFormat == GL_LUMINANCE8_ALPHA8_EXT ||
- internalFormat == GL_ALPHA8_EXT;
-
- if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0 || !formatCaps.filterable ||
- (!formatCaps.renderable && !isLUMA) || formatInfo.compressed)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // GL_EXT_sRGB does not support mipmap generation on sRGB textures
- if (context->getClientVersion() == 2 && formatInfo.colorEncoding == GL_SRGB)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // Non-power of 2 ES2 check
- if (!context->getExtensions().textureNPOT && (!gl::isPow2(texture->getBaseLevelWidth()) || !gl::isPow2(texture->getBaseLevelHeight())))
- {
- ASSERT(context->getClientVersion() <= 2 && (target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP));
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // Cube completeness check
- if (target == GL_TEXTURE_CUBE_MAP)
- {
- gl::TextureCubeMap *textureCube = static_cast<gl::TextureCubeMap *>(texture);
- if (!textureCube->isCubeComplete())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- }
-
- gl::Error error = texture->generateMipmaps();
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
-}
-
-void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
-{
- EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < n; i++)
- {
- fences[i] = context->createFenceNV();
- }
- }
+ return gl::GenerateMipmap(target);
}
void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
{
- EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < n; i++)
- {
- framebuffers[i] = context->createFramebuffer();
- }
- }
+ return gl::GenFramebuffers(n, framebuffers);
}
-void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
+void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
{
- EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (GLsizei i = 0; i < n; i++)
- {
- ids[i] = context->createQuery();
- }
- }
+ return gl::GenRenderbuffers(n, renderbuffers);
}
-void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
{
- EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < n; i++)
- {
- renderbuffers[i] = context->createRenderbuffer();
- }
- }
+ return gl::GenTextures(n, textures);
}
-void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
+void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
{
- EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < n; i++)
- {
- textures[i] = context->createTexture();
- }
- }
-}
-
-void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
-{
- EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
- "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
- program, index, bufsize, length, size, type, name);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (bufsize < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- if (index >= (GLuint)programObject->getActiveAttributeCount())
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- programObject->getActiveAttribute(index, bufsize, length, size, type, 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)
{
- EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
- "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
- program, index, bufsize, length, size, type, name);
-
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (bufsize < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- if (index >= (GLuint)programObject->getActiveUniformCount())
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- programObject->getActiveUniform(index, bufsize, length, size, type, name);
- }
+ return gl::GetActiveUniform(program, index, bufsize, length, size, type, name);
}
void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
{
- EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
- program, maxcount, count, shaders);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (maxcount < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- return programObject->getAttachedShaders(maxcount, count, shaders);
- }
+ return gl::GetAttachedShaders(program, maxcount, count, shaders);
}
GLint GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
{
- EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return -1;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return -1;
- }
- }
-
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programObject->isLinked() || !programBinary)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return -1;
- }
-
- return programBinary->getAttributeLocation(name);
- }
-
- return -1;
+ return gl::GetAttribLocation(program, name);
}
void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
{
- EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- GLenum nativeType;
- unsigned int numParams = 0;
- if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
- {
- return;
- }
-
- if (nativeType == GL_BOOL)
- {
- context->getBooleanv(pname, params);
- }
- else
- {
- CastStateValues(context, nativeType, pname, numParams, params);
- }
- }
+ return gl::GetBooleanv(pname, params);
}
void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
- EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!gl::ValidBufferTarget(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (!gl::ValidBufferParameter(context, pname))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Buffer *buffer = context->getState().getTargetBuffer(target);
-
- if (!buffer)
- {
- // A null buffer means that "0" is bound to the requested buffer target
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- switch (pname)
- {
- case GL_BUFFER_USAGE:
- *params = static_cast<GLint>(buffer->getUsage());
- break;
- case GL_BUFFER_SIZE:
- *params = gl::clampCast<GLint>(buffer->getSize());
- break;
- case GL_BUFFER_ACCESS_FLAGS:
- *params = buffer->getAccessFlags();
- break;
- case GL_BUFFER_MAPPED:
- *params = static_cast<GLint>(buffer->isMapped());
- break;
- case GL_BUFFER_MAP_OFFSET:
- *params = gl::clampCast<GLint>(buffer->getMapOffset());
- break;
- case GL_BUFFER_MAP_LENGTH:
- *params = gl::clampCast<GLint>(buffer->getMapLength());
- break;
- default: UNREACHABLE(); break;
- }
- }
+ return gl::GetBufferParameteriv(target, pname, params);
}
GLenum GL_APIENTRY glGetError(void)
{
- EVENT("()");
-
- gl::Context *context = gl::getContext();
-
- if (context)
- {
- return context->getError();
- }
-
- return GL_NO_ERROR;
-}
-
-void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
-{
- EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::FenceNV *fenceObject = context->getFenceNV(fence);
-
- if (fenceObject == NULL)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (fenceObject->isFence() != GL_TRUE)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- 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)
- {
- gl::Error error = fenceObject->testFence(&status);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- *params = status;
- break;
- }
-
- case GL_FENCE_CONDITION_NV:
- {
- *params = fenceObject->getCondition();
- break;
- }
-
- default:
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
- }
+ return gl::GetError();
}
void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
{
- EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- GLenum nativeType;
- unsigned int numParams = 0;
- if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
- {
- return;
- }
-
- if (nativeType == GL_FLOAT)
- {
- context->getFloatv(pname, params);
- }
- else
- {
- CastStateValues(context, nativeType, pname, numParams, params);
- }
- }
+ return gl::GetFloatv(pname, params);
}
void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
- EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
- target, attachment, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!gl::ValidFramebufferTarget(target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- int clientVersion = context->getClientVersion();
-
- switch (pname)
- {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
- if (clientVersion < 3 && !context->getExtensions().sRGB)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
- case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
- if (clientVersion < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- // Determine if the attachment is a valid enum
- switch (attachment)
- {
- case GL_BACK:
- case GL_FRONT:
- case GL_DEPTH:
- case GL_STENCIL:
- case GL_DEPTH_STENCIL_ATTACHMENT:
- if (clientVersion < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- break;
-
- case GL_DEPTH_ATTACHMENT:
- case GL_STENCIL_ATTACHMENT:
- break;
-
- default:
- if (attachment < GL_COLOR_ATTACHMENT0_EXT ||
- (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- break;
- }
-
- GLuint framebufferHandle = context->getState().getTargetFramebuffer(target)->id();
- gl::Framebuffer *framebuffer = context->getFramebuffer(framebufferHandle);
- ASSERT(framebuffer);
-
- if (framebufferHandle == 0)
- {
- if (clientVersion < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- switch (attachment)
- {
- case GL_BACK:
- case GL_DEPTH:
- case GL_STENCIL:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- }
- else
- {
- if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
- {
- // Valid attachment query
- }
- else
- {
- switch (attachment)
- {
- case GL_DEPTH_ATTACHMENT:
- case GL_STENCIL_ATTACHMENT:
- break;
-
- case GL_DEPTH_STENCIL_ATTACHMENT:
- if (framebuffer->hasValidDepthStencil())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- }
- }
-
- GLenum attachmentType = GL_NONE;
- GLuint attachmentHandle = 0;
- GLuint attachmentLevel = 0;
- GLuint attachmentLayer = 0;
-
- const gl::FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment);
-
- if (attachmentObject)
- {
- attachmentType = attachmentObject->type();
- attachmentHandle = attachmentObject->id();
- attachmentLevel = attachmentObject->mipLevel();
- attachmentLayer = attachmentObject->layer();
- }
-
- GLenum attachmentObjectType; // Type category
- if (framebufferHandle == 0)
- {
- attachmentObjectType = GL_FRAMEBUFFER_DEFAULT;
- }
- else if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
- {
- attachmentObjectType = attachmentType;
- }
- else if (gl::ValidTexture2DDestinationTarget(context, attachmentType))
- {
- attachmentObjectType = GL_TEXTURE;
- }
- else
- {
- UNREACHABLE();
- return;
- }
-
- if (attachmentObjectType == GL_NONE)
- {
- // 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 = attachmentObjectType;
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- if (clientVersion < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = 0;
- break;
-
- default:
- if (clientVersion < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- }
- }
- else
- {
- ASSERT(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE ||
- attachmentObjectType == GL_FRAMEBUFFER_DEFAULT);
- ASSERT(attachmentObject != NULL);
-
- switch (pname)
- {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- *params = attachmentObjectType;
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- if (attachmentObjectType != GL_RENDERBUFFER && attachmentObjectType != GL_TEXTURE)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = attachmentHandle;
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
- if (attachmentObjectType != GL_TEXTURE)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = attachmentLevel;
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
- if (attachmentObjectType != GL_TEXTURE)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = gl::IsCubemapTextureTarget(attachmentType) ? attachmentType : 0;
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
- *params = attachmentObject->getRedSize();
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
- *params = attachmentObject->getGreenSize();
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
- *params = attachmentObject->getBlueSize();
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
- *params = attachmentObject->getAlphaSize();
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
- *params = attachmentObject->getDepthSize();
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
- *params = attachmentObject->getStencilSize();
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
- if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- *params = attachmentObject->getComponentType();
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
- *params = attachmentObject->getColorEncoding();
- break;
-
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
- if (attachmentObjectType != GL_TEXTURE)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = attachmentLayer;
- break;
-
- default:
- UNREACHABLE();
- break;
- }
- }
- }
-}
-
-GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)
-{
- EVENT("()");
-
- gl::Context *context = gl::getContext();
-
- if (context)
- {
- return context->getResetStatus();
- }
-
- return GL_NO_ERROR;
+ return gl::GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
}
void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params)
{
- EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- GLenum nativeType;
- unsigned int numParams = 0;
-
- if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
- {
- return;
- }
-
- if (nativeType == GL_INT)
- {
- context->getIntegerv(pname, params);
- }
- else
- {
- CastStateValues(context, nativeType, pname, numParams, params);
- }
- }
+ return gl::GetIntegerv(pname, params);
}
void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
{
- EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (context->getClientVersion() < 3)
- {
- switch (pname)
- {
- case GL_ACTIVE_UNIFORM_BLOCKS:
- case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
- case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
- case GL_TRANSFORM_FEEDBACK_VARYINGS:
- case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
-
- switch (pname)
- {
- case GL_DELETE_STATUS:
- *params = programObject->isFlaggedForDeletion();
- return;
- case GL_LINK_STATUS:
- *params = programObject->isLinked();
- return;
- case GL_VALIDATE_STATUS:
- *params = programObject->isValidated();
- return;
- case GL_INFO_LOG_LENGTH:
- *params = programObject->getInfoLogLength();
- return;
- case GL_ATTACHED_SHADERS:
- *params = programObject->getAttachedShadersCount();
- return;
- case GL_ACTIVE_ATTRIBUTES:
- *params = programObject->getActiveAttributeCount();
- return;
- case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
- *params = programObject->getActiveAttributeMaxLength();
- return;
- case GL_ACTIVE_UNIFORMS:
- *params = programObject->getActiveUniformCount();
- return;
- case GL_ACTIVE_UNIFORM_MAX_LENGTH:
- *params = programObject->getActiveUniformMaxLength();
- return;
- case GL_PROGRAM_BINARY_LENGTH_OES:
- *params = programObject->getProgramBinaryLength();
- return;
- case GL_ACTIVE_UNIFORM_BLOCKS:
- *params = programObject->getActiveUniformBlockCount();
- return;
- case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
- *params = programObject->getActiveUniformBlockMaxLength();
- break;
- case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
- *params = programObject->getTransformFeedbackBufferMode();
- break;
- case GL_TRANSFORM_FEEDBACK_VARYINGS:
- *params = programObject->getTransformFeedbackVaryingCount();
- break;
- case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
- *params = programObject->getTransformFeedbackVaryingMaxLength();
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::GetProgramiv(program, pname, params);
}
void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
- EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
- program, bufsize, length, infolog);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (bufsize < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- programObject->getInfoLog(bufsize, length, infolog);
- }
-}
-
-void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
-{
- EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidQueryType(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (pname)
- {
- case GL_CURRENT_QUERY_EXT:
- params[0] = context->getState().getActiveQueryId(target);
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
-}
-
-void GL_APIENTRY glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
-{
- EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
-
- if (!queryObject)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (context->getState().getActiveQueryId(queryObject->getType()) == id)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- switch(pname)
- {
- case GL_QUERY_RESULT_EXT:
- {
- gl::Error error = queryObject->getResult(params);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_QUERY_RESULT_AVAILABLE_EXT:
- {
- gl::Error error = queryObject->isResultAvailable(params);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::GetProgramInfoLog(program, bufsize, length, infolog);
}
void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
- EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (target != GL_RENDERBUFFER)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (context->getState().getRenderbufferId() == 0)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getState().getRenderbufferId());
-
- switch (pname)
- {
- case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break;
- case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break;
- case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break;
- case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break;
- case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break;
- case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break;
- case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break;
- case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break;
- case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break;
-
- case GL_RENDERBUFFER_SAMPLES_ANGLE:
- if (!context->getExtensions().framebufferMultisample)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = renderbuffer->getSamples();
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::GetRenderbufferParameteriv(target, pname, params);
}
void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
{
- EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Shader *shaderObject = context->getShader(shader);
-
- if (!shaderObject)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- switch (pname)
- {
- case GL_SHADER_TYPE:
- *params = shaderObject->getType();
- return;
- case GL_DELETE_STATUS:
- *params = shaderObject->isFlaggedForDeletion();
- return;
- case GL_COMPILE_STATUS:
- *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
- return;
- case GL_INFO_LOG_LENGTH:
- *params = shaderObject->getInfoLogLength();
- return;
- case GL_SHADER_SOURCE_LENGTH:
- *params = shaderObject->getSourceLength();
- return;
- case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
- *params = shaderObject->getTranslatedSourceLength();
- return;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::GetShaderiv(shader, pname, params);
}
void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
- EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
- shader, bufsize, length, infolog);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (bufsize < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Shader *shaderObject = context->getShader(shader);
-
- if (!shaderObject)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- shaderObject->getInfoLog(bufsize, length, infolog);
- }
+ return gl::GetShaderInfoLog(shader, bufsize, length, infolog);
}
void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
{
- EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
- shadertype, precisiontype, range, precision);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- switch (shadertype)
- {
- case GL_VERTEX_SHADER:
- case GL_FRAGMENT_SHADER:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (precisiontype)
- {
- case GL_LOW_FLOAT:
- case GL_MEDIUM_FLOAT:
- case GL_HIGH_FLOAT:
- // Assume IEEE 754 precision
- range[0] = 127;
- range[1] = 127;
- *precision = 23;
- break;
-
- case GL_LOW_INT:
- case GL_MEDIUM_INT:
- case GL_HIGH_INT:
- // Some (most) hardware only supports single-precision floating-point numbers,
- // which can accurately represent integers up to +/-16777216
- range[0] = 24;
- range[1] = 24;
- *precision = 0;
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::GetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
}
void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
{
- EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
- shader, bufsize, length, source);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (bufsize < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Shader *shaderObject = context->getShader(shader);
-
- if (!shaderObject)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- shaderObject->getSource(bufsize, length, source);
- }
-}
-
-void GL_APIENTRY glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
-{
- EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
- shader, bufsize, length, source);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (bufsize < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Shader *shaderObject = context->getShader(shader);
-
- if (!shaderObject)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // Only returns extra info if ANGLE_GENERATE_SHADER_DEBUG_INFO is defined
- shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source);
- }
+ return gl::GetShaderSource(shader, bufsize, length, source);
}
const GLubyte* GL_APIENTRY glGetString(GLenum name)
{
- EVENT("(GLenum name = 0x%X)", name);
-
- gl::Context *context = gl::getNonLostContext();
-
- switch (name)
- {
- case GL_VENDOR:
- return (GLubyte*)"Google Inc.";
-
- case GL_RENDERER:
- return (GLubyte*)((context != NULL) ? context->getRendererString().c_str() : "ANGLE");
-
- case GL_VERSION:
- if (context->getClientVersion() == 2)
- {
- return (GLubyte*)"OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")";
- }
- else
- {
- return (GLubyte*)"OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")";
- }
-
- case GL_SHADING_LANGUAGE_VERSION:
- if (context->getClientVersion() == 2)
- {
- return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")";
- }
- else
- {
- return (GLubyte*)"OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")";
- }
-
- case GL_EXTENSIONS:
- return (GLubyte*)((context != NULL) ? context->getExtensionString().c_str() : "");
-
- default:
- if (context)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- }
- return NULL;
- }
+ return gl::GetString(name);
}
void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
{
- EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Texture *texture = context->getTargetTexture(target);
-
- if (!texture)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (pname)
- {
- case GL_TEXTURE_MAG_FILTER:
- *params = (GLfloat)texture->getSamplerState().magFilter;
- break;
- case GL_TEXTURE_MIN_FILTER:
- *params = (GLfloat)texture->getSamplerState().minFilter;
- break;
- case GL_TEXTURE_WRAP_S:
- *params = (GLfloat)texture->getSamplerState().wrapS;
- break;
- case GL_TEXTURE_WRAP_T:
- *params = (GLfloat)texture->getSamplerState().wrapT;
- break;
- case GL_TEXTURE_WRAP_R:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLfloat)texture->getSamplerState().wrapR;
- break;
- case GL_TEXTURE_IMMUTABLE_FORMAT:
- // Exposed to ES2.0 through EXT_texture_storage, no client version validation.
- *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE);
- break;
- case GL_TEXTURE_IMMUTABLE_LEVELS:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLfloat)texture->immutableLevelCount();
- break;
- case GL_TEXTURE_USAGE_ANGLE:
- *params = (GLfloat)texture->getUsage();
- break;
- case GL_TEXTURE_MAX_ANISOTROPY_EXT:
- if (!context->getExtensions().textureFilterAnisotropic)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLfloat)texture->getSamplerState().maxAnisotropy;
- break;
- case GL_TEXTURE_SWIZZLE_R:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLfloat)texture->getSamplerState().swizzleRed;
- break;
- case GL_TEXTURE_SWIZZLE_G:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLfloat)texture->getSamplerState().swizzleGreen;
- break;
- case GL_TEXTURE_SWIZZLE_B:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLfloat)texture->getSamplerState().swizzleBlue;
- break;
- case GL_TEXTURE_SWIZZLE_A:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLfloat)texture->getSamplerState().swizzleAlpha;
- break;
- case GL_TEXTURE_BASE_LEVEL:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLfloat)texture->getSamplerState().baseLevel;
- break;
- case GL_TEXTURE_MAX_LEVEL:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLfloat)texture->getSamplerState().maxLevel;
- break;
- case GL_TEXTURE_MIN_LOD:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = texture->getSamplerState().minLod;
- break;
- case GL_TEXTURE_MAX_LOD:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = texture->getSamplerState().maxLod;
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::GetTexParameterfv(target, pname, params);
}
void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
{
- EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Texture *texture = context->getTargetTexture(target);
-
- if (!texture)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (pname)
- {
- case GL_TEXTURE_MAG_FILTER:
- *params = texture->getSamplerState().magFilter;
- break;
- case GL_TEXTURE_MIN_FILTER:
- *params = texture->getSamplerState().minFilter;
- break;
- case GL_TEXTURE_WRAP_S:
- *params = texture->getSamplerState().wrapS;
- break;
- case GL_TEXTURE_WRAP_T:
- *params = texture->getSamplerState().wrapT;
- break;
- case GL_TEXTURE_WRAP_R:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = texture->getSamplerState().wrapR;
- break;
- case GL_TEXTURE_IMMUTABLE_FORMAT:
- // Exposed to ES2.0 through EXT_texture_storage, no client version validation.
- *params = texture->isImmutable() ? GL_TRUE : GL_FALSE;
- break;
- case GL_TEXTURE_IMMUTABLE_LEVELS:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = static_cast<GLint>(texture->immutableLevelCount());
- break;
- case GL_TEXTURE_USAGE_ANGLE:
- *params = texture->getUsage();
- break;
- case GL_TEXTURE_MAX_ANISOTROPY_EXT:
- if (!context->getExtensions().textureFilterAnisotropic)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLint)texture->getSamplerState().maxAnisotropy;
- break;
- case GL_TEXTURE_SWIZZLE_R:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = texture->getSamplerState().swizzleRed;
- break;
- case GL_TEXTURE_SWIZZLE_G:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = texture->getSamplerState().swizzleGreen;
- break;
- case GL_TEXTURE_SWIZZLE_B:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = texture->getSamplerState().swizzleBlue;
- break;
- case GL_TEXTURE_SWIZZLE_A:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = texture->getSamplerState().swizzleAlpha;
- break;
- case GL_TEXTURE_BASE_LEVEL:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = texture->getSamplerState().baseLevel;
- break;
- case GL_TEXTURE_MAX_LEVEL:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = texture->getSamplerState().maxLevel;
- break;
- case GL_TEXTURE_MIN_LOD:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLint)texture->getSamplerState().minLod;
- break;
- case GL_TEXTURE_MAX_LOD:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- *params = (GLint)texture->getSamplerState().maxLod;
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
-}
-
-void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
-{
- EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)",
- program, location, bufSize, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateGetnUniformfvEXT(context, program, location, bufSize, params))
- {
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
- ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- ASSERT(programBinary);
-
- programBinary->getUniformfv(location, params);
- }
+ return gl::GetTexParameteriv(target, pname, params);
}
void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
{
- EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateGetUniformfv(context, program, location, params))
- {
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
- ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- ASSERT(programBinary);
-
- programBinary->getUniformfv(location, params);
- }
-}
-
-void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
-{
- EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)",
- program, location, bufSize, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateGetnUniformivEXT(context, program, location, bufSize, params))
- {
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
- ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- ASSERT(programBinary);
-
- programBinary->getUniformiv(location, params);
- }
+ return gl::GetUniformfv(program, location, params);
}
void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
{
- EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateGetUniformiv(context, program, location, params))
- {
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
- ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- ASSERT(programBinary);
-
- programBinary->getUniformiv(location, params);
- }
+ return gl::GetUniformiv(program, location, params);
}
GLint GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
{
- EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (strstr(name, "gl_") == name)
- {
- return -1;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return -1;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return -1;
- }
- }
-
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programObject->isLinked() || !programBinary)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return -1;
- }
-
- return programBinary->getUniformLocation(name);
- }
-
- return -1;
+ return gl::GetUniformLocation(program, name);
}
void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
{
- EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
- if (!gl::ValidateGetVertexAttribParameters(context, pname))
- {
- return;
- }
-
- if (pname == GL_CURRENT_VERTEX_ATTRIB)
- {
- const gl::VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
- for (int i = 0; i < 4; ++i)
- {
- params[i] = currentValueData.FloatValues[i];
- }
- }
- else
- {
- *params = gl::QuerySingleVertexAttributeParameter<GLfloat>(attribState, pname);
- }
- }
+ return gl::GetVertexAttribfv(index, pname, params);
}
void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
{
- EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
-
- if (!gl::ValidateGetVertexAttribParameters(context, pname))
- {
- return;
- }
-
- if (pname == GL_CURRENT_VERTEX_ATTRIB)
- {
- const gl::VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
- for (int i = 0; i < 4; ++i)
- {
- float currentValue = currentValueData.FloatValues[i];
- params[i] = gl::iround<GLint>(currentValue);
- }
- }
- else
- {
- *params = gl::QuerySingleVertexAttributeParameter<GLint>(attribState, pname);
- }
- }
+ return gl::GetVertexAttribiv(index, pname, params);
}
void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
{
- EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- *pointer = const_cast<GLvoid*>(context->getState().getVertexAttribPointer(index));
- }
+ return gl::GetVertexAttribPointerv(index, pname, pointer);
}
void GL_APIENTRY glHint(GLenum target, GLenum mode)
{
- EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- switch (mode)
- {
- case GL_FASTEST:
- case GL_NICEST:
- case GL_DONT_CARE:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (target)
- {
- case GL_GENERATE_MIPMAP_HINT:
- context->getState().setGenerateMipmapHint(mode);
- break;
-
- case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
- context->getState().setFragmentShaderDerivativeHint(mode);
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::Hint(target, mode);
}
GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
{
- EVENT("(GLuint buffer = %d)", buffer);
-
- gl::Context *context = gl::getNonLostContext();
- if (context && buffer)
- {
- gl::Buffer *bufferObject = context->getBuffer(buffer);
-
- if (bufferObject)
- {
- return GL_TRUE;
- }
- }
-
- return GL_FALSE;
+ return gl::IsBuffer(buffer);
}
GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
{
- EVENT("(GLenum cap = 0x%X)", cap);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidCap(context, cap))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return GL_FALSE;
- }
-
- return context->getState().getEnableFeature(cap);
- }
-
- return false;
-}
-
-GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)
-{
- EVENT("(GLuint fence = %d)", fence);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::FenceNV *fenceObject = context->getFenceNV(fence);
-
- if (fenceObject == NULL)
- {
- return GL_FALSE;
- }
-
- return fenceObject->isFence();
- }
-
- return GL_FALSE;
+ return gl::IsEnabled(cap);
}
GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
{
- EVENT("(GLuint framebuffer = %d)", framebuffer);
-
- gl::Context *context = gl::getNonLostContext();
- if (context && framebuffer)
- {
- gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
-
- if (framebufferObject)
- {
- return GL_TRUE;
- }
- }
-
- return GL_FALSE;
+ return gl::IsFramebuffer(framebuffer);
}
GLboolean GL_APIENTRY glIsProgram(GLuint program)
{
- EVENT("(GLuint program = %d)", program);
-
- gl::Context *context = gl::getNonLostContext();
- if (context && program)
- {
- gl::Program *programObject = context->getProgram(program);
-
- if (programObject)
- {
- return GL_TRUE;
- }
- }
-
- return GL_FALSE;
-}
-
-GLboolean GL_APIENTRY glIsQueryEXT(GLuint id)
-{
- EVENT("(GLuint id = %d)", id);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
- }
-
- return GL_FALSE;
+ return gl::IsProgram(program);
}
GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
{
- EVENT("(GLuint renderbuffer = %d)", renderbuffer);
-
- gl::Context *context = gl::getNonLostContext();
- if (context && renderbuffer)
- {
- gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
-
- if (renderbufferObject)
- {
- return GL_TRUE;
- }
- }
-
- return GL_FALSE;
+ return gl::IsRenderbuffer(renderbuffer);
}
GLboolean GL_APIENTRY glIsShader(GLuint shader)
{
- EVENT("(GLuint shader = %d)", shader);
-
- gl::Context *context = gl::getNonLostContext();
- if (context && shader)
- {
- gl::Shader *shaderObject = context->getShader(shader);
-
- if (shaderObject)
- {
- return GL_TRUE;
- }
- }
-
- return GL_FALSE;
+ return gl::IsShader(shader);
}
GLboolean GL_APIENTRY glIsTexture(GLuint texture)
{
- EVENT("(GLuint texture = %d)", texture);
-
- gl::Context *context = gl::getNonLostContext();
- if (context && texture)
- {
- gl::Texture *textureObject = context->getTexture(texture);
-
- if (textureObject)
- {
- return GL_TRUE;
- }
- }
-
- return GL_FALSE;
+ return gl::IsTexture(texture);
}
void GL_APIENTRY glLineWidth(GLfloat width)
{
- EVENT("(GLfloat width = %f)", width);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (width <= 0.0f)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->getState().setLineWidth(width);
- }
+ return gl::LineWidth(width);
}
void GL_APIENTRY glLinkProgram(GLuint program)
{
- EVENT("(GLuint program = %d)", program);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- gl::Error error = context->linkProgram(program);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::LinkProgram(program);
}
void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
{
- EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- switch (pname)
- {
- case GL_UNPACK_ALIGNMENT:
- if (param != 1 && param != 2 && param != 4 && param != 8)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->getState().setUnpackAlignment(param);
- break;
-
- case GL_PACK_ALIGNMENT:
- if (param != 1 && param != 2 && param != 4 && param != 8)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->getState().setPackAlignment(param);
- break;
-
- case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
- context->getState().setPackReverseRowOrder(param != 0);
- break;
-
- case GL_UNPACK_IMAGE_HEIGHT:
- case GL_UNPACK_SKIP_IMAGES:
- case GL_UNPACK_ROW_LENGTH:
- 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:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- UNIMPLEMENTED();
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::PixelStorei(pname, param);
}
void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
{
- EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- context->getState().setPolygonOffsetParams(factor, units);
- }
-}
-
-void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLsizei bufSize,
- GLvoid *data)
-{
- EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
- "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)",
- x, y, width, height, format, type, bufSize, data);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (width < 0 || height < 0 || bufSize < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
- format, type, &bufSize, data))
- {
- return;
- }
-
- gl::Error error = context->readPixels(x, y, width, height, format, type, &bufSize, data);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
-}
-
-void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLvoid* pixels)
-{
- EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
- "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
- x, y, width, height, format, type, pixels);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (width < 0 || height < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (!gl::ValidateReadPixelsParameters(context, x, y, width, height,
- format, type, NULL, pixels))
- {
- return;
- }
-
- gl::Error error = context->readPixels(x, y, width, height, format, type, NULL, pixels);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::PolygonOffset(factor, units);
}
-void GL_APIENTRY glReleaseShaderCompiler(void)
+void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
{
- EVENT("()");
-
- gl::Context *context = gl::getNonLostContext();
-
- if (context)
- {
- context->releaseShaderCompiler();
- }
+ return gl::ReadPixels(x, y, width, height, format, type, pixels);
}
-void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+void GL_APIENTRY glReleaseShaderCompiler(void)
{
- EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
- target, samples, internalformat, width, height);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
- width, height, true))
- {
- return;
- }
-
- gl::Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
- gl::Error error = renderbuffer->setStorage(width, height, internalformat, samples);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::ReleaseShaderCompiler();
}
void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
- glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
+ return gl::RenderbufferStorage(target, internalformat, width, height);
}
-void GL_APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
+void GL_APIENTRY glSampleCoverage(GLfloat value, GLboolean invert)
{
- EVENT("(GLclampf value = %f, GLboolean invert = %u)", value, invert);
-
- gl::Context* context = gl::getNonLostContext();
-
- if (context)
- {
- context->getState().setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
- }
-}
-
-void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
-{
- EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (condition != GL_ALL_COMPLETED_NV)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::FenceNV *fenceObject = context->getFenceNV(fence);
-
- if (fenceObject == NULL)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- gl::Error error = fenceObject->setFence(condition);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::SampleCoverage(value, invert);
}
void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
- EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
-
- gl::Context* context = gl::getNonLostContext();
- if (context)
- {
- if (width < 0 || height < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->getState().setScissorParams(x, y, width, height);
- }
+ return gl::Scissor(x, y, width, height);
}
void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
{
- EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
- "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
- n, shaders, binaryformat, binary, length);
-
- gl::Context* context = gl::getNonLostContext();
- if (context)
- {
- const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
- if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) == shaderBinaryFormats.end())
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- // No binary shader formats are supported.
- UNIMPLEMENTED();
- }
+ return gl::ShaderBinary(n, shaders, binaryformat, binary, length);
}
void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length)
{
- EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
- shader, count, string, length);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (count < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Shader *shaderObject = context->getShader(shader);
-
- if (!shaderObject)
- {
- if (context->getProgram(shader))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- shaderObject->setSource(count, string, length);
- }
+ return gl::ShaderSource(shader, count, string, length);
}
void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
{
- glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
+ return gl::StencilFunc(func, ref, mask);
}
void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
{
- EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- switch (face)
- {
- case GL_FRONT:
- case GL_BACK:
- case GL_FRONT_AND_BACK:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- 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:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
- {
- context->getState().setStencilParams(func, ref, mask);
- }
-
- if (face == GL_BACK || face == GL_FRONT_AND_BACK)
- {
- context->getState().setStencilBackParams(func, ref, mask);
- }
- }
+ return gl::StencilFuncSeparate(face, func, ref, mask);
}
void GL_APIENTRY glStencilMask(GLuint mask)
{
- glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
+ return gl::StencilMask(mask);
}
void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
{
- EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- switch (face)
- {
- case GL_FRONT:
- case GL_BACK:
- case GL_FRONT_AND_BACK:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
- {
- context->getState().setStencilWritemask(mask);
- }
-
- if (face == GL_BACK || face == GL_FRONT_AND_BACK)
- {
- context->getState().setStencilBackWritemask(mask);
- }
- }
+ return gl::StencilMaskSeparate(face, mask);
}
void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
{
- glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
+ return gl::StencilOp(fail, zfail, zpass);
}
void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
{
- EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
- face, fail, zfail, zpass);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- switch (face)
- {
- case GL_FRONT:
- case GL_BACK:
- case GL_FRONT_AND_BACK:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (fail)
- {
- 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:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (zfail)
- {
- 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:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (zpass)
- {
- 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:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
- {
- context->getState().setStencilOperations(fail, zfail, zpass);
- }
-
- if (face == GL_BACK || face == GL_FRONT_AND_BACK)
- {
- context->getState().setStencilBackOperations(fail, zfail, zpass);
- }
- }
+ return gl::StencilOpSeparate(face, fail, zfail, zpass);
}
-GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)
+void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
- EVENT("(GLuint fence = %d)", fence);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::FenceNV *fenceObject = context->getFenceNV(fence);
-
- if (fenceObject == NULL)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_TRUE;
- }
-
- if (fenceObject->isFence() != GL_TRUE)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_TRUE;
- }
-
- GLboolean result;
- gl::Error error = fenceObject->testFence(&result);
- if (error.isError())
- {
- context->recordError(error);
- return GL_TRUE;
- }
-
- return result;
- }
-
- return GL_TRUE;
-}
-
-void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
- GLint border, GLenum format, GLenum type, const GLvoid* pixels)
-{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
- "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
- target, level, internalformat, width, height, border, format, type, pixels);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3 &&
- !ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
- 0, 0, width, height, border, format, type, pixels))
- {
- return;
- }
-
- if (context->getClientVersion() >= 3 &&
- !ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
- 0, 0, 0, width, height, 1, border, format, type, pixels))
- {
- return;
- }
-
- switch (target)
- {
- case GL_TEXTURE_2D:
- {
- gl::Texture2D *texture = context->getTexture2D();
- gl::Error error = texture->setImage(level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
- gl::Error error = texture->setImage(target, level, width, height, internalformat, format, type, context->getState().getUnpackState(), pixels);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default: UNREACHABLE();
- }
- }
+ return gl::TexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
}
void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
{
- EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
- {
- return;
- }
-
- gl::Texture *texture = context->getTargetTexture(target);
-
- if (!texture)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (pname)
- {
- case GL_TEXTURE_WRAP_S: texture->getSamplerState().wrapS = gl::uiround<GLenum>(param); break;
- case GL_TEXTURE_WRAP_T: texture->getSamplerState().wrapT = gl::uiround<GLenum>(param); break;
- case GL_TEXTURE_WRAP_R: texture->getSamplerState().wrapR = gl::uiround<GLenum>(param); break;
- case GL_TEXTURE_MIN_FILTER: texture->getSamplerState().minFilter = gl::uiround<GLenum>(param); break;
- case GL_TEXTURE_MAG_FILTER: texture->getSamplerState().magFilter = gl::uiround<GLenum>(param); break;
- case GL_TEXTURE_USAGE_ANGLE: texture->setUsage(gl::uiround<GLenum>(param)); break;
- case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->getSamplerState().maxAnisotropy = std::min(param, context->getExtensions().maxTextureAnisotropy); break;
- case GL_TEXTURE_COMPARE_MODE: texture->getSamplerState().compareMode = gl::uiround<GLenum>(param); break;
- case GL_TEXTURE_COMPARE_FUNC: texture->getSamplerState().compareFunc = gl::uiround<GLenum>(param); break;
- case GL_TEXTURE_SWIZZLE_R: texture->getSamplerState().swizzleRed = gl::uiround<GLenum>(param); break;
- case GL_TEXTURE_SWIZZLE_G: texture->getSamplerState().swizzleGreen = gl::uiround<GLenum>(param); break;
- case GL_TEXTURE_SWIZZLE_B: texture->getSamplerState().swizzleBlue = gl::uiround<GLenum>(param); break;
- case GL_TEXTURE_SWIZZLE_A: texture->getSamplerState().swizzleAlpha = gl::uiround<GLenum>(param); break;
- case GL_TEXTURE_BASE_LEVEL: texture->getSamplerState().baseLevel = gl::iround<GLint>(param); break;
- case GL_TEXTURE_MAX_LEVEL: texture->getSamplerState().maxLevel = gl::iround<GLint>(param); break;
- case GL_TEXTURE_MIN_LOD: texture->getSamplerState().minLod = param; break;
- case GL_TEXTURE_MAX_LOD: texture->getSamplerState().maxLod = param; break;
- default: UNREACHABLE(); break;
- }
- }
+ return gl::TexParameterf(target, pname, param);
}
void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
{
- glTexParameterf(target, pname, (GLfloat)*params);
+ return gl::TexParameterfv(target, pname, params);
}
void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
{
- EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateTexParamParameters(context, pname, param))
- {
- return;
- }
-
- gl::Texture *texture = context->getTargetTexture(target);
-
- if (!texture)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (pname)
- {
- case GL_TEXTURE_WRAP_S: texture->getSamplerState().wrapS = (GLenum)param; break;
- case GL_TEXTURE_WRAP_T: texture->getSamplerState().wrapT = (GLenum)param; break;
- case GL_TEXTURE_WRAP_R: texture->getSamplerState().wrapR = (GLenum)param; break;
- case GL_TEXTURE_MIN_FILTER: texture->getSamplerState().minFilter = (GLenum)param; break;
- case GL_TEXTURE_MAG_FILTER: texture->getSamplerState().magFilter = (GLenum)param; break;
- case GL_TEXTURE_USAGE_ANGLE: texture->setUsage((GLenum)param); break;
- case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->getSamplerState().maxAnisotropy = std::min((float)param, context->getExtensions().maxTextureAnisotropy); break;
- case GL_TEXTURE_COMPARE_MODE: texture->getSamplerState().compareMode = (GLenum)param; break;
- case GL_TEXTURE_COMPARE_FUNC: texture->getSamplerState().compareFunc = (GLenum)param; break;
- case GL_TEXTURE_SWIZZLE_R: texture->getSamplerState().swizzleRed = (GLenum)param; break;
- case GL_TEXTURE_SWIZZLE_G: texture->getSamplerState().swizzleGreen = (GLenum)param; break;
- case GL_TEXTURE_SWIZZLE_B: texture->getSamplerState().swizzleBlue = (GLenum)param; break;
- case GL_TEXTURE_SWIZZLE_A: texture->getSamplerState().swizzleAlpha = (GLenum)param; break;
- case GL_TEXTURE_BASE_LEVEL: texture->getSamplerState().baseLevel = param; break;
- case GL_TEXTURE_MAX_LEVEL: texture->getSamplerState().maxLevel = param; break;
- case GL_TEXTURE_MIN_LOD: texture->getSamplerState().minLod = (GLfloat)param; break;
- case GL_TEXTURE_MAX_LOD: texture->getSamplerState().maxLod = (GLfloat)param; break;
- default: UNREACHABLE(); break;
- }
- }
+ return gl::TexParameteri(target, pname, param);
}
void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
{
- glTexParameteri(target, pname, *params);
+ return gl::TexParameteriv(target, pname, params);
}
-void GL_APIENTRY glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
{
- EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
- target, levels, internalformat, width, height);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!context->getExtensions().textureStorage)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (context->getClientVersion() < 3 &&
- !ValidateES2TexStorageParameters(context, target, levels, internalformat, width, height))
- {
- return;
- }
-
- if (context->getClientVersion() >= 3 &&
- !ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
- {
- return;
- }
-
- switch (target)
- {
- case GL_TEXTURE_2D:
- {
- gl::Texture2D *texture2d = context->getTexture2D();
- gl::Error error = texture2d->storage(levels, internalformat, width, height);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_CUBE_MAP:
- {
- gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
- gl::Error error = textureCube->storage(levels, internalformat, width);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
-}
-
-void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid* pixels)
-{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
- "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
- "const GLvoid* pixels = 0x%0.8p)",
- target, level, xoffset, yoffset, width, height, format, type, pixels);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3 &&
- !ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true,
- xoffset, yoffset, width, height, 0, format, type, pixels))
- {
- return;
- }
-
- if (context->getClientVersion() >= 3 &&
- !ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
- xoffset, yoffset, 0, width, height, 1, 0, format, type, pixels))
- {
- return;
- }
-
- // Zero sized uploads are valid but no-ops
- if (width == 0 || height == 0)
- {
- return;
- }
-
- switch (target)
- {
- case GL_TEXTURE_2D:
- {
- gl::Texture2D *texture = context->getTexture2D();
- gl::Error error = texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
- gl::Error error = texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getState().getUnpackState(), pixels);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- UNREACHABLE();
- }
- }
+ return gl::TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
}
void GL_APIENTRY glUniform1f(GLint location, GLfloat x)
{
- glUniform1fv(location, 1, &x);
+ return gl::Uniform1f(location, x);
}
void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_FLOAT, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform1fv(location, count, v);
- }
+ return gl::Uniform1fv(location, count, v);
}
void GL_APIENTRY glUniform1i(GLint location, GLint x)
{
- glUniform1iv(location, 1, &x);
+ return gl::Uniform1i(location, x);
}
void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_INT, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform1iv(location, count, v);
- }
+ return gl::Uniform1iv(location, count, v);
}
void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
{
- GLfloat xy[2] = {x, y};
-
- glUniform2fv(location, 1, xy);
+ return gl::Uniform2f(location, x, y);
}
void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_FLOAT_VEC2, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform2fv(location, count, v);
- }
+ return gl::Uniform2fv(location, count, v);
}
void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y)
{
- GLint xy[2] = {x, y};
-
- glUniform2iv(location, 1, xy);
+ return gl::Uniform2i(location, x, y);
}
void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_INT_VEC2, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform2iv(location, count, v);
- }
+ return gl::Uniform2iv(location, count, v);
}
void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
{
- GLfloat xyz[3] = {x, y, z};
-
- glUniform3fv(location, 1, xyz);
+ return gl::Uniform3f(location, x, y, z);
}
void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_FLOAT_VEC3, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform3fv(location, count, v);
- }
+ return gl::Uniform3fv(location, count, v);
}
void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
{
- GLint xyz[3] = {x, y, z};
-
- glUniform3iv(location, 1, xyz);
+ return gl::Uniform3i(location, x, y, z);
}
void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_INT_VEC3, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform3iv(location, count, v);
- }
+ return gl::Uniform3iv(location, count, v);
}
void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
- GLfloat xyzw[4] = {x, y, z, w};
-
- glUniform4fv(location, 1, xyzw);
+ return gl::Uniform4f(location, x, y, z, w);
}
void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_FLOAT_VEC4, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform4fv(location, count, v);
- }
+ return gl::Uniform4fv(location, count, v);
}
void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
{
- GLint xyzw[4] = {x, y, z, w};
-
- glUniform4iv(location, 1, xyzw);
+ return gl::Uniform4i(location, x, y, z, w);
}
void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_INT_VEC4, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform4iv(location, count, v);
- }
+ return gl::Uniform4iv(location, count, v);
}
void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
- location, count, transpose, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix2fv(location, count, transpose, value);
- }
+ return gl::UniformMatrix2fv(location, count, transpose, value);
}
void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
- location, count, transpose, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix3fv(location, count, transpose, value);
- }
+ return gl::UniformMatrix3fv(location, count, transpose, value);
}
void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
- location, count, transpose, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix4fv(location, count, transpose, value);
- }
+ return gl::UniformMatrix4fv(location, count, transpose, value);
}
void GL_APIENTRY glUseProgram(GLuint program)
{
- EVENT("(GLuint program = %d)", program);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject && program != 0)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- if (program != 0 && !programObject->isLinked())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- context->useProgram(program);
- }
+ return gl::UseProgram(program);
}
void GL_APIENTRY glValidateProgram(GLuint program)
{
- EVENT("(GLuint program = %d)", program);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- programObject->validate(context->getCaps());
- }
+ return gl::ValidateProgram(program);
}
-void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
+void GL_APIENTRY glVertexAttrib1f(GLuint indx, GLfloat x)
{
- EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- GLfloat vals[4] = { x, 0, 0, 1 };
- context->getState().setVertexAttribf(index, vals);
- }
+ return gl::VertexAttrib1f(indx, x);
}
-void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
+void GL_APIENTRY glVertexAttrib1fv(GLuint indx, const GLfloat* values)
{
- EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- GLfloat vals[4] = { values[0], 0, 0, 1 };
- context->getState().setVertexAttribf(index, vals);
- }
+ return gl::VertexAttrib1fv(indx, values);
}
-void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
+void GL_APIENTRY glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
{
- EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- GLfloat vals[4] = { x, y, 0, 1 };
- context->getState().setVertexAttribf(index, vals);
- }
+ return gl::VertexAttrib2f(indx, x, y);
}
-void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
+void GL_APIENTRY glVertexAttrib2fv(GLuint indx, const GLfloat* values)
{
- EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- GLfloat vals[4] = { values[0], values[1], 0, 1 };
- context->getState().setVertexAttribf(index, vals);
- }
+ return gl::VertexAttrib2fv(indx, values);
}
-void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+void GL_APIENTRY glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
{
- EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- GLfloat vals[4] = { x, y, z, 1 };
- context->getState().setVertexAttribf(index, vals);
- }
+ return gl::VertexAttrib3f(indx, x, y, z);
}
-void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
+void GL_APIENTRY glVertexAttrib3fv(GLuint indx, const GLfloat* values)
{
- EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- GLfloat vals[4] = { values[0], values[1], values[2], 1 };
- context->getState().setVertexAttribf(index, vals);
- }
+ return gl::VertexAttrib3fv(indx, values);
}
-void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+void GL_APIENTRY glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
- EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- GLfloat vals[4] = { x, y, z, w };
- context->getState().setVertexAttribf(index, vals);
- }
+ return gl::VertexAttrib4f(indx, x, y, z, w);
}
-void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
+void GL_APIENTRY glVertexAttrib4fv(GLuint indx, const GLfloat* values)
{
- EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->getState().setVertexAttribf(index, values);
- }
+ return gl::VertexAttrib4fv(indx, values);
}
-void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+void GL_APIENTRY glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
{
- EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->setVertexAttribDivisor(index, divisor);
- }
-}
-
-void GL_APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
-{
- EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
- "GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
- index, size, type, normalized, stride, ptr);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (size < 1 || size > 4)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- switch (type)
- {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- case GL_FIXED:
- case GL_FLOAT:
- break;
-
- case GL_HALF_FLOAT:
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_INT_2_10_10_10_REV:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (stride < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // [OpenGL ES 3.0.2] Section 2.8 page 24:
- // An INVALID_OPERATION error is generated when a non-zero vertex array object
- // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
- // and the pointer argument is not NULL.
- if (context->getState().getVertexArray()->id() != 0 && context->getState().getArrayBufferId() == 0 && ptr != NULL)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type,
- normalized == GL_TRUE, false, stride, ptr);
- }
+ return gl::VertexAttribPointer(indx, size, type, normalized, stride, ptr);
}
void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
- EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (width < 0 || height < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->getState().setViewportParams(x, y, width, height);
- }
+ return gl::Viewport(x, y, width, height);
}
-// OpenGL ES 3.0 functions
-
void GL_APIENTRY glReadBuffer(GLenum mode)
{
- EVENT("(GLenum mode = 0x%X)", mode);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // glReadBuffer
- UNIMPLEMENTED();
- }
+ return gl::ReadBuffer(mode);
}
void GL_APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices)
{
- EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, "
- "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // glDrawRangeElements
- UNIMPLEMENTED();
- }
+ return gl::DrawRangeElements(mode, start, end, count, type, indices);
}
void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
- "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, "
- "GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
- target, level, internalformat, width, height, depth, border, format, type, pixels);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // validateES3TexImageFormat sets the error code if there is an error
- if (!ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
- 0, 0, 0, width, height, depth, border, format, type, pixels))
- {
- return;
- }
-
- switch(target)
- {
- case GL_TEXTURE_3D:
- {
- gl::Texture3D *texture = context->getTexture3D();
- gl::Error error = texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_2D_ARRAY:
- {
- gl::Texture2DArray *texture = context->getTexture2DArray();
- gl::Error error = texture->setImage(level, width, height, depth, internalformat, format, type, context->getState().getUnpackState(), pixels);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
}
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 GLvoid* pixels)
{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
- "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
- "GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
- target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // validateES3TexImageFormat sets the error code if there is an error
- if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
- xoffset, yoffset, zoffset, width, height, depth, 0,
- format, type, pixels))
- {
- return;
- }
-
- // Zero sized uploads are valid but no-ops
- if (width == 0 || height == 0 || depth == 0)
- {
- return;
- }
-
- switch(target)
- {
- case GL_TEXTURE_3D:
- {
- gl::Texture3D *texture = context->getTexture3D();
- gl::Error error = texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_2D_ARRAY:
- {
- gl::Texture2DArray *texture = context->getTexture2DArray();
- gl::Error error = texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getState().getUnpackState(), pixels);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
- "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
- target, level, xoffset, yoffset, zoffset, x, y, width, height);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset,
- x, y, width, height, 0))
- {
- return;
- }
-
- gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
- gl::Texture *texture = NULL;
- switch (target)
- {
- case GL_TEXTURE_3D:
- texture = context->getTexture3D();
- break;
-
- case GL_TEXTURE_2D_ARRAY:
- texture = context->getTexture2DArray();
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Error error = texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
}
void GL_APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
- "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, "
- "const GLvoid* data = 0x%0.8p)",
- target, level, internalformat, width, height, depth, border, imageSize, data);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
- if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- // validateES3TexImageFormat sets the error code if there is an error
- if (!ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
- 0, 0, 0, width, height, depth, border, GL_NONE, GL_NONE, data))
- {
- return;
- }
-
- switch(target)
- {
- case GL_TEXTURE_3D:
- {
- gl::Texture3D *texture = context->getTexture3D();
- gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, context->getState().getUnpackState(), data);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_2D_ARRAY:
- {
- gl::Texture2DArray *texture = context->getTexture2DArray();
- gl::Error error = texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, context->getState().getUnpackState(), data);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ 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 GLvoid* data)
{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
- "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
- "GLenum format = 0x%X, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
- target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format);
- if (imageSize < 0 || static_cast<GLuint>(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height))
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (!data)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- // validateES3TexImageFormat sets the error code if there is an error
- if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
- 0, 0, 0, width, height, depth, 0, GL_NONE, GL_NONE, data))
- {
- return;
- }
-
- // Zero sized uploads are valid but no-ops
- if (width == 0 || height == 0)
- {
- return;
- }
-
- switch(target)
- {
- case GL_TEXTURE_3D:
- {
- gl::Texture3D *texture = context->getTexture3D();
- gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
- format, imageSize, context->getState().getUnpackState(), data);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_2D_ARRAY:
- {
- gl::Texture2DArray *texture = context->getTexture2DArray();
- gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth,
- format, imageSize, context->getState().getUnpackState(), data);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
}
void GL_APIENTRY glGenQueries(GLsizei n, GLuint* ids)
{
- EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (GLsizei i = 0; i < n; i++)
- {
- ids[i] = context->createQuery();
- }
- }
+ return gl::GenQueries(n, ids);
}
void GL_APIENTRY glDeleteQueries(GLsizei n, const GLuint* ids)
{
- EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (GLsizei i = 0; i < n; i++)
- {
- context->deleteQuery(ids[i]);
- }
- }
+ return gl::DeleteQueries(n, ids);
}
GLboolean GL_APIENTRY glIsQuery(GLuint id)
{
- EVENT("(GLuint id = %u)", id);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_FALSE;
- }
-
- return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
- }
-
- return GL_FALSE;
+ return gl::IsQuery(id);
}
void GL_APIENTRY glBeginQuery(GLenum target, GLuint id)
{
- EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!ValidateBeginQuery(context, target, id))
- {
- return;
- }
-
- gl::Error error = context->beginQuery(target, id);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::BeginQuery(target, id);
}
void GL_APIENTRY glEndQuery(GLenum target)
{
- EVENT("(GLenum target = 0x%X)", target);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!ValidateEndQuery(context, target))
- {
- return;
- }
-
- gl::Error error = context->endQuery(target);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::EndQuery(target);
}
void GL_APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint* params)
{
- EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!ValidQueryType(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (pname)
- {
- case GL_CURRENT_QUERY:
- params[0] = static_cast<GLint>(context->getState().getActiveQueryId(target));
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::GetQueryiv(target, pname, params);
}
void GL_APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
{
- EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- gl::Query *queryObject = context->getQuery(id, false, GL_NONE);
-
- if (!queryObject)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (context->getState().getActiveQueryId(queryObject->getType()) == id)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- switch(pname)
- {
- case GL_QUERY_RESULT_EXT:
- {
- gl::Error error = queryObject->getResult(params);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_QUERY_RESULT_AVAILABLE_EXT:
- {
- gl::Error error = queryObject->isResultAvailable(params);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::GetQueryObjectuiv(id, pname, params);
}
GLboolean GL_APIENTRY glUnmapBuffer(GLenum target)
{
- EVENT("(GLenum target = 0x%X)", target);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_FALSE;
- }
-
- return glUnmapBufferOES(target);
- }
-
- return GL_FALSE;
+ return gl::UnmapBuffer(target);
}
void GL_APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
{
- EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- glGetBufferPointervOES(target, pname, params);
- }
+ return gl::GetBufferPointerv(target, pname, params);
}
void GL_APIENTRY glDrawBuffers(GLsizei n, const GLenum* bufs)
{
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- glDrawBuffersEXT(n, bufs);
- }
+ return gl::DrawBuffers(n, bufs);
}
void GL_APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
- location, count, transpose, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix2x3fv(location, count, transpose, value);
- }
+ return gl::UniformMatrix2x3fv(location, count, transpose, value);
}
void GL_APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
- location, count, transpose, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix3x2fv(location, count, transpose, value);
- }
+ return gl::UniformMatrix3x2fv(location, count, transpose, value);
}
void GL_APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
- location, count, transpose, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix2x4fv(location, count, transpose, value);
- }
+ return gl::UniformMatrix2x4fv(location, count, transpose, value);
}
void GL_APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
- location, count, transpose, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix4x2fv(location, count, transpose, value);
- }
+ return gl::UniformMatrix4x2fv(location, count, transpose, value);
}
void GL_APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
- location, count, transpose, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix3x4fv(location, count, transpose, value);
- }
+ return gl::UniformMatrix3x4fv(location, count, transpose, value);
}
void GL_APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
- location, count, transpose, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniformMatrix4x3fv(location, count, transpose, value);
- }
+ return gl::UniformMatrix4x3fv(location, count, transpose, value);
}
void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
- EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = %d, "
- "GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
- srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1, mask, filter,
- false))
- {
- return;
- }
-
- gl::Error error = context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
- mask, filter);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}
void GL_APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
- EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
- target, samples, internalformat, width, height);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat,
- width, height, false))
- {
- return;
- }
-
- gl::Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
- renderbuffer->setStorage(width, height, internalformat, samples);
- }
+ return gl::RenderbufferStorageMultisample(target, samples, internalformat, width, height);
}
void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
{
- EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)",
- target, attachment, texture, level, layer);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateFramebufferTextureLayer(context, target, attachment, texture,
- level, layer))
- {
- return;
- }
-
- gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
- ASSERT(framebuffer);
-
- if (texture != 0)
- {
- gl::Texture *textureObject = context->getTexture(texture);
- gl::ImageIndex index(textureObject->getTarget(), level, layer);
- framebuffer->setTextureAttachment(attachment, textureObject, index);
- }
- else
- {
- framebuffer->setNULLAttachment(attachment);
- }
- }
+ return gl::FramebufferTextureLayer(target, attachment, texture, level, layer);
}
GLvoid* GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
{
- EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
- target, offset, length, access);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return NULL;
- }
-
- return glMapBufferRangeEXT(target, offset, length, access);
- }
-
- return NULL;
+ return gl::MapBufferRange(target, offset, length, access);
}
void GL_APIENTRY glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
{
- EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- glFlushMappedBufferRangeEXT(target, offset, length);
- }
+ return gl::FlushMappedBufferRange(target, offset, length);
}
void GL_APIENTRY glBindVertexArray(GLuint array)
{
- EVENT("(GLuint array = %u)", array);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- gl::VertexArray *vao = context->getVertexArray(array);
-
- if (!vao)
- {
- // The default VAO should always exist
- ASSERT(array != 0);
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- context->bindVertexArray(array);
- }
+ return gl::BindVertexArray(array);
}
void GL_APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint* arrays)
{
- EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
- {
- if (arrays[arrayIndex] != 0)
- {
- context->deleteVertexArray(arrays[arrayIndex]);
- }
- }
- }
+ return gl::DeleteVertexArrays(n, arrays);
}
void GL_APIENTRY glGenVertexArrays(GLsizei n, GLuint* arrays)
{
- EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (n < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
- {
- arrays[arrayIndex] = context->createVertexArray();
- }
- }
+ return gl::GenVertexArrays(n, arrays);
}
GLboolean GL_APIENTRY glIsVertexArray(GLuint array)
{
- EVENT("(GLuint array = %u)", array);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_FALSE;
- }
-
- if (array == 0)
- {
- return GL_FALSE;
- }
-
- gl::VertexArray *vao = context->getVertexArray(array);
-
- return (vao != NULL ? GL_TRUE : GL_FALSE);
- }
-
- return GL_FALSE;
+ return gl::IsVertexArray(array);
}
void GL_APIENTRY glGetIntegeri_v(GLenum target, GLuint index, GLint* data)
{
- EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)",
- target, index, data);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- const gl::Caps &caps = context->getCaps();
- switch (target)
- {
- case GL_TRANSFORM_FEEDBACK_BUFFER_START:
- case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
- case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
- if (index >= caps.maxTransformFeedbackSeparateAttributes)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- case GL_UNIFORM_BUFFER_START:
- case GL_UNIFORM_BUFFER_SIZE:
- case GL_UNIFORM_BUFFER_BINDING:
- if (index >= caps.maxCombinedUniformBlocks)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (!(context->getIndexedIntegerv(target, index, data)))
- {
- GLenum nativeType;
- unsigned int numParams = 0;
- if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (numParams == 0)
- {
- return; // it is known that pname is valid, but there are no parameters to return
- }
-
- if (nativeType == GL_INT_64_ANGLEX)
- {
- GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<int>::min());
- GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<int>::max());
- GLint64 *int64Params = new GLint64[numParams];
-
- context->getIndexedInteger64v(target, index, int64Params);
-
- for (unsigned int i = 0; i < numParams; ++i)
- {
- GLint64 clampedValue = std::max(std::min(int64Params[i], maxIntValue), minIntValue);
- data[i] = static_cast<GLint>(clampedValue);
- }
-
- delete [] int64Params;
- }
- else
- {
- UNREACHABLE();
- }
- }
- }
+ return gl::GetIntegeri_v(target, index, data);
}
void GL_APIENTRY glBeginTransformFeedback(GLenum primitiveMode)
{
- EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- switch (primitiveMode)
- {
- case GL_TRIANGLES:
- case GL_LINES:
- case GL_POINTS:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
- ASSERT(transformFeedback != NULL);
-
- if (transformFeedback->isStarted())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (transformFeedback->isPaused())
- {
- transformFeedback->resume();
- }
- else
- {
- transformFeedback->start(primitiveMode);
- }
- }
+ return gl::BeginTransformFeedback(primitiveMode);
}
void GL_APIENTRY glEndTransformFeedback(void)
{
- EVENT("(void)");
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
- ASSERT(transformFeedback != NULL);
-
- if (!transformFeedback->isStarted())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- transformFeedback->stop();
- }
+ return gl::EndTransformFeedback();
}
void GL_APIENTRY glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
{
- EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)",
- target, index, buffer, offset, size);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- const gl::Caps &caps = context->getCaps();
- switch (target)
- {
- case GL_TRANSFORM_FEEDBACK_BUFFER:
- if (index >= caps.maxTransformFeedbackSeparateAttributes)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- case GL_UNIFORM_BUFFER:
- if (index >= caps.maxUniformBufferBindings)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (buffer != 0 && size <= 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- switch (target)
- {
- case GL_TRANSFORM_FEEDBACK_BUFFER:
-
- // size and offset must be a multiple of 4
- if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0))
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
- context->bindGenericTransformFeedbackBuffer(buffer);
- break;
-
- case GL_UNIFORM_BUFFER:
-
- // it is an error to bind an offset not a multiple of the alignment
- if (buffer != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->bindIndexedUniformBuffer(buffer, index, offset, size);
- context->bindGenericUniformBuffer(buffer);
- break;
-
- default:
- UNREACHABLE();
- }
- }
+ return gl::BindBufferRange(target, index, buffer, offset, size);
}
void GL_APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
- EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)",
- target, index, buffer);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- const gl::Caps &caps = context->getCaps();
- switch (target)
- {
- case GL_TRANSFORM_FEEDBACK_BUFFER:
- if (index >= caps.maxTransformFeedbackSeparateAttributes)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- case GL_UNIFORM_BUFFER:
- if (index >= caps.maxUniformBufferBindings)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- switch (target)
- {
- case GL_TRANSFORM_FEEDBACK_BUFFER:
- context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0);
- context->bindGenericTransformFeedbackBuffer(buffer);
- break;
-
- case GL_UNIFORM_BUFFER:
- context->bindIndexedUniformBuffer(buffer, index, 0, 0);
- context->bindGenericUniformBuffer(buffer);
- break;
-
- default:
- UNREACHABLE();
- }
- }
+ return gl::BindBufferBase(target, index, buffer);
}
void GL_APIENTRY glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
{
- EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)",
- program, count, varyings, bufferMode);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (count < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- const gl::Caps &caps = context->getCaps();
- switch (bufferMode)
- {
- case GL_INTERLEAVED_ATTRIBS:
- break;
- case GL_SEPARATE_ATTRIBS:
- if (static_cast<GLuint>(count) > caps.maxTransformFeedbackSeparateAttributes)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (!gl::ValidProgram(context, program))
- {
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
- ASSERT(programObject);
-
- programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
- }
+ return gl::TransformFeedbackVaryings(program, count, varyings, bufferMode);
}
void GL_APIENTRY glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
{
- EVENT("(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, "
- "GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
- program, index, bufSize, length, size, type, name);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (bufSize < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (!gl::ValidProgram(context, program))
- {
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
- ASSERT(programObject);
-
- if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
- }
+ return gl::GetTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
}
void GL_APIENTRY glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
{
- EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)",
- index, size, type, stride, pointer);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (size < 1 || size > 4)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- switch (type)
- {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_INT_2_10_10_10_REV:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (stride < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // [OpenGL ES 3.0.2] Section 2.8 page 24:
- // An INVALID_OPERATION error is generated when a non-zero vertex array object
- // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
- // and the pointer argument is not NULL.
- if (context->getState().getVertexArray()->id() != 0 && context->getState().getArrayBufferId() == 0 && pointer != NULL)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type, false, true,
- stride, pointer);
- }
+ return gl::VertexAttribIPointer(index, size, type, stride, pointer);
}
void GL_APIENTRY glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
{
- EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
- index, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
-
- if (!gl::ValidateGetVertexAttribParameters(context, pname))
- {
- return;
- }
-
- if (pname == GL_CURRENT_VERTEX_ATTRIB)
- {
- const gl::VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
- for (int i = 0; i < 4; ++i)
- {
- params[i] = currentValueData.IntValues[i];
- }
- }
- else
- {
- *params = gl::QuerySingleVertexAttributeParameter<GLint>(attribState, pname);
- }
- }
+ return gl::GetVertexAttribIiv(index, pname, params);
}
void GL_APIENTRY glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
{
- EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)",
- index, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- const gl::VertexAttribute &attribState = context->getState().getVertexAttribState(index);
-
- if (!gl::ValidateGetVertexAttribParameters(context, pname))
- {
- return;
- }
-
- if (pname == GL_CURRENT_VERTEX_ATTRIB)
- {
- const gl::VertexAttribCurrentValueData &currentValueData = context->getState().getVertexAttribCurrentValue(index);
- for (int i = 0; i < 4; ++i)
- {
- params[i] = currentValueData.UnsignedIntValues[i];
- }
- }
- else
- {
- *params = gl::QuerySingleVertexAttributeParameter<GLuint>(attribState, pname);
- }
- }
+ return gl::GetVertexAttribIuiv(index, pname, params);
}
void GL_APIENTRY glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
{
- EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
- index, x, y, z, w);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- GLint vals[4] = { x, y, z, w };
- context->getState().setVertexAttribi(index, vals);
- }
+ return gl::VertexAttribI4i(index, x, y, z, w);
}
void GL_APIENTRY glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
{
- EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)",
- index, x, y, z, w);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- GLuint vals[4] = { x, y, z, w };
- context->getState().setVertexAttribu(index, vals);
- }
+ return gl::VertexAttribI4ui(index, x, y, z, w);
}
void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint* v)
{
- EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->getState().setVertexAttribi(index, v);
- }
+ return gl::VertexAttribI4iv(index, v);
}
void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint* v)
{
- EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->getState().setVertexAttribu(index, v);
- }
+ return gl::VertexAttribI4uiv(index, v);
}
void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint* params)
{
- EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)",
- program, location, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateGetUniformuiv(context, program, location, params))
- {
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
- ASSERT(programObject);
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- ASSERT(programBinary);
-
- programBinary->getUniformuiv(location, params);
- }
+ return gl::GetUniformuiv(program, location, params);
}
GLint GL_APIENTRY glGetFragDataLocation(GLuint program, const GLchar *name)
{
- EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)",
- program, name);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return -1;
- }
-
- if (program == 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return -1;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject || !programObject->isLinked())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return -1;
- }
-
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programBinary)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return -1;
- }
-
- return programBinary->getFragDataLocation(name);
- }
-
- return 0;
+ return gl::GetFragDataLocation(program, name);
}
void GL_APIENTRY glUniform1ui(GLint location, GLuint v0)
{
- glUniform1uiv(location, 1, &v0);
+ return gl::Uniform1ui(location, v0);
}
void GL_APIENTRY glUniform2ui(GLint location, GLuint v0, GLuint v1)
{
- const GLuint xy[] = { v0, v1 };
- glUniform2uiv(location, 1, xy);
+ return gl::Uniform2ui(location, v0, v1);
}
void GL_APIENTRY glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
{
- const GLuint xyz[] = { v0, v1, v2 };
- glUniform3uiv(location, 1, xyz);
+ return gl::Uniform3ui(location, v0, v1, v2);
}
void GL_APIENTRY glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
{
- const GLuint xyzw[] = { v0, v1, v2, v3 };
- glUniform4uiv(location, 1, xyzw);
+ return gl::Uniform4ui(location, v0, v1, v2, v3);
}
void GL_APIENTRY glUniform1uiv(GLint location, GLsizei count, const GLuint* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
- location, count, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform1uiv(location, count, value);
- }
+ return gl::Uniform1uiv(location, count, value);
}
void GL_APIENTRY glUniform2uiv(GLint location, GLsizei count, const GLuint* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
- location, count, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform2uiv(location, count, value);
- }
+ return gl::Uniform2uiv(location, count, value);
}
void GL_APIENTRY glUniform3uiv(GLint location, GLsizei count, const GLuint* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)",
- location, count, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform3uiv(location, count, value);
- }
+ return gl::Uniform3uiv(location, count, value);
}
void GL_APIENTRY glUniform4uiv(GLint location, GLsizei count, const GLuint* value)
{
- EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
- location, count, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC4, location, count))
- {
- return;
- }
-
- gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
- programBinary->setUniform4uiv(location, count, value);
- }
+ return gl::Uniform4uiv(location, count, value);
}
void GL_APIENTRY glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value)
{
- EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint* value = 0x%0.8p)",
- buffer, drawbuffer, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateClearBuffer(context))
- {
- return;
- }
-
- switch (buffer)
- {
- case GL_COLOR:
- if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- case GL_STENCIL:
- if (drawbuffer != 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Error error = context->clearBufferiv(buffer, drawbuffer, value);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::ClearBufferiv(buffer, drawbuffer, value);
}
void GL_APIENTRY glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value)
{
- EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint* value = 0x%0.8p)",
- buffer, drawbuffer, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateClearBuffer(context))
- {
- return;
- }
-
- switch (buffer)
- {
- case GL_COLOR:
- if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Error error = context->clearBufferuiv(buffer, drawbuffer, value);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::ClearBufferuiv(buffer, drawbuffer, value);
}
void GL_APIENTRY glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value)
{
- EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat* value = 0x%0.8p)",
- buffer, drawbuffer, value);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateClearBuffer(context))
- {
- return;
- }
-
- switch (buffer)
- {
- case GL_COLOR:
- if (drawbuffer < 0 || static_cast<GLuint>(drawbuffer) >= context->getCaps().maxDrawBuffers)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- case GL_DEPTH:
- if (drawbuffer != 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Error error = context->clearBufferfv(buffer, drawbuffer, value);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::ClearBufferfv(buffer, drawbuffer, value);
}
void GL_APIENTRY glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
{
- EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth, GLint stencil = %d)",
- buffer, drawbuffer, depth, stencil);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateClearBuffer(context))
- {
- return;
- }
-
- switch (buffer)
- {
- case GL_DEPTH_STENCIL:
- if (drawbuffer != 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Error error = context->clearBufferfi(buffer, drawbuffer, depth, stencil);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::ClearBufferfi(buffer, drawbuffer, depth, stencil);
}
const GLubyte* GL_APIENTRY glGetStringi(GLenum name, GLuint index)
{
- EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return NULL;
- }
-
- if (name != GL_EXTENSIONS)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return NULL;
- }
-
- if (index >= context->getExtensionStringCount())
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return NULL;
- }
-
- return reinterpret_cast<const GLubyte*>(context->getExtensionString(index).c_str());
- }
-
- return NULL;
+ return gl::GetStringi(name, index);
}
void GL_APIENTRY glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
{
- EVENT("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)",
- readTarget, writeTarget, readOffset, writeOffset, size);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, writeTarget))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Buffer *readBuffer = context->getState().getTargetBuffer(readTarget);
- gl::Buffer *writeBuffer = context->getState().getTargetBuffer(writeTarget);
-
- if (!readBuffer || !writeBuffer)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // Verify that readBuffer and writeBuffer are not currently mapped
- if (readBuffer->isMapped() || writeBuffer->isMapped())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (readOffset < 0 || writeOffset < 0 || size < 0 ||
- static_cast<unsigned int>(readOffset + size) > readBuffer->getSize() ||
- static_cast<unsigned int>(writeOffset + size) > writeBuffer->getSize())
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (readBuffer == writeBuffer && std::abs(readOffset - writeOffset) < size)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- // if size is zero, the copy is a successful no-op
- if (size > 0)
- {
- gl::Error error = writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- }
+ return gl::CopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
}
void GL_APIENTRY glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices)
{
- EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLchar* const* uniformNames = 0x%0.8p, GLuint* uniformIndices = 0x%0.8p)",
- program, uniformCount, uniformNames, uniformIndices);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (uniformCount < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programObject->isLinked() || !programBinary)
- {
- for (int uniformId = 0; uniformId < uniformCount; uniformId++)
- {
- uniformIndices[uniformId] = GL_INVALID_INDEX;
- }
- }
- else
- {
- for (int uniformId = 0; uniformId < uniformCount; uniformId++)
- {
- uniformIndices[uniformId] = programBinary->getUniformIndex(uniformNames[uniformId]);
- }
- }
- }
+ return gl::GetUniformIndices(program, uniformCount, uniformNames, uniformIndices);
}
void GL_APIENTRY glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params)
{
- EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLuint* uniformIndices = 0x%0.8p, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
- program, uniformCount, uniformIndices, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (uniformCount < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- switch (pname)
- {
- case GL_UNIFORM_TYPE:
- case GL_UNIFORM_SIZE:
- case GL_UNIFORM_NAME_LENGTH:
- 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->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
- if (!programBinary && uniformCount > 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int uniformId = 0; uniformId < uniformCount; uniformId++)
- {
- const GLuint index = uniformIndices[uniformId];
-
- if (index >= (GLuint)programBinary->getActiveUniformCount())
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- for (int uniformId = 0; uniformId < uniformCount; uniformId++)
- {
- const GLuint index = uniformIndices[uniformId];
- params[uniformId] = programBinary->getActiveUniformi(index, pname);
- }
- }
+ return gl::GetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params);
}
GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName)
{
- EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_INVALID_INDEX;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_INVALID_INDEX;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return GL_INVALID_INDEX;
- }
- }
-
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
- if (!programBinary)
- {
- return GL_INVALID_INDEX;
- }
-
- return programBinary->getUniformBlockIndex(uniformBlockName);
- }
-
- return 0;
+ return gl::GetUniformBlockIndex(program, uniformBlockName);
}
void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params)
{
- EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
- program, uniformBlockIndex, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
- if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- switch (pname)
- {
- case GL_UNIFORM_BLOCK_BINDING:
- *params = static_cast<GLint>(programObject->getUniformBlockBinding(uniformBlockIndex));
- break;
-
- 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:
- programBinary->getActiveUniformBlockiv(uniformBlockIndex, pname, params);
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::GetActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
}
void GL_APIENTRY glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName)
{
- EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* uniformBlockName = 0x%0.8p)",
- program, uniformBlockIndex, bufSize, length, uniformBlockName);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
- if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- programBinary->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
- }
+ return gl::GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName);
}
void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{
- EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)",
- program, uniformBlockIndex, uniformBlockBinding);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject)
- {
- if (context->getShader(program))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- else
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- }
-
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
- // if never linked, there won't be any uniform blocks
- if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount())
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
- }
+ return gl::UniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
}
void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
{
- EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
- mode, first, count, instanceCount);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // glDrawArraysInstanced
- UNIMPLEMENTED();
- }
+ return gl::DrawArraysInstanced(mode, first, count, instanceCount);
}
void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount)
{
- EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei instanceCount = %d)",
- mode, count, type, indices, instanceCount);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // glDrawElementsInstanced
- UNIMPLEMENTED();
- }
+ return gl::DrawElementsInstanced(mode, count, type, indices, instanceCount);
}
GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags)
{
- EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return 0;
- }
-
- if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return 0;
- }
-
- if (flags != 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return 0;
- }
-
- GLsync fenceSync = context->createFenceSync();
-
- gl::FenceSync *fenceSyncObject = context->getFenceSync(fenceSync);
- gl::Error error = fenceSyncObject->set(condition);
- if (error.isError())
- {
- context->deleteFenceSync(fenceSync);
- context->recordError(error);
- return NULL;
- }
-
- return fenceSync;
- }
-
- return NULL;
+ return gl::FenceSync_(condition, flags);
}
GLboolean GL_APIENTRY glIsSync(GLsync sync)
{
- EVENT("(GLsync sync = 0x%0.8p)", sync);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_FALSE;
- }
-
- return (context->getFenceSync(sync) != NULL);
- }
-
- return GL_FALSE;
+ return gl::IsSync(sync);
}
void GL_APIENTRY glDeleteSync(GLsync sync)
{
- EVENT("(GLsync sync = 0x%0.8p)", sync);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (sync != static_cast<GLsync>(0) && !context->getFenceSync(sync))
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->deleteFenceSync(sync);
- }
+ return gl::DeleteSync(sync);
}
GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
- EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
- sync, flags, timeout);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_WAIT_FAILED;
- }
-
- if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return GL_WAIT_FAILED;
- }
-
- gl::FenceSync *fenceSync = context->getFenceSync(sync);
-
- if (!fenceSync)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return GL_WAIT_FAILED;
- }
-
- GLenum result = GL_WAIT_FAILED;
- gl::Error error = fenceSync->clientWait(flags, timeout, &result);
- if (error.isError())
- {
- context->recordError(error);
- return GL_WAIT_FAILED;
- }
-
- return result;
- }
-
- return GL_FALSE;
+ return gl::ClientWaitSync(sync, flags, timeout);
}
void GL_APIENTRY glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
- EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
- sync, flags, timeout);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (flags != 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (timeout != GL_TIMEOUT_IGNORED)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::FenceSync *fenceSync = context->getFenceSync(sync);
-
- if (!fenceSync)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::Error error = fenceSync->serverWait(flags, timeout);
- if (error.isError())
- {
- context->recordError(error);
- }
- }
+ return gl::WaitSync(sync, flags, timeout);
}
void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64* params)
{
- EVENT("(GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
- pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- GLenum nativeType;
- unsigned int numParams = 0;
- if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
- {
- return;
- }
-
- if (nativeType == GL_INT_64_ANGLEX)
- {
- context->getInteger64v(pname, params);
- }
- else
- {
- CastStateValues(context, nativeType, pname, numParams, params);
- }
- }
+ return gl::GetInteger64v(pname, params);
}
void GL_APIENTRY glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values)
{
- EVENT("(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLint* values = 0x%0.8p)",
- sync, pname, bufSize, length, values);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (bufSize < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- gl::FenceSync *fenceSync = context->getFenceSync(sync);
-
- if (!fenceSync)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- switch (pname)
- {
- case GL_OBJECT_TYPE: values[0] = static_cast<GLint>(GL_SYNC_FENCE); break;
- case GL_SYNC_CONDITION: values[0] = static_cast<GLint>(fenceSync->getCondition()); break;
- case GL_SYNC_FLAGS: values[0] = 0; break;
-
- case GL_SYNC_STATUS:
- {
- gl::Error error = fenceSync->getStatus(values);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- break;
- }
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::GetSynciv(sync, pname, bufSize, length, values);
}
void GL_APIENTRY glGetInteger64i_v(GLenum target, GLuint index, GLint64* data)
{
- EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64* data = 0x%0.8p)",
- target, index, data);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- const gl::Caps &caps = context->getCaps();
- switch (target)
- {
- case GL_TRANSFORM_FEEDBACK_BUFFER_START:
- case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
- case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
- if (index >= caps.maxTransformFeedbackSeparateAttributes)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- case GL_UNIFORM_BUFFER_START:
- case GL_UNIFORM_BUFFER_SIZE:
- case GL_UNIFORM_BUFFER_BINDING:
- if (index >= caps.maxUniformBufferBindings)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (!(context->getIndexedInteger64v(target, index, data)))
- {
- GLenum nativeType;
- unsigned int numParams = 0;
- if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (numParams == 0)
- return; // it is known that pname is valid, but there are no parameters to return
-
- if (nativeType == GL_INT)
- {
- GLint *intParams = new GLint[numParams];
-
- context->getIndexedIntegerv(target, index, intParams);
-
- for (unsigned int i = 0; i < numParams; ++i)
- {
- data[i] = static_cast<GLint64>(intParams[i]);
- }
-
- delete [] intParams;
- }
- else
- {
- UNREACHABLE();
- }
- }
- }
+ return gl::GetInteger64i_v(target, index, data);
}
void GL_APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params)
{
- EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
- target, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!gl::ValidBufferTarget(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (!gl::ValidBufferParameter(context, pname))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Buffer *buffer = context->getState().getTargetBuffer(target);
-
- if (!buffer)
- {
- // A null buffer means that "0" is bound to the requested buffer target
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- switch (pname)
- {
- case GL_BUFFER_USAGE:
- *params = static_cast<GLint64>(buffer->getUsage());
- break;
- case GL_BUFFER_SIZE:
- *params = buffer->getSize();
- break;
- case GL_BUFFER_ACCESS_FLAGS:
- *params = static_cast<GLint64>(buffer->getAccessFlags());
- break;
- case GL_BUFFER_MAPPED:
- *params = static_cast<GLint64>(buffer->isMapped());
- break;
- case GL_BUFFER_MAP_OFFSET:
- *params = buffer->getMapOffset();
- break;
- case GL_BUFFER_MAP_LENGTH:
- *params = buffer->getMapLength();
- break;
- default: UNREACHABLE(); break;
- }
- }
+ return gl::GetBufferParameteri64v(target, pname, params);
}
void GL_APIENTRY glGenSamplers(GLsizei count, GLuint* samplers)
{
- EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (count < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < count; i++)
- {
- samplers[i] = context->createSampler();
- }
- }
+ return gl::GenSamplers(count, samplers);
}
void GL_APIENTRY glDeleteSamplers(GLsizei count, const GLuint* samplers)
{
- EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (count < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- for (int i = 0; i < count; i++)
- {
- context->deleteSampler(samplers[i]);
- }
- }
+ return gl::DeleteSamplers(count, samplers);
}
GLboolean GL_APIENTRY glIsSampler(GLuint sampler)
{
- EVENT("(GLuint sampler = %u)", sampler);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_FALSE;
- }
-
- return context->isSampler(sampler);
- }
-
- return GL_FALSE;
+ return gl::IsSampler(sampler);
}
void GL_APIENTRY glBindSampler(GLuint unit, GLuint sampler)
{
- EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (sampler != 0 && !context->isSampler(sampler))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (unit >= context->getCaps().maxCombinedTextureImageUnits)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- context->bindSampler(unit, sampler);
- }
+ return gl::BindSampler(unit, sampler);
}
void GL_APIENTRY glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
{
- EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!gl::ValidateSamplerObjectParameter(context, pname))
- {
- return;
- }
-
- if (!gl::ValidateTexParamParameters(context, pname, param))
- {
- return;
- }
-
- if (!context->isSampler(sampler))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- context->samplerParameteri(sampler, pname, param);
- }
+ return gl::SamplerParameteri(sampler, pname, param);
}
void GL_APIENTRY glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param)
{
- glSamplerParameteri(sampler, pname, *param);
+ return gl::SamplerParameteriv(sampler, pname, param);
}
void GL_APIENTRY glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
{
- EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!gl::ValidateSamplerObjectParameter(context, pname))
- {
- return;
- }
-
- if (!gl::ValidateTexParamParameters(context, pname, static_cast<GLint>(param)))
- {
- return;
- }
-
- if (!context->isSampler(sampler))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- context->samplerParameterf(sampler, pname, param);
- }
+ return gl::SamplerParameterf(sampler, pname, param);
}
void GL_APIENTRY glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param)
{
- glSamplerParameterf(sampler, pname, *param);
+ return gl::SamplerParameterfv(sampler, pname, param);
}
void GL_APIENTRY glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params)
{
- EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params);
+ return gl::GetSamplerParameteriv(sampler, pname, params);
+}
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
+{
+ return gl::GetSamplerParameterfv(sampler, pname, params);
+}
- if (!gl::ValidateSamplerObjectParameter(context, pname))
- {
- return;
- }
+void GL_APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor)
+{
+ return gl::VertexAttribDivisor(index, divisor);
+}
- if (!context->isSampler(sampler))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id)
+{
+ return gl::BindTransformFeedback(target, id);
+}
- *params = context->getSamplerParameteri(sampler, pname);
- }
+void GL_APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
+{
+ return gl::DeleteTransformFeedbacks(n, ids);
}
-void GL_APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
+void GL_APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint* ids)
{
- EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params);
+ return gl::GenTransformFeedbacks(n, ids);
+}
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+GLboolean GL_APIENTRY glIsTransformFeedback(GLuint id)
+{
+ return gl::IsTransformFeedback(id);
+}
- if (!gl::ValidateSamplerObjectParameter(context, pname))
- {
- return;
- }
+void GL_APIENTRY glPauseTransformFeedback(void)
+{
+ return gl::PauseTransformFeedback();
+}
- if (!context->isSampler(sampler))
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glResumeTransformFeedback(void)
+{
+ return gl::ResumeTransformFeedback();
+}
- *params = context->getSamplerParameterf(sampler, pname);
- }
+void GL_APIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)
+{
+ return gl::GetProgramBinary(program, bufSize, length, binaryFormat, binary);
}
-void GL_APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor)
+void GL_APIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length)
{
- EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor);
+ return gl::ProgramBinary(program, binaryFormat, binary, length);
+}
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value)
+{
+ return gl::ProgramParameteri(program, pname, value);
+}
- if (index >= gl::MAX_VERTEX_ATTRIBS)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
+void GL_APIENTRY glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments)
+{
+ return gl::InvalidateFramebuffer(target, numAttachments, attachments);
+}
- context->setVertexAttribDivisor(index, divisor);
- }
+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);
}
-void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id)
+void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
- EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- 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)
- gl::TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback();
- if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section 2.14.1)
- if (context->getTransformFeedback(id) == NULL)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- context->bindTransformFeedback(id);
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::TexStorage2D(target, levels, internalformat, width, height);
}
-void GL_APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
+void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
- EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids);
+ return gl::TexStorage3D(target, levels, internalformat, width, height, depth);
+}
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
+{
+ return gl::GetInternalformativ(target, internalformat, pname, bufSize, params);
+}
- for (int i = 0; i < n; i++)
- {
- context->deleteTransformFeedback(ids[i]);
- }
- }
+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);
}
-void GL_APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint* ids)
+void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
- EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
+ return gl::RenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height);
+}
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
+{
+ return gl::DeleteFencesNV(n, fences);
+}
- for (int i = 0; i < n; i++)
- {
- ids[i] = context->createTransformFeedback();
- }
- }
+void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
+{
+ return gl::GenFencesNV(n, fences);
}
-GLboolean GL_APIENTRY glIsTransformFeedback(GLuint id)
+GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)
{
- EVENT("(GLuint id = %u)", id);
+ return gl::IsFenceNV(fence);
+}
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_FALSE;
- }
+GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)
+{
+ return gl::TestFenceNV(fence);
+}
- return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE);
- }
+void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+ return gl::GetFenceivNV(fence, pname, params);
+}
- return GL_FALSE;
+void GL_APIENTRY glFinishFenceNV(GLuint fence)
+{
+ return gl::FinishFenceNV(fence);
}
-void GL_APIENTRY glPauseTransformFeedback(void)
+void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
{
- EVENT("(void)");
+ return gl::SetFenceNV(fence, condition);
+}
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source)
+{
+ return gl::GetTranslatedShaderSourceANGLE(shader, bufsize, length, source);
+}
- gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
- ASSERT(transformFeedback != NULL);
+void GL_APIENTRY glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ return gl::TexStorage2DEXT(target, levels, internalformat, width, height);
+}
- // Current transform feedback must be started and not paused in order to pause (3.0.2 pg 86)
- if (!transformFeedback->isStarted() || transformFeedback->isPaused())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void)
+{
+ return gl::GetGraphicsResetStatusEXT();
+}
- transformFeedback->pause();
- }
+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);
}
-void GL_APIENTRY glResumeTransformFeedback(void)
+void GL_APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, float *params)
{
- EVENT("(void)");
+ return gl::GetnUniformfvEXT(program, location, bufSize, params);
+}
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint *params)
+{
+ return gl::GetnUniformivEXT(program, location, bufSize, params);
+}
- gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
- ASSERT(transformFeedback != NULL);
+void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint *ids)
+{
+ return gl::GenQueriesEXT(n, ids);
+}
- // Current transform feedback must be started and paused in order to resume (3.0.2 pg 86)
- if (!transformFeedback->isStarted() || !transformFeedback->isPaused())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
+{
+ return gl::DeleteQueriesEXT(n, ids);
+}
- transformFeedback->resume();
- }
+GLboolean GL_APIENTRY glIsQueryEXT(GLuint id)
+{
+ return gl::IsQueryEXT(id);
}
-void GL_APIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)
+void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint id)
{
- EVENT("(GLuint program = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLenum* binaryFormat = 0x%0.8p, GLvoid* binary = 0x%0.8p)",
- program, bufSize, length, binaryFormat, binary);
+ return gl::BeginQueryEXT(target, id);
+}
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glEndQueryEXT(GLenum target)
+{
+ return gl::EndQueryEXT(target);
+}
- // glGetProgramBinary
- UNIMPLEMENTED();
- }
+void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
+{
+ return gl::GetQueryivEXT(target, pname, params);
}
-void GL_APIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length)
+void GL_APIENTRY glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
{
- EVENT("(GLuint program = %u, GLenum binaryFormat = 0x%X, const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
- program, binaryFormat, binary, length);
+ return gl::GetQueryObjectuivEXT(id, pname, params);
+}
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
+{
+ return gl::DrawBuffersEXT(n, bufs);
+}
- // glProgramBinary
- UNIMPLEMENTED();
- }
+void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+{
+ return gl::DrawArraysInstancedANGLE(mode, first, count, primcount);
}
-void GL_APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value)
+void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount)
{
- EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)",
- program, pname, value);
+ return gl::DrawElementsInstancedANGLE(mode, count, type, indices, primcount);
+}
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
+void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+{
+ return gl::VertexAttribDivisorANGLE(index, divisor);
+}
- // glProgramParameteri
- UNIMPLEMENTED();
- }
+void GL_APIENTRY glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary)
+{
+ return gl::GetProgramBinaryOES(program, bufSize, length, binaryFormat, binary);
}
-void GL_APIENTRY glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments)
+void GL_APIENTRY glProgramBinaryOES(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length)
{
- EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p)",
- target, numAttachments, attachments);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
- {
- return;
- }
-
- gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
- ASSERT(framebuffer);
-
- if (framebuffer->completeness(context->getData()) == GL_FRAMEBUFFER_COMPLETE)
- {
- gl::Error error = framebuffer->invalidate(context->getCaps(), numAttachments, attachments);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- }
+ return gl::ProgramBinaryOES(program, binaryFormat, binary, length);
}
-void GL_APIENTRY glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height)
+void* GL_APIENTRY glMapBufferOES(GLenum target, GLenum access)
{
- EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p, GLint x = %d, "
- "GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
- target, numAttachments, attachments, x, y, width, height);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments))
- {
- return;
- }
-
- gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
- ASSERT(framebuffer);
-
- if (framebuffer->completeness(context->getData()) == GL_FRAMEBUFFER_COMPLETE)
- {
- gl::Error error = framebuffer->invalidateSub(numAttachments, attachments, x, y, width, height);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- }
+ return gl::MapBufferOES(target, access);
}
-void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+GLboolean GL_APIENTRY glUnmapBufferOES(GLenum target)
{
- EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
- target, levels, internalformat, width, height);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1))
- {
- return;
- }
-
- switch (target)
- {
- case GL_TEXTURE_2D:
- {
- gl::Texture2D *texture2d = context->getTexture2D();
- gl::Error error = texture2d->storage(levels, internalformat, width, height);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_CUBE_MAP:
- {
- gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
- gl::Error error = textureCube->storage(levels, internalformat, width);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
+ return gl::UnmapBufferOES(target);
}
-void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+void GL_APIENTRY glGetBufferPointervOES(GLenum target, GLenum pname, GLvoid **params)
{
- EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
- "GLsizei height = %d, GLsizei depth = %d)",
- target, levels, internalformat, width, height, depth);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, depth))
- {
- return;
- }
-
- switch (target)
- {
- case GL_TEXTURE_3D:
- {
- gl::Texture3D *texture3d = context->getTexture3D();
- gl::Error error = texture3d->storage(levels, internalformat, width, height, depth);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- case GL_TEXTURE_2D_ARRAY:
- {
- gl::Texture2DArray *texture2darray = context->getTexture2DArray();
- gl::Error error = texture2darray->storage(levels, internalformat, width, height, depth);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
- break;
-
- default:
- UNREACHABLE();
- }
- }
+ return gl::GetBufferPointervOES(target, pname, params);
}
-void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
+void* GL_APIENTRY glMapBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
{
- EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, "
- "GLint* params = 0x%0.8p)",
- target, internalformat, pname, bufSize, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (context->getClientVersion() < 3)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- const gl::TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
- if (!formatCaps.renderable)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (target != GL_RENDERBUFFER)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (bufSize < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- switch (pname)
- {
- case GL_NUM_SAMPLE_COUNTS:
- if (bufSize != 0)
- {
- *params = formatCaps.sampleCounts.size();
- }
- break;
-
- case GL_SAMPLES:
- std::copy_n(formatCaps.sampleCounts.rbegin(), std::min<size_t>(bufSize, formatCaps.sampleCounts.size()), params);
- break;
-
- default:
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
- }
-}
-
-// Extension functions
-
-void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
- "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
- "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
- srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1,
- dstX0, dstY0, dstX1, dstY1, mask, filter,
- true))
- {
- return;
- }
-
- gl::Error error = context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
- mask, filter);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
-}
-
-void GL_APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum format, GLenum type, const GLvoid* pixels)
-{
- EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
- "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
- "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
- target, level, internalformat, width, height, depth, border, format, type, pixels);
-
- UNIMPLEMENTED(); // FIXME
-}
-
-void GL_APIENTRY glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length,
- GLenum *binaryFormat, void *binary)
-{
- EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)",
- program, bufSize, length, binaryFormat, binary);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Program *programObject = context->getProgram(program);
-
- if (!programObject || !programObject->isLinked())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
- if (!programBinary)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- gl::Error error = programBinary->save(binaryFormat, binary, bufSize, length);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
-}
-
-void GL_APIENTRY glProgramBinaryOES(GLuint program, GLenum binaryFormat,
- const void *binary, GLint length)
-{
- EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)",
- program, binaryFormat, binary, length);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
- if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) == programBinaryFormats.end())
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Program *programObject = context->getProgram(program);
- if (!programObject)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- gl::Error error = context->setProgramBinary(program, binaryFormat, binary, length);
- if (error.isError())
- {
- context->recordError(error);
- return;
- }
- }
+ return gl::MapBufferRangeEXT(target, offset, length, access);
}
-void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
+void GL_APIENTRY glFlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length)
{
- EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (n < 0 || static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- ASSERT(context->getState().getDrawFramebuffer());
-
- if (context->getState().getDrawFramebuffer()->id() == 0)
- {
- if (n != 1)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- }
- else
- {
- for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
- {
- const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
- if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
- }
- }
-
- gl::Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
- ASSERT(framebuffer);
-
- for (unsigned int colorAttachment = 0; colorAttachment < static_cast<unsigned int>(n); colorAttachment++)
- {
- framebuffer->setDrawBufferState(colorAttachment, bufs[colorAttachment]);
- }
-
- for (unsigned int colorAttachment = n; colorAttachment < context->getCaps().maxDrawBuffers; colorAttachment++)
- {
- framebuffer->setDrawBufferState(colorAttachment, GL_NONE);
- }
- }
-}
-
-void GL_APIENTRY glGetBufferPointervOES(GLenum target, GLenum pname, void** params)
-{
- EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!gl::ValidBufferTarget(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- if (pname != GL_BUFFER_MAP_POINTER)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Buffer *buffer = context->getState().getTargetBuffer(target);
-
- if (!buffer || !buffer->isMapped())
- {
- *params = NULL;
- }
- else
- {
- *params = buffer->getMapPointer();
- }
- }
-}
-
-void * GL_APIENTRY glMapBufferOES(GLenum target, GLenum access)
-{
- EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!gl::ValidBufferTarget(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return NULL;
- }
-
- gl::Buffer *buffer = context->getState().getTargetBuffer(target);
-
- if (buffer == NULL)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return NULL;
- }
-
- if (access != GL_WRITE_ONLY_OES)
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return NULL;
- }
-
- if (buffer->isMapped())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return NULL;
- }
-
- gl::Error error = buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT);
- if (error.isError())
- {
- context->recordError(error);
- return NULL;
- }
-
- return buffer->getMapPointer();
- }
-
- return NULL;
+ return gl::FlushMappedBufferRangeEXT(target, offset, length);
}
-GLboolean GL_APIENTRY glUnmapBufferOES(GLenum target)
+void GL_APIENTRY SetTraceFunctionPointers(GetCategoryEnabledFlagFunc getCategoryEnabledFlag,
+ AddTraceEventFunc addTraceEvent)
{
- EVENT("(GLenum target = 0x%X)", target);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!gl::ValidBufferTarget(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return GL_FALSE;
- }
-
- gl::Buffer *buffer = context->getState().getTargetBuffer(target);
-
- if (buffer == NULL || !buffer->isMapped())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return GL_FALSE;
- }
-
- // TODO: detect if we had corruption. if so, throw an error and return false.
-
- gl::Error error = buffer->unmap();
- if (error.isError())
- {
- context->recordError(error);
- return GL_FALSE;
- }
-
- return GL_TRUE;
- }
-
- return GL_FALSE;
-}
-
-void* GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
-{
- EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
- target, offset, length, access);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (!gl::ValidBufferTarget(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return NULL;
- }
-
- if (offset < 0 || length < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return NULL;
- }
-
- gl::Buffer *buffer = context->getState().getTargetBuffer(target);
-
- if (buffer == NULL)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return NULL;
- }
-
- // Check for buffer overflow
- size_t offsetSize = static_cast<size_t>(offset);
- size_t lengthSize = static_cast<size_t>(length);
-
- if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
- offsetSize + lengthSize > static_cast<size_t>(buffer->getSize()))
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return NULL;
- }
-
- // Check for invalid bits in the mask
- GLbitfield allAccessBits = 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 (access & ~(allAccessBits))
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return NULL;
- }
-
- if (length == 0 || buffer->isMapped())
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return NULL;
- }
-
- // Check for invalid bit combinations
- if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return NULL;
- }
-
- 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->recordError(gl::Error(GL_INVALID_OPERATION));
- return NULL;
- }
-
- if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return NULL;
- }
-
- gl::Error error = buffer->mapRange(offset, length, access);
- if (error.isError())
- {
- context->recordError(error);
- return NULL;
- }
-
- return buffer->getMapPointer();
- }
-
- return NULL;
-}
-
-void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length)
-{
- EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- if (offset < 0 || length < 0)
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- if (!gl::ValidBufferTarget(context, target))
- {
- context->recordError(gl::Error(GL_INVALID_ENUM));
- return;
- }
-
- gl::Buffer *buffer = context->getState().getTargetBuffer(target);
-
- if (buffer == NULL)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
- {
- context->recordError(gl::Error(GL_INVALID_OPERATION));
- return;
- }
-
- // Check for buffer overflow
- size_t offsetSize = static_cast<size_t>(offset);
- size_t lengthSize = static_cast<size_t>(length);
-
- if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) ||
- offsetSize + lengthSize > static_cast<size_t>(buffer->getMapLength()))
- {
- context->recordError(gl::Error(GL_INVALID_VALUE));
- return;
- }
-
- // We do not currently support a non-trivial implementation of FlushMappedBufferRange
- }
-}
-
-__eglMustCastToProperFunctionPointerType EGLAPIENTRY glGetProcAddress(const char *procname)
-{
- struct Extension
- {
- const char *name;
- __eglMustCastToProperFunctionPointerType address;
- };
-
- static const Extension glExtensions[] =
- {
- {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
- {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
- {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
- {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
- {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
- {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
- {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
- {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
- {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
- {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
- {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE},
- {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT},
- {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT},
- {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT},
- {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT},
- {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT},
- {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT},
- {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT},
- {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT},
- {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT},
- {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
- {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
- {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
- {"glDrawBuffersEXT", (__eglMustCastToProperFunctionPointerType)glDrawBuffersEXT},
- {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE},
- {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE},
- {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE},
- {"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES},
- {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES},
- {"glGetBufferPointervOES", (__eglMustCastToProperFunctionPointerType)glGetBufferPointervOES},
- {"glMapBufferOES", (__eglMustCastToProperFunctionPointerType)glMapBufferOES},
- {"glUnmapBufferOES", (__eglMustCastToProperFunctionPointerType)glUnmapBufferOES},
- {"glMapBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)glMapBufferRangeEXT},
- {"glFlushMappedBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)glFlushMappedBufferRangeEXT}, };
-
- for (unsigned int ext = 0; ext < ArraySize(glExtensions); ext++)
- {
- if (strcmp(procname, glExtensions[ext].name) == 0)
- {
- return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
- }
- }
-
- return NULL;
-}
-
-// Non-public functions used by EGL
-
-bool EGLAPIENTRY glBindTexImage(egl::Surface *surface)
-{
- EVENT("(egl::Surface* surface = 0x%0.8p)",
- surface);
-
- gl::Context *context = gl::getNonLostContext();
- if (context)
- {
- gl::Texture2D *textureObject = context->getTexture2D();
- ASSERT(textureObject != NULL);
-
- if (textureObject->isImmutable())
- {
- return false;
- }
-
- textureObject->bindTexImage(surface);
- }
-
- return true;
+ gl::g_getCategoryEnabledFlag = getCategoryEnabledFlag;
+ gl::g_addTraceEvent = addTraceEvent;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
index 33557eb1c9..9c6dc497d0 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
@@ -144,7 +144,6 @@ EXPORTS
glViewport @142
; Extensions
- glTexImage3DOES @143
glBlitFramebufferANGLE @149
glRenderbufferStorageMultisampleANGLE @150
glDeleteFencesNV @151
@@ -285,12 +284,5 @@ EXPORTS
glTexStorage3D @282
glGetInternalformativ @283
- ; EGL dependencies
- glCreateContext @144 NONAME
- glDestroyContext @145 NONAME
- glMakeCurrent @146 NONAME
- glGetCurrentContext @147 NONAME
- glGetProcAddress @148 NONAME
- glBindTexImage @158 NONAME
- glCreateRenderer @177 NONAME
- glDestroyRenderer @178 NONAME
+ ; Setting up TRACE macro callbacks
+ SetTraceFunctionPointers @284
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.rc b/src/3rdparty/angle/src/libGLESv2/libGLESv2.rc
deleted file mode 100644
index 76cd05566e..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.rc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include <windows.h>
-#include "../common/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,0,0
- PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,0,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) 2011 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
-
-#endif // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
index 18ffcf6a0d..e02b85bcf2 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def
@@ -144,7 +144,6 @@ EXPORTS
glViewport@16 @142
; Extensions
- glTexImage3DOES@40 @143
glBlitFramebufferANGLE@40 @149
glRenderbufferStorageMultisampleANGLE@20 @150
glDeleteFencesNV@8 @151
@@ -285,12 +284,5 @@ EXPORTS
glTexStorage3D@24 @282
glGetInternalformativ@20 @283
- ; EGL dependencies
- glCreateContext @144 NONAME
- glDestroyContext @145 NONAME
- glMakeCurrent @146 NONAME
- glGetCurrentContext @147 NONAME
- glGetProcAddress@4 @148 NONAME
- glBindTexImage@4 @158 NONAME
- glCreateRenderer @177 NONAME
- glDestroyRenderer @178 NONAME
+ ; Setting up TRACE macro callbacks
+ SetTraceFunctionPointers@8 @284
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
index 120371e013..d35309c6ce 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
@@ -144,7 +144,6 @@ EXPORTS
glViewport @142
; Extensions
- glTexImage3DOES @143
glBlitFramebufferANGLE @149
glRenderbufferStorageMultisampleANGLE @150
glDeleteFencesNV @151
@@ -285,12 +284,5 @@ EXPORTS
glTexStorage3D @282
glGetInternalformativ @283
- ; EGL dependencies
- glCreateContext @144 NONAME
- glDestroyContext @145 NONAME
- glMakeCurrent @146 NONAME
- glGetCurrentContext @147 NONAME
- glGetProcAddress @148 NONAME
- glBindTexImage @158 NONAME
- glCreateRenderer @177 NONAME
- glDestroyRenderer @178 NONAME
+ ; Setting up TRACE macro callbacks
+ SetTraceFunctionPointers @284
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
index 8c1306a703..e2b2c333a1 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def
@@ -144,7 +144,6 @@ EXPORTS
glViewport@16 @142
; Extensions
- glTexImage3DOES@40 @143
glBlitFramebufferANGLE@40 @149
glRenderbufferStorageMultisampleANGLE@20 @150
glDeleteFencesNV@8 @151
@@ -285,12 +284,5 @@ EXPORTS
glTexStorage3D@24 @282
glGetInternalformativ@20 @283
- ; EGL dependencies
- glCreateContext @144 NONAME
- glDestroyContext @145 NONAME
- glMakeCurrent @146 NONAME
- glGetCurrentContext @147 NONAME
- glGetProcAddress@4 @148 NONAME
- glBindTexImage@4 @158 NONAME
- glCreateRenderer @177 NONAME
- glDestroyRenderer @178 NONAME
+ ; Setting up TRACE macro callbacks
+ SetTraceFunctionPointers@8 @284
diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
deleted file mode 100644
index 00f63ae079..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// main.cpp: DLL entry point and management of thread-local data.
-
-#include "libGLESv2/main.h"
-#include "libGLESv2/Context.h"
-
-#include "common/tls.h"
-
-static TLSIndex currentTLS = TLS_INVALID_INDEX;
-
-namespace gl
-{
-
-// TODO(kbr): figure out how these are going to be managed on
-// non-Windows platforms. These routines would need to be exported
-// from ANGLE and called cooperatively when users create and destroy
-// threads -- or the initialization of the TLS index, and allocation
-// of thread-local data, will have to be done lazily. Will have to use
-// destructor function with pthread_create_key on POSIX platforms to
-// clean up thread-local data.
-
-// Call this exactly once at process startup.
-bool CreateThreadLocalIndex()
-{
- currentTLS = CreateTLSIndex();
- if (currentTLS == TLS_INVALID_INDEX)
- {
- return false;
- }
- return true;
-}
-
-// Call this exactly once at process shutdown.
-void DestroyThreadLocalIndex()
-{
- DestroyTLSIndex(currentTLS);
- currentTLS = TLS_INVALID_INDEX;
-}
-
-// Call this upon thread startup.
-Current *AllocateCurrent()
-{
- ASSERT(currentTLS != TLS_INVALID_INDEX);
- if (currentTLS == TLS_INVALID_INDEX)
- {
- return NULL;
- }
-
- Current *current = new Current();
- current->context = NULL;
- current->display = NULL;
-
- if (!SetTLSValue(currentTLS, current))
- {
- ERR("Could not set thread local storage.");
- return NULL;
- }
-
- return current;
-}
-
-// Call this upon thread shutdown.
-void DeallocateCurrent()
-{
- Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
- SafeDelete(current);
- SetTLSValue(currentTLS, NULL);
-}
-
-}
-
-#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(QT_OPENGL_ES_2_ANGLE_STATIC)
-extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
-{
- switch (reason)
- {
- case DLL_PROCESS_ATTACH:
- {
- if (!gl::CreateThreadLocalIndex())
- {
- return FALSE;
- }
-
-#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
- gl::InitializeDebugAnnotations();
-#endif
- }
- // Fall through to initialize index
- case DLL_THREAD_ATTACH:
- {
- gl::AllocateCurrent();
- }
- break;
- case DLL_THREAD_DETACH:
- {
- gl::DeallocateCurrent();
- }
- break;
- case DLL_PROCESS_DETACH:
- {
- gl::DeallocateCurrent();
- gl::DestroyThreadLocalIndex();
-
-#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
- gl::UninitializeDebugAnnotations();
-#endif
- }
- break;
- default:
- break;
- }
-
- return TRUE;
-}
-#endif // ANGLE_PLATFORM_WINDOWS && !QT_OPENGL_ES_2_ANGLE_STATIC
-
-namespace gl
-{
-
-Current *GetCurrentData()
-{
-#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
- Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
-
- // ANGLE issue 488: when the dll is loaded after thread initialization,
- // thread local storage (current) might not exist yet.
- return (current ? current : AllocateCurrent());
-#else
- // No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
- static Current current = { 0, 0 };
- return &current;
-#endif
-}
-
-void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
-{
- Current *current = GetCurrentData();
-
- current->context = context;
- current->display = display;
-
- if (context && display && surface)
- {
- context->makeCurrent(surface);
- }
-}
-
-Context *getContext()
-{
- Current *current = GetCurrentData();
-
- return current->context;
-}
-
-Context *getNonLostContext()
-{
- Context *context = getContext();
-
- if (context)
- {
- if (context->isContextLost())
- {
- context->recordError(Error(GL_OUT_OF_MEMORY, "Context has been lost."));
- return NULL;
- }
- else
- {
- return context;
- }
- }
- return NULL;
-}
-
-egl::Display *getDisplay()
-{
- Current *current = GetCurrentData();
-
- return current->display;
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/main.h b/src/3rdparty/angle/src/libGLESv2/main.h
deleted file mode 100644
index dff02787f5..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/main.h
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// main.h: Management of thread-local data.
-
-#ifndef LIBGLESV2_MAIN_H_
-#define LIBGLESV2_MAIN_H_
-
-#include "common/debug.h"
-
-#include <GLES2/gl2.h>
-#include <EGL/egl.h>
-
-namespace egl
-{
-class Display;
-class Surface;
-class AttributeMap;
-}
-
-namespace gl
-{
-class Context;
-
-struct Current
-{
- Context *context;
- egl::Display *display;
-};
-
-void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface);
-
-Context *getContext();
-Context *getNonLostContext();
-egl::Display *getDisplay();
-
-}
-
-namespace rx
-{
-class Renderer;
-}
-
-extern "C"
-{
-// Exported functions for use by EGL
-gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
-void glDestroyContext(gl::Context *context);
-void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
-gl::Context *glGetCurrentContext();
-rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap);
-void glDestroyRenderer(rx::Renderer *renderer);
-
-__eglMustCastToProperFunctionPointerType EGLAPIENTRY glGetProcAddress(const char *procname);
-bool EGLAPIENTRY glBindTexImage(egl::Surface *surface);
-}
-
-#endif // LIBGLESV2_MAIN_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h
deleted file mode 100644
index 1dd46785d9..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) 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.
-//
-
-// FenceImpl.h: Defines the rx::FenceNVImpl and rx::FenceSyncImpl classes.
-
-#ifndef LIBGLESV2_RENDERER_FENCEIMPL_H_
-#define LIBGLESV2_RENDERER_FENCEIMPL_H_
-
-#include "libGLESv2/Error.h"
-
-#include "common/angleutils.h"
-
-#include "angle_gl.h"
-
-namespace rx
-{
-
-class FenceNVImpl
-{
- public:
- FenceNVImpl() { };
- virtual ~FenceNVImpl() { };
-
- virtual gl::Error set() = 0;
- virtual gl::Error test(bool flushCommandBuffer, GLboolean *outFinished) = 0;
- virtual gl::Error finishFence(GLboolean *outFinished) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FenceNVImpl);
-};
-
-class FenceSyncImpl
-{
- public:
- FenceSyncImpl() { };
- virtual ~FenceSyncImpl() { };
-
- virtual gl::Error set() = 0;
- virtual gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) = 0;
- virtual gl::Error serverWait(GLbitfield flags, GLuint64 timeout) = 0;
- virtual gl::Error getStatus(GLint *outResult) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FenceSyncImpl);
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_FENCEIMPL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp
deleted file mode 100644
index 5b9b75f562..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// 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 "libGLESv2/renderer/Image.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/main.h"
-
-namespace rx
-{
-
-Image::Image()
-{
- mWidth = 0;
- mHeight = 0;
- mDepth = 0;
- mInternalFormat = GL_NONE;
- mActualFormat = GL_NONE;
- mTarget = GL_NONE;
- mRenderable = false;
- mDirty = false;
-}
-
-gl::Error Image::copy(GLint xoffset, GLint yoffset, GLint zoffset, const gl::Rectangle &area, gl::Framebuffer *source)
-{
- gl::FramebufferAttachment *colorbuffer = source->getReadColorbuffer();
- ASSERT(colorbuffer);
-
- RenderTarget *renderTarget = NULL;
- gl::Error error = GetAttachmentRenderTarget(colorbuffer, &renderTarget);
- if (error.isError())
- {
- return error;
- }
-
- ASSERT(renderTarget);
- return copy(xoffset, yoffset, zoffset, area, renderTarget);
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp
deleted file mode 100644
index 857fdc9dae..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-//
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// RenderTarget.cpp: Implements serial handling for rx::RenderTarget
-
-#include "libGLESv2/renderer/RenderTarget.h"
-
-namespace rx
-{
-unsigned int RenderTarget::mCurrentSerial = 1;
-
-RenderTarget::RenderTarget()
- : mSerial(issueSerials(1))
-{
-}
-
-RenderTarget::~RenderTarget()
-{
-}
-
-unsigned int RenderTarget::getSerial() const
-{
- return mSerial;
-}
-
-unsigned int RenderTarget::issueSerials(unsigned int count)
-{
- unsigned int firstSerial = mCurrentSerial;
- mCurrentSerial += count;
- return firstSerial;
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h
deleted file mode 100644
index 3bdfb0cc98..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// RenderTarget.h: Defines an abstract wrapper class to manage IDirect3DSurface9
-// and ID3D11View objects belonging to renderbuffers.
-
-#ifndef LIBGLESV2_RENDERER_RENDERTARGET_H_
-#define LIBGLESV2_RENDERER_RENDERTARGET_H_
-
-#include "common/angleutils.h"
-#include "libGLESv2/angletypes.h"
-
-namespace rx
-{
-class RenderTarget
-{
- public:
- RenderTarget();
- virtual ~RenderTarget();
-
- virtual GLsizei getWidth() const = 0;
- virtual GLsizei getHeight() const = 0;
- virtual GLsizei getDepth() const = 0;
- virtual GLenum getInternalFormat() const = 0;
- virtual GLenum getActualFormat() const = 0;
- virtual GLsizei getSamples() const = 0;
- gl::Extents getExtents() const { return gl::Extents(getWidth(), getHeight(), getDepth()); }
-
- virtual void invalidate(GLint x, GLint y, GLsizei width, GLsizei height) = 0;
-
- virtual unsigned int getSerial() const;
- static unsigned int issueSerials(unsigned int count);
-
- struct Desc {
- GLsizei width;
- GLsizei height;
- GLsizei depth;
- GLenum format;
- };
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RenderTarget);
-
- const unsigned int mSerial;
- static unsigned int mCurrentSerial;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERTARGET_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h
deleted file mode 100644
index 52e070f1d3..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (c) 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 LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_
-#define LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_
-
-#include "angle_gl.h"
-
-#include "libGLESv2/Error.h"
-
-#include "common/angleutils.h"
-
-namespace rx
-{
-
-class RenderbufferImpl
-{
- public:
- RenderbufferImpl();
- virtual ~RenderbufferImpl() = 0;
-
- virtual gl::Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) = 0;
-
- virtual GLsizei getWidth() const = 0;
- virtual GLsizei getHeight() const = 0;
- virtual GLenum getInternalFormat() const = 0;
- virtual GLenum getActualFormat() const = 0;
- virtual GLsizei getSamples() const = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RenderbufferImpl);
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_RENDERBUFFERIMPL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
deleted file mode 100644
index df3dae1e38..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-//
-// Copyright (c) 2012-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.
-//
-
-// Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances.
-
-#include "common/utilities.h"
-#include "libEGL/AttributeMap.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/renderer/Renderer.h"
-
-#include <EGL/eglext.h>
-
-#if defined (ANGLE_ENABLE_D3D9)
-#include "libGLESv2/renderer/d3d/d3d9/Renderer9.h"
-#endif // ANGLE_ENABLE_D3D9
-
-#if defined (ANGLE_ENABLE_D3D11)
-#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-#endif // ANGLE_ENABLE_D3D11
-
-#if defined (ANGLE_TEST_CONFIG)
-#define ANGLE_DEFAULT_D3D11 1
-#endif
-
-#if !defined(ANGLE_DEFAULT_D3D11)
-// Enables use of the Direct3D 11 API for a default display, when available
-#define ANGLE_DEFAULT_D3D11 0
-#endif
-
-namespace rx
-{
-
-Renderer::Renderer()
- : mCapsInitialized(false),
- mWorkaroundsInitialized(false)
-{
-}
-
-Renderer::~Renderer()
-{
-}
-
-const gl::Caps &Renderer::getRendererCaps() const
-{
- if (!mCapsInitialized)
- {
- generateCaps(&mCaps, &mTextureCaps, &mExtensions);
- mCapsInitialized = true;
- }
-
- return mCaps;
-}
-
-const gl::TextureCapsMap &Renderer::getRendererTextureCaps() const
-{
- if (!mCapsInitialized)
- {
- generateCaps(&mCaps, &mTextureCaps, &mExtensions);
- mCapsInitialized = true;
- }
-
- return mTextureCaps;
-}
-
-const gl::Extensions &Renderer::getRendererExtensions() const
-{
- if (!mCapsInitialized)
- {
- generateCaps(&mCaps, &mTextureCaps, &mExtensions);
- mCapsInitialized = true;
- }
-
- return mExtensions;
-}
-
-const Workarounds &Renderer::getWorkarounds() const
-{
- if (!mWorkaroundsInitialized)
- {
- mWorkarounds = generateWorkarounds();
- mWorkaroundsInitialized = true;
- }
-
- return mWorkarounds;
-}
-
-typedef Renderer *(*CreateRendererFunction)(egl::Display*, EGLNativeDisplayType, const egl::AttributeMap &);
-
-template <typename RendererType>
-Renderer *CreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attributes)
-{
- return new RendererType(display, nativeDisplay, attributes);
-}
-
-}
-
-extern "C"
-{
-
-rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType nativeDisplay, const egl::AttributeMap &attribMap)
-{
- std::vector<rx::CreateRendererFunction> rendererCreationFunctions;
-
- EGLint requestedDisplayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
-
-# if defined(ANGLE_ENABLE_D3D11)
- if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
- nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE ||
- requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
- {
- rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer11>);
- }
-# endif
-
-# if defined(ANGLE_ENABLE_D3D9)
- if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
- requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
- {
- rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer9>);
- }
-# 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(rx::CreateRenderer<rx::Renderer11>);
-# endif
-# if defined(ANGLE_ENABLE_D3D9)
- rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer9>);
-# endif
-# else
-# if defined(ANGLE_ENABLE_D3D9)
- rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer9>);
-# endif
-# if defined(ANGLE_ENABLE_D3D11)
- rendererCreationFunctions.push_back(rx::CreateRenderer<rx::Renderer11>);
-# endif
-# endif
- }
-
- for (size_t i = 0; i < rendererCreationFunctions.size(); i++)
- {
- rx::Renderer *renderer = rendererCreationFunctions[i](display, nativeDisplay, attribMap);
- if (renderer->initialize() == EGL_SUCCESS)
- {
- return renderer;
- }
- else
- {
- // Failed to create the renderer, try the next
- SafeDelete(renderer);
- }
- }
-
- return NULL;
-}
-
-void glDestroyRenderer(rx::Renderer *renderer)
-{
- ASSERT(renderer);
- SafeDelete(renderer);
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
deleted file mode 100644
index b85895a938..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
+++ /dev/null
@@ -1,193 +0,0 @@
-//
-// Copyright (c) 2012-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.
-//
-
-// Renderer.h: Defines a back-end specific class that hides the details of the
-// implementation-specific renderer.
-
-#ifndef LIBGLESV2_RENDERER_RENDERER_H_
-#define LIBGLESV2_RENDERER_RENDERER_H_
-
-#include "libGLESv2/Caps.h"
-#include "libGLESv2/Error.h"
-#include "libGLESv2/Uniform.h"
-#include "libGLESv2/angletypes.h"
-#include "libGLESv2/renderer/Workarounds.h"
-#include "common/NativeWindow.h"
-#include "common/mathutil.h"
-
-#include <cstdint>
-
-#include <EGL/egl.h>
-
-#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
-
-namespace egl
-{
-class Display;
-}
-
-namespace gl
-{
-class Buffer;
-class Framebuffer;
-struct Data;
-}
-
-namespace rx
-{
-class QueryImpl;
-class FenceNVImpl;
-class FenceSyncImpl;
-class BufferImpl;
-class VertexArrayImpl;
-class ShaderImpl;
-class ProgramImpl;
-class TextureImpl;
-class TransformFeedbackImpl;
-class RenderbufferImpl;
-struct TranslatedIndexData;
-struct Workarounds;
-class SwapChain;
-
-struct ConfigDesc
-{
- GLenum renderTargetFormat;
- GLenum depthStencilFormat;
- GLint multiSample;
- bool fastConfig;
- bool es3Capable;
-};
-
-class Renderer
-{
- public:
- Renderer();
- virtual ~Renderer();
-
- virtual EGLint initialize() = 0;
- virtual bool resetDevice() = 0;
-
- virtual int generateConfigs(ConfigDesc **configDescList) = 0;
- virtual void deleteConfigs(ConfigDesc *configDescList) = 0;
-
- virtual gl::Error sync(bool block) = 0;
-
- virtual gl::Error drawArrays(const gl::Data &data, GLenum mode,
- GLint first, GLsizei count, GLsizei instances) = 0;
- virtual gl::Error drawElements(const gl::Data &data, GLenum mode, GLsizei count, GLenum type,
- const GLvoid *indices, GLsizei instances,
- const RangeUI &indexRange) = 0;
-
- virtual gl::Error clear(const gl::Data &data, GLbitfield mask) = 0;
- virtual gl::Error clearBufferfv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLfloat *values) = 0;
- virtual gl::Error clearBufferuiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLuint *values) = 0;
- virtual gl::Error clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values) = 0;
- virtual gl::Error clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) = 0;
-
- virtual gl::Error readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLsizei *bufSize, void* pixels) = 0;
-
- virtual gl::Error blitFramebuffer(const gl::Data &data,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter) = 0;
-
- // TODO(jmadill): caps? and virtual for egl::Display
- virtual bool getShareHandleSupport() const = 0;
- virtual bool getPostSubBufferSupport() const = 0;
-
- // Shader creation
- virtual ShaderImpl *createShader(const gl::Data &data, GLenum type) = 0;
- virtual ProgramImpl *createProgram() = 0;
-
- // Shader operations
- virtual void releaseShaderCompiler() = 0;
-
- // Texture creation
- virtual TextureImpl *createTexture(GLenum target) = 0;
-
- // Renderbuffer creation
- virtual RenderbufferImpl *createRenderbuffer() = 0;
- virtual RenderbufferImpl *createRenderbuffer(SwapChain *swapChain, bool depth) = 0;
-
- // Buffer creation
- virtual BufferImpl *createBuffer() = 0;
-
- // Vertex Array creation
- virtual VertexArrayImpl *createVertexArray() = 0;
-
- // Query and Fence creation
- virtual QueryImpl *createQuery(GLenum type) = 0;
- virtual FenceNVImpl *createFenceNV() = 0;
- virtual FenceSyncImpl *createFenceSync() = 0;
-
- // Transform Feedback creation
- virtual TransformFeedbackImpl *createTransformFeedback() = 0;
-
- // lost device
- //TODO(jmadill): investigate if this stuff is necessary in GL
- virtual void notifyDeviceLost() = 0;
- virtual bool isDeviceLost() = 0;
- virtual bool testDeviceLost(bool notify) = 0;
- virtual bool testDeviceResettable() = 0;
-
- virtual DWORD getAdapterVendor() const = 0;
- virtual std::string getRendererDescription() const = 0;
- virtual GUID getAdapterIdentifier() const = 0;
-
- // Renderer capabilities (virtual because of egl::Display)
- virtual const gl::Caps &getRendererCaps() const;
- const gl::TextureCapsMap &getRendererTextureCaps() const;
- virtual const gl::Extensions &getRendererExtensions() const;
- const Workarounds &getWorkarounds() const;
-
- // TODO(jmadill): needed by egl::Display, probably should be removed
- virtual int getMajorShaderModel() const = 0;
- virtual int getMinSwapInterval() const = 0;
- virtual int getMaxSwapInterval() const = 0;
- virtual bool getLUID(LUID *adapterLuid) const = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Renderer);
-
- virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const = 0;
- virtual Workarounds generateWorkarounds() const = 0;
-
- mutable bool mCapsInitialized;
- mutable gl::Caps mCaps;
- mutable gl::TextureCapsMap mTextureCaps;
- mutable gl::Extensions mExtensions;
-
- mutable bool mWorkaroundsInitialized;
- mutable Workarounds mWorkarounds;
-};
-
-struct dx_VertexConstants
-{
- float depthRange[4];
- float viewAdjust[4];
-};
-
-struct dx_PixelConstants
-{
- float depthRange[4];
- float viewCoords[4];
- float depthFront[4];
-};
-
-enum ShaderType
-{
- SHADER_VERTEX,
- SHADER_PIXEL,
- SHADER_GEOMETRY
-};
-
-}
-#endif // LIBGLESV2_RENDERER_RENDERER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h
deleted file mode 100644
index f1a96d74fb..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// ShaderExecutable.h: Defines a renderer-agnostic class to contain shader
-// executable implementation details.
-
-#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE_H_
-#define LIBGLESV2_RENDERER_SHADEREXECUTABLE_H_
-
-#include "common/angleutils.h"
-#include "common/debug.h"
-
-#include <vector>
-#include <cstdint>
-
-namespace rx
-{
-
-class ShaderExecutable
-{
- public:
- ShaderExecutable(const void *function, size_t length)
- : mFunctionBuffer(length)
- {
- memcpy(mFunctionBuffer.data(), function, length);
- }
-
- virtual ~ShaderExecutable() {}
-
- const uint8_t *getFunction() const
- {
- return mFunctionBuffer.data();
- }
-
- size_t getLength() const
- {
- return mFunctionBuffer.size();
- }
-
- const std::string &getDebugInfo() const
- {
- return mDebugInfo;
- }
-
- void appendDebugInfo(const std::string &info)
- {
- mDebugInfo += info;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ShaderExecutable);
-
- std::vector<uint8_t> mFunctionBuffer;
- std::string mDebugInfo;
-};
-
-class UniformStorage
-{
- public:
- UniformStorage(size_t initialSize)
- : mSize(initialSize)
- {
- }
-
- virtual ~UniformStorage() {}
-
- size_t size() const { return mSize; }
-
- private:
- size_t mSize;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h
deleted file mode 100644
index 3e662557e4..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h
+++ /dev/null
@@ -1,64 +0,0 @@
-//
-// Copyright 2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// TextureImpl.h: Defines the abstract rx::TextureImpl classes.
-
-#ifndef LIBGLESV2_RENDERER_TEXTUREIMPL_H_
-#define LIBGLESV2_RENDERER_TEXTUREIMPL_H_
-
-#include "common/angleutils.h"
-#include "libGLESv2/Error.h"
-
-#include "angle_gl.h"
-
-#include "libGLESv2/ImageIndex.h"
-
-namespace egl
-{
-class Surface;
-}
-
-namespace gl
-{
-class Framebuffer;
-struct PixelUnpackState;
-struct SamplerState;
-}
-
-namespace rx
-{
-
-class Image;
-
-class TextureImpl
-{
- public:
- virtual ~TextureImpl() {};
-
- // Deprecated in favour of the ImageIndex method
- virtual Image *getImage(int level, int layer) const = 0;
- virtual Image *getImage(const gl::ImageIndex &index) const = 0;
- virtual GLsizei getLayerCount(int level) const = 0;
-
- virtual void setUsage(GLenum usage) = 0;
-
- virtual gl::Error setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
- virtual gl::Error setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
- virtual gl::Error subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
- virtual gl::Error subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const gl::PixelUnpackState &unpack, const void *pixels) = 0;
- virtual gl::Error copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
- virtual gl::Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
- virtual gl::Error storage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = 0;
-
- virtual gl::Error generateMipmaps() = 0;
-
- virtual void bindTexImage(egl::Surface *surface) = 0;
- virtual void releaseTexImage() = 0;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_TEXTUREIMPL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h b/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h
deleted file mode 100644
index 20a166fb7a..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// Copyright (c) 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.
-//
-
-// angletypes.h: Workarounds for driver bugs and other issues.
-
-#ifndef LIBGLESV2_RENDERER_WORKAROUNDS_H_
-#define LIBGLESV2_RENDERER_WORKAROUNDS_H_
-
-// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate
-// independent of ANGLE's renderer. Workarounds should also be accessible
-// outside of the Renderer.
-
-namespace rx
-{
-
-enum D3DWorkaroundType
-{
- ANGLE_D3D_WORKAROUND_NONE,
- ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION,
- ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION
-};
-
-struct Workarounds
-{
- Workarounds()
- : mrtPerfWorkaround(false),
- setDataFasterThanImageUpload(false)
- {}
-
- bool mrtPerfWorkaround;
- bool setDataFasterThanImageUpload;
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_WORKAROUNDS_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.h b/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.h
deleted file mode 100644
index e0e8af166b..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/copyvertex.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// Copyright (c) 2013-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.h: Defines vertex buffer copying and conversion functions
-
-#ifndef LIBGLESV2_RENDERER_COPYVERTEX_H_
-#define LIBGLESV2_RENDERER_COPYVERTEX_H_
-
-#include "common/mathutil.h"
-
-namespace rx
-{
-
-// 'widenDefaultValueBits' gives the default value for the alpha channel (4th component)
-// the sentinel value 0 means we do not want to widen the input or add an alpha channel
-template <typename T, size_t componentCount, uint32_t widenDefaultValueBits>
-inline void CopyNativeVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
-
-template <size_t componentCount>
-inline void Copy32FixedTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
-
-template <typename T, size_t componentCount, bool normalized>
-inline void CopyTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
-
-template <bool isSigned, bool normalized, bool toFloat>
-inline void CopyXYZ10W2ToXYZW32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
-
-}
-
-#include "copyvertex.inl"
-
-#endif // LIBGLESV2_RENDERER_COPYVERTEX_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp
deleted file mode 100644
index 12b919ab5a..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// 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 "libGLESv2/renderer/d3d/ImageD3D.h"
-
-namespace rx
-{
-
-ImageD3D::ImageD3D()
-{
-}
-
-ImageD3D *ImageD3D::makeImageD3D(Image *img)
-{
- ASSERT(HAS_DYNAMIC_TYPE(ImageD3D*, img));
- return static_cast<ImageD3D*>(img);
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h
deleted file mode 100644
index 554ca0cee0..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Copyright (c) 2002-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.
-//
-
-// Image.h: Defines the rx::Image class, an abstract base class for the
-// renderer-specific classes which will define the interface to the underlying
-// surfaces or resources.
-
-#ifndef LIBGLESV2_RENDERER_IMAGED3D_H_
-#define LIBGLESV2_RENDERER_IMAGED3D_H_
-
-#include "common/debug.h"
-#include "libGLESv2/renderer/Image.h"
-
-namespace gl
-{
-class Framebuffer;
-struct ImageIndex;
-struct Box;
-}
-
-namespace rx
-{
-class TextureStorage;
-
-class ImageD3D : public Image
-{
- public:
- ImageD3D();
- virtual ~ImageD3D() {};
-
- static ImageD3D *makeImageD3D(Image *img);
-
- virtual bool isDirty() const = 0;
-
- virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); };
- virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level) { return gl::Error(GL_NO_ERROR); };
- virtual gl::Error setManagedSurface3D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); };
- virtual gl::Error setManagedSurface2DArray(TextureStorage *storage, int layer, int level) { return gl::Error(GL_NO_ERROR); };
- virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box &region) = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ImageD3D);
-};
-
-}
-
-#endif // LIBGLESV2_RENDERER_IMAGED3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h
deleted file mode 100644
index 9440a449f2..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//
-// Copyright (c) 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 LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
-#define LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
-
-#include "angle_gl.h"
-
-#include "common/angleutils.h"
-#include "libGLESv2/renderer/RenderbufferImpl.h"
-
-namespace rx
-{
-class RendererD3D;
-class RenderTarget;
-class SwapChain;
-
-class RenderbufferD3D : public RenderbufferImpl
-{
- public:
- RenderbufferD3D(RendererD3D *renderer);
- virtual ~RenderbufferD3D();
-
- static RenderbufferD3D *makeRenderbufferD3D(RenderbufferImpl *renderbuffer);
-
- virtual gl::Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples) override;
- gl::Error setStorage(SwapChain *swapChain, bool depth);
-
- virtual GLsizei getWidth() const;
- virtual GLsizei getHeight() const;
- virtual GLenum getInternalFormat() const;
- virtual GLenum getActualFormat() const;
- virtual GLsizei getSamples() const;
-
- RenderTarget *getRenderTarget();
- unsigned int getRenderTargetSerial() const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RenderbufferD3D);
-
- RendererD3D *mRenderer;
- RenderTarget *mRenderTarget;
-};
-}
-
-#endif // LIBGLESV2_RENDERER_RENDERBUFFERD3D_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
deleted file mode 100644
index 5cddd8ab5e..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
+++ /dev/null
@@ -1,801 +0,0 @@
-//
-// Copyright (c) 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 "libGLESv2/renderer/d3d/RendererD3D.h"
-
-#include "libGLESv2/renderer/d3d/IndexDataManager.h"
-#include "libGLESv2/Framebuffer.h"
-#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/ResourceManager.h"
-#include "libGLESv2/State.h"
-#include "libGLESv2/VertexArray.h"
-#include "libGLESv2/formatutils.h"
-#include "common/utilities.h"
-
-namespace rx
-{
-
-RendererD3D::RendererD3D(egl::Display *display)
- : mDisplay(display)
-{
-}
-
-RendererD3D::~RendererD3D()
-{
- cleanup();
-}
-
-void RendererD3D::cleanup()
-{
- for (gl::TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); ++i)
- {
- i->second.set(NULL);
- }
- mIncompleteTextures.clear();
-}
-
-// static
-RendererD3D *RendererD3D::makeRendererD3D(Renderer *renderer)
-{
- ASSERT(HAS_DYNAMIC_TYPE(RendererD3D*, renderer));
- return static_cast<RendererD3D*>(renderer);
-}
-
-gl::Error RendererD3D::drawElements(const gl::Data &data,
- GLenum mode, GLsizei count, GLenum type,
- const GLvoid *indices, GLsizei instances,
- const RangeUI &indexRange)
-{
- ASSERT(data.state->getCurrentProgramId() != 0);
-
- gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
- programBinary->updateSamplerMapping();
-
- gl::Error error = generateSwizzles(data);
- if (error.isError())
- {
- return error;
- }
-
- if (!applyPrimitiveType(mode, count))
- {
- return gl::Error(GL_NO_ERROR);
- }
-
- error = applyRenderTarget(data, mode, false);
- if (error.isError())
- {
- return error;
- }
-
- error = applyState(data, mode);
- if (error.isError())
- {
- return error;
- }
-
- gl::VertexArray *vao = data.state->getVertexArray();
- TranslatedIndexData indexInfo;
- indexInfo.indexRange = indexRange;
- error = applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
- if (error.isError())
- {
- return error;
- }
-
- GLsizei vertexCount = indexInfo.indexRange.length() + 1;
- error = applyVertexBuffer(*data.state, indexInfo.indexRange.start, vertexCount, instances);
- if (error.isError())
- {
- return error;
- }
-
- bool transformFeedbackActive = applyTransformFeedbackBuffers(data);
- // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
- // layer.
- ASSERT(!transformFeedbackActive);
-
- error = applyShaders(data, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(data);
- if (error.isError())
- {
- return error;
- }
-
- error = applyUniformBuffers(data);
- if (error.isError())
- {
- return error;
- }
-
- if (!skipDraw(data, mode))
- {
- error = drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
- if (error.isError())
- {
- return error;
- }
- }
-
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error RendererD3D::drawArrays(const gl::Data &data,
- GLenum mode, GLint first,
- GLsizei count, GLsizei instances)
-{
- ASSERT(data.state->getCurrentProgramId() != 0);
-
- gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
- programBinary->updateSamplerMapping();
-
- gl::Error error = generateSwizzles(data);
- if (error.isError())
- {
- return error;
- }
-
- if (!applyPrimitiveType(mode, count))
- {
- return gl::Error(GL_NO_ERROR);
- }
-
- error = applyRenderTarget(data, mode, false);
- if (error.isError())
- {
- return error;
- }
-
- error = applyState(data, mode);
- if (error.isError())
- {
- return error;
- }
-
- error = applyVertexBuffer(*data.state, first, count, instances);
- if (error.isError())
- {
- return error;
- }
-
- bool transformFeedbackActive = applyTransformFeedbackBuffers(data);
-
- error = applyShaders(data, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(data);
- if (error.isError())
- {
- return error;
- }
-
- error = applyUniformBuffers(data);
- if (error.isError())
- {
- return error;
- }
-
- if (!skipDraw(data, mode))
- {
- error = drawArrays(mode, count, instances, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- if (transformFeedbackActive)
- {
- markTransformFeedbackUsage(data);
- }
- }
-
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error RendererD3D::generateSwizzles(const gl::Data &data, gl::SamplerType type)
-{
- gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
-
- size_t samplerRange = programBinary->getUsedSamplerRange(type);
-
- for (size_t i = 0; i < samplerRange; i++)
- {
- GLenum textureType = programBinary->getSamplerTextureType(type, i);
- GLint textureUnit = programBinary->getSamplerMapping(type, i, *data.caps);
- if (textureUnit != -1)
- {
- gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
- ASSERT(texture);
- if (texture->getSamplerState().swizzleRequired())
- {
- gl::Error error = generateSwizzle(texture);
- if (error.isError())
- {
- return error;
- }
- }
- }
- }
-
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error RendererD3D::generateSwizzles(const gl::Data &data)
-{
- gl::Error error = generateSwizzles(data, gl::SAMPLER_VERTEX);
- if (error.isError())
- {
- return error;
- }
-
- error = generateSwizzles(data, gl::SAMPLER_PIXEL);
- if (error.isError())
- {
- return error;
- }
-
- return gl::Error(GL_NO_ERROR);
-}
-
-// Applies the render target surface, depth stencil surface, viewport rectangle and
-// scissor rectangle to the renderer
-gl::Error RendererD3D::applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport)
-{
- const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
- ASSERT(framebufferObject && framebufferObject->completeness(data) == GL_FRAMEBUFFER_COMPLETE);
-
- gl::Error error = applyRenderTarget(framebufferObject);
- if (error.isError())
- {
- return error;
- }
-
- float nearZ, farZ;
- data.state->getDepthRange(&nearZ, &farZ);
- setViewport(data.state->getViewport(), nearZ, farZ, drawMode,
- data.state->getRasterizerState().frontFace, ignoreViewport);
-
- setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled());
-
- return gl::Error(GL_NO_ERROR);
-}
-
-// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D device
-gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode)
-{
- const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer();
- int samples = framebufferObject->getSamples(data);
-
- gl::RasterizerState rasterizer = data.state->getRasterizerState();
- rasterizer.pointDrawMode = (drawMode == GL_POINTS);
- rasterizer.multiSample = (samples != 0);
-
- gl::Error error = setRasterizerState(rasterizer);
- if (error.isError())
- {
- return error;
- }
-
- unsigned int mask = 0;
- if (data.state->isSampleCoverageEnabled())
- {
- GLclampf coverageValue;
- bool coverageInvert = false;
- data.state->getSampleCoverageParams(&coverageValue, &coverageInvert);
- 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;
- }
- }
- }
-
- if (coverageInvert)
- {
- mask = ~mask;
- }
- }
- else
- {
- mask = 0xFFFFFFFF;
- }
- error = setBlendState(framebufferObject, data.state->getBlendState(), data.state->getBlendColor(), mask);
- if (error.isError())
- {
- return error;
- }
-
- error = setDepthStencilState(data.state->getDepthStencilState(), data.state->getStencilRef(),
- data.state->getStencilBackRef(), rasterizer.frontFace == GL_CCW);
- if (error.isError())
- {
- return error;
- }
-
- return gl::Error(GL_NO_ERROR);
-}
-
-bool RendererD3D::applyTransformFeedbackBuffers(const gl::Data &data)
-{
- gl::TransformFeedback *curTransformFeedback = data.state->getCurrentTransformFeedback();
- if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
- {
- applyTransformFeedbackBuffers(*data.state);
- return true;
- }
- else
- {
- return false;
- }
-}
-
-// Applies the shaders and shader constants to the Direct3D device
-gl::Error RendererD3D::applyShaders(const gl::Data &data, bool transformFeedbackActive)
-{
- gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
-
- gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
- gl::VertexFormat::GetInputLayout(inputLayout, programBinary, *data.state);
-
- const gl::Framebuffer *fbo = data.state->getDrawFramebuffer();
-
- gl::Error error = applyShaders(programBinary, inputLayout, fbo, data.state->getRasterizerState().rasterizerDiscard, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- return programBinary->applyUniforms();
-}
-
-// 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).
-gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType,
- const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
-{
- gl::ProgramBinary *programBinary = data.state->getCurrentProgramBinary();
-
- size_t samplerRange = programBinary->getUsedSamplerRange(shaderType);
- for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
- {
- GLenum textureType = programBinary->getSamplerTextureType(shaderType, samplerIndex);
- GLint textureUnit = programBinary->getSamplerMapping(shaderType, samplerIndex, *data.caps);
- if (textureUnit != -1)
- {
- gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType);
- ASSERT(texture);
- gl::SamplerState sampler = texture->getSamplerState();
-
- gl::Sampler *samplerObject = data.state->getSampler(textureUnit);
- if (samplerObject)
- {
- samplerObject->getState(&sampler);
- }
-
- // TODO: std::binary_search may become unavailable using older versions of GCC
- if (texture->isSamplerComplete(sampler, *data.textureCaps, *data.extensions, data.clientVersion) &&
- !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
- {
- gl::Error error = setSamplerState(shaderType, samplerIndex, texture, sampler);
- if (error.isError())
- {
- return error;
- }
-
- error = setTexture(shaderType, samplerIndex, texture);
- if (error.isError())
- {
- return error;
- }
- }
- else
- {
- // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture.
- gl::Texture *incompleteTexture = getIncompleteTexture(textureType);
- gl::Error error = setTexture(shaderType, samplerIndex, incompleteTexture);
- if (error.isError())
- {
- return error;
- }
- }
- }
- else
- {
- // No texture bound to this slot even though it is used by the shader, bind a NULL texture
- gl::Error error = setTexture(shaderType, samplerIndex, NULL);
- if (error.isError())
- {
- return error;
- }
- }
- }
-
- // Set all the remaining textures to NULL
- size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits
- : data.caps->maxVertexTextureImageUnits;
- for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
- {
- gl::Error error = setTexture(shaderType, samplerIndex, NULL);
- if (error.isError())
- {
- return error;
- }
- }
-
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error RendererD3D::applyTextures(const gl::Data &data)
-{
- FramebufferTextureSerialArray framebufferSerials;
- size_t framebufferSerialCount = getBoundFramebufferTextureSerials(data, &framebufferSerials);
-
- gl::Error error = applyTextures(data, gl::SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(data, gl::SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
- if (error.isError())
- {
- return error;
- }
-
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error RendererD3D::applyUniformBuffers(const gl::Data &data)
-{
- gl::Program *programObject = data.resourceManager->getProgram(data.state->getCurrentProgramId());
- gl::ProgramBinary *programBinary = programObject->getProgramBinary();
-
- std::vector<gl::Buffer*> boundBuffers;
-
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
- {
- GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
-
- if (data.state->getIndexedUniformBuffer(blockBinding)->id() == 0)
- {
- // undefined behaviour
- return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer.");
- }
- else
- {
- gl::Buffer *uniformBuffer = data.state->getIndexedUniformBuffer(blockBinding);
- ASSERT(uniformBuffer);
- boundBuffers.push_back(uniformBuffer);
- }
- }
-
- return programBinary->applyUniformBuffers(boundBuffers, *data.caps);
-}
-
-bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode)
-{
- if (drawMode == GL_POINTS)
- {
- // 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 (!data.state->getCurrentProgramBinary()->usesPointSize())
- {
- // This is stictly speaking not an error, but developers should be
- // notified of risking undefined behavior.
- ERR("Point rendering without writing to gl_PointSize.");
-
- return true;
- }
- }
- else if (gl::IsTriangleMode(drawMode))
- {
- if (data.state->getRasterizerState().cullFace && data.state->getRasterizerState().cullMode == GL_FRONT_AND_BACK)
- {
- return true;
- }
- }
-
- return false;
-}
-
-void RendererD3D::markTransformFeedbackUsage(const gl::Data &data)
-{
- for (size_t i = 0; i < data.caps->maxTransformFeedbackSeparateAttributes; i++)
- {
- gl::Buffer *buffer = data.state->getIndexedTransformFeedbackBuffer(i);
- if (buffer)
- {
- buffer->markTransformFeedbackUsage();
- }
- }
-}
-
-size_t RendererD3D::getBoundFramebufferTextureSerials(const gl::Data &data,
- FramebufferTextureSerialArray *outSerialArray)
-{
- size_t serialCount = 0;
-
- const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer();
- for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
- {
- gl::FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
- if (attachment && attachment->isTexture())
- {
- gl::Texture *texture = attachment->getTexture();
- (*outSerialArray)[serialCount++] = texture->getTextureSerial();
- }
- }
-
- gl::FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
- if (depthStencilAttachment && depthStencilAttachment->isTexture())
- {
- gl::Texture *depthStencilTexture = depthStencilAttachment->getTexture();
- (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
- }
-
- std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
-
- return serialCount;
-}
-
-gl::Texture *RendererD3D::getIncompleteTexture(GLenum type)
-{
- if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
- {
- const GLubyte color[] = { 0, 0, 0, 255 };
- const gl::PixelUnpackState incompleteUnpackState(1);
-
- gl::Texture* t = NULL;
- switch (type)
- {
- default:
- UNREACHABLE();
- // default falls through to TEXTURE_2D
-
- case GL_TEXTURE_2D:
- {
- gl::Texture2D *incomplete2d = new gl::Texture2D(createTexture(GL_TEXTURE_2D), gl::Texture::INCOMPLETE_TEXTURE_ID);
- incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- t = incomplete2d;
- }
- break;
-
- case GL_TEXTURE_CUBE_MAP:
- {
- gl::TextureCubeMap *incompleteCube = new gl::TextureCubeMap(createTexture(GL_TEXTURE_CUBE_MAP), gl::Texture::INCOMPLETE_TEXTURE_ID);
-
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
-
- t = incompleteCube;
- }
- break;
-
- case GL_TEXTURE_3D:
- {
- gl::Texture3D *incomplete3d = new gl::Texture3D(createTexture(GL_TEXTURE_3D), gl::Texture::INCOMPLETE_TEXTURE_ID);
- incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
-
- t = incomplete3d;
- }
- break;
-
- case GL_TEXTURE_2D_ARRAY:
- {
- gl::Texture2DArray *incomplete2darray = new gl::Texture2DArray(createTexture(GL_TEXTURE_2D_ARRAY), gl::Texture::INCOMPLETE_TEXTURE_ID);
- incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
-
- t = incomplete2darray;
- }
- break;
- }
-
- mIncompleteTextures[type].set(t);
- }
-
- return mIncompleteTextures[type].get();
-}
-
-gl::Error RendererD3D::clear(const gl::Data &data, GLbitfield mask)
-{
- gl::ClearParameters clearParams = data.state->getClearParameters(mask);
-
- // Clips the clear to the scissor rectangle but not the viewport
- gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
- if (error.isError())
- {
- return error;
- }
-
- return clear(clearParams, data.state->getDrawFramebuffer());
-}
-
-gl::Error RendererD3D::clearBufferfv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLfloat *values)
-{
- // glClearBufferfv can be called to clear the color buffer or depth buffer
- gl::ClearParameters clearParams = data.state->getClearParameters(0);
-
- if (buffer == GL_COLOR)
- {
- for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
- {
- clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
- }
- clearParams.colorFClearValue = gl::ColorF(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_FLOAT;
- }
-
- if (buffer == GL_DEPTH)
- {
- clearParams.clearDepth = true;
- clearParams.depthClearValue = values[0];
- }
-
- // Clips the clear to the scissor rectangle but not the viewport
- gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
- if (error.isError())
- {
- return error;
- }
-
- return clear(clearParams, data.state->getDrawFramebuffer());
-}
-
-gl::Error RendererD3D::clearBufferuiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLuint *values)
-{
- // glClearBufferuiv can only be called to clear a color buffer
- gl::ClearParameters clearParams = data.state->getClearParameters(0);
- for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
- {
- clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
- }
- clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_UNSIGNED_INT;
-
- // Clips the clear to the scissor rectangle but not the viewport
- gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
- if (error.isError())
- {
- return error;
- }
-
- return clear(clearParams, data.state->getDrawFramebuffer());
-}
-
-gl::Error RendererD3D::clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values)
-{
- // glClearBufferiv can be called to clear the color buffer or stencil buffer
- gl::ClearParameters clearParams = data.state->getClearParameters(0);
-
- if (buffer == GL_COLOR)
- {
- for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
- {
- clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
- }
- clearParams.colorIClearValue = gl::ColorI(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_INT;
- }
-
- if (buffer == GL_STENCIL)
- {
- clearParams.clearStencil = true;
- clearParams.stencilClearValue = values[1];
- }
-
- // Clips the clear to the scissor rectangle but not the viewport
- gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
- if (error.isError())
- {
- return error;
- }
-
- return clear(clearParams, data.state->getDrawFramebuffer());
-}
-
-gl::Error RendererD3D::clearBufferfi(const gl::Data &data, GLenum buffer, GLint drawbuffer,
- GLfloat depth, GLint stencil)
-{
- if (data.state->isRasterizerDiscardEnabled())
- {
- return gl::Error(GL_NO_ERROR);
- }
-
- // glClearBufferfi can only be called to clear a depth stencil buffer
- gl::ClearParameters clearParams = data.state->getClearParameters(0);
- clearParams.clearDepth = true;
- clearParams.depthClearValue = depth;
- clearParams.clearStencil = true;
- clearParams.stencilClearValue = stencil;
-
- // Clips the clear to the scissor rectangle but not the viewport
- gl::Error error = applyRenderTarget(data, GL_TRIANGLES, true);
- if (error.isError())
- {
- return error;
- }
-
- return clear(clearParams, data.state->getDrawFramebuffer());
-}
-
-gl::Error RendererD3D::blitFramebuffer(const gl::Data &data,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- const gl::Framebuffer *readFramebuffer = data.state->getReadFramebuffer();
- const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer();
-
- bool blitRenderTarget = false;
- bool blitDepth = false;
- bool blitStencil = false;
- if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
- {
- blitRenderTarget = true;
- }
- if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
- {
- blitStencil = true;
- }
- if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
- {
- blitDepth = true;
- }
-
- gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
- gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
- if (blitRenderTarget || blitDepth || blitStencil)
- {
- const gl::Rectangle *scissor = data.state->isScissorTestEnabled() ? &data.state->getScissor() : NULL;
- gl::Error error = blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
- blitRenderTarget, blitDepth, blitStencil, filter);
- if (error.isError())
- {
- return error;
- }
- }
-
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error RendererD3D::readPixels(const gl::Data &data, GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
-{
- const gl::Framebuffer *framebuffer = data.state->getReadFramebuffer();
-
- GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, type);
- const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(sizedInternalFormat);
- GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, data.state->getPackAlignment());
-
- return readPixels(framebuffer, x, y, width, height, format, type, outputPitch, data.state->getPackState(),
- reinterpret_cast<uint8_t*>(pixels));
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
deleted file mode 100644
index ff90a6a69a..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-//
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches
-// D3D11 input layouts.
-
-#include "libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h"
-#include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
-#include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h"
-#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
-#include "libGLESv2/renderer/d3d/ProgramD3D.h"
-#include "libGLESv2/renderer/d3d/VertexDataManager.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/VertexAttribute.h"
-
-#include "third_party/murmurhash/MurmurHash3.h"
-
-namespace rx
-{
-
-static void GetInputLayout(const TranslatedAttribute translatedAttributes[gl::MAX_VERTEX_ATTRIBS],
- gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS])
-{
- for (unsigned int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- const TranslatedAttribute &translatedAttribute = translatedAttributes[attributeIndex];
-
- if (translatedAttributes[attributeIndex].active)
- {
- inputLayout[attributeIndex] = gl::VertexFormat(*translatedAttribute.attribute,
- translatedAttribute.currentValueType);
- }
- }
-}
-
-const unsigned int InputLayoutCache::kMaxInputLayouts = 1024;
-
-InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts)
-{
- mCounter = 0;
- mDevice = NULL;
- mDeviceContext = NULL;
- mCurrentIL = NULL;
- for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
- {
- mCurrentBuffers[i] = NULL;
- mCurrentVertexStrides[i] = -1;
- mCurrentVertexOffsets[i] = -1;
- }
-}
-
-InputLayoutCache::~InputLayoutCache()
-{
- clear();
-}
-
-void InputLayoutCache::initialize(ID3D11Device *device, ID3D11DeviceContext *context)
-{
- clear();
- mDevice = device;
- mDeviceContext = context;
-}
-
-void InputLayoutCache::clear()
-{
- for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
- {
- SafeRelease(i->second.inputLayout);
- }
- mInputLayoutMap.clear();
- markDirty();
-}
-
-void InputLayoutCache::markDirty()
-{
- mCurrentIL = NULL;
- for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
- {
- mCurrentBuffers[i] = NULL;
- mCurrentVertexStrides[i] = -1;
- mCurrentVertexOffsets[i] = -1;
- }
-}
-
-gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
- gl::ProgramBinary *programBinary)
-{
- int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS];
- programBinary->sortAttributesByLayout(attributes, sortedSemanticIndices);
-
- if (!mDevice || !mDeviceContext)
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Internal input layout cache is not initialized.");
- }
-
- InputLayoutKey ilKey = { 0 };
-
- static const char* semanticName = "TEXCOORD";
-
- for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
- {
- if (attributes[i].active)
- {
- D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
-
- gl::VertexFormat vertexFormat(*attributes[i].attribute, attributes[i].currentValueType);
- const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat);
-
- // Record the type of the associated vertex shader vector in our key
- // This will prevent mismatched vertex shaders from using the same input layout
- GLint attributeSize;
- programBinary->getActiveAttribute(sortedSemanticIndices[i], 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL);
-
- ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName;
- ilKey.elements[ilKey.elementCount].desc.SemanticIndex = i;
- ilKey.elements[ilKey.elementCount].desc.Format = vertexFormatInfo.nativeFormat;
- ilKey.elements[ilKey.elementCount].desc.InputSlot = i;
- ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0;
- ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass;
- ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = attributes[i].divisor;
- ilKey.elementCount++;
- }
- }
-
- ID3D11InputLayout *inputLayout = NULL;
-
- InputLayoutMap::iterator keyIter = mInputLayoutMap.find(ilKey);
- if (keyIter != mInputLayoutMap.end())
- {
- inputLayout = keyIter->second.inputLayout;
- keyIter->second.lastUsedTime = mCounter++;
- }
- else
- {
- gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS];
- GetInputLayout(attributes, shaderInputLayout);
- ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary->getImplementation());
-
- ShaderExecutable *shader = NULL;
- gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader);
- if (error.isError())
- {
- return error;
- }
-
- ShaderExecutable *shader11 = ShaderExecutable11::makeShaderExecutable11(shader);
-
- D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS];
- for (unsigned int j = 0; j < ilKey.elementCount; ++j)
- {
- descs[j] = ilKey.elements[j].desc;
- }
-
- HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader11->getFunction(), shader11->getLength(), &inputLayout);
- if (FAILED(result))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal input layout, HRESULT: 0x%08x", result);
- }
-
- if (mInputLayoutMap.size() >= kMaxInputLayouts)
- {
- TRACE("Overflowed the limit of %u input layouts, removing the least recently used "
- "to make room.", kMaxInputLayouts);
-
- InputLayoutMap::iterator leastRecentlyUsed = mInputLayoutMap.begin();
- for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
- {
- if (i->second.lastUsedTime < leastRecentlyUsed->second.lastUsedTime)
- {
- leastRecentlyUsed = i;
- }
- }
- SafeRelease(leastRecentlyUsed->second.inputLayout);
- mInputLayoutMap.erase(leastRecentlyUsed);
- }
-
- InputLayoutCounterPair inputCounterPair;
- inputCounterPair.inputLayout = inputLayout;
- inputCounterPair.lastUsedTime = mCounter++;
-
- mInputLayoutMap.insert(std::make_pair(ilKey, inputCounterPair));
- }
-
- if (inputLayout != mCurrentIL)
- {
- mDeviceContext->IASetInputLayout(inputLayout);
- mCurrentIL = inputLayout;
- }
-
- bool dirtyBuffers = false;
- size_t minDiff = gl::MAX_VERTEX_ATTRIBS;
- size_t maxDiff = 0;
- for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
- {
- ID3D11Buffer *buffer = NULL;
-
- if (attributes[i].active)
- {
- VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer);
- Buffer11 *bufferStorage = attributes[i].storage ? Buffer11::makeBuffer11(attributes[i].storage) : NULL;
-
- buffer = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK)
- : vertexBuffer->getBuffer();
- }
-
- UINT vertexStride = attributes[i].stride;
- UINT vertexOffset = attributes[i].offset;
-
- if (buffer != mCurrentBuffers[i] || vertexStride != mCurrentVertexStrides[i] ||
- vertexOffset != mCurrentVertexOffsets[i])
- {
- dirtyBuffers = true;
- minDiff = std::min(minDiff, static_cast<size_t>(i));
- maxDiff = std::max(maxDiff, static_cast<size_t>(i));
-
- mCurrentBuffers[i] = buffer;
- mCurrentVertexStrides[i] = vertexStride;
- mCurrentVertexOffsets[i] = vertexOffset;
- }
- }
-
- if (dirtyBuffers)
- {
- ASSERT(minDiff <= maxDiff && maxDiff < gl::MAX_VERTEX_ATTRIBS);
- mDeviceContext->IASetVertexBuffers(minDiff, maxDiff - minDiff + 1, mCurrentBuffers + minDiff,
- mCurrentVertexStrides + minDiff, mCurrentVertexOffsets + minDiff);
- }
-
- return gl::Error(GL_NO_ERROR);
-}
-
-std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout)
-{
- static const unsigned int seed = 0xDEADBEEF;
-
- std::size_t hash = 0;
- MurmurHash3_x86_32(inputLayout.begin(), inputLayout.end() - inputLayout.begin(), seed, &hash);
- return hash;
-}
-
-bool InputLayoutCache::compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b)
-{
- if (a.elementCount != b.elementCount)
- {
- return false;
- }
-
- return std::equal(a.begin(), a.end(), b.begin());
-}
-
-}
diff --git a/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h b/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h
index 30bb7e3b94..27917e6eec 100644
--- a/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h
+++ b/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h
@@ -23,8 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef THIRD_PARTY_COMPILER_ARRAY_BOUNDS_CLAMPER_H_
-#define THIRD_PARTY_COMPILER_ARRAY_BOUNDS_CLAMPER_H_
+#ifndef THIRD_PARTY_COMPILER_ARRAYBOUNDSCLAMPER_H_
+#define THIRD_PARTY_COMPILER_ARRAYBOUNDSCLAMPER_H_
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
@@ -57,4 +57,4 @@ private:
bool mArrayBoundsClampDefinitionNeeded;
};
-#endif // THIRD_PARTY_COMPILER_ARRAY_BOUNDS_CLAMPER_H_
+#endif // THIRD_PARTY_COMPILER_ARRAYBOUNDSCLAMPER_H_
diff --git a/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp b/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp
index dd86292649..a599c26502 100644
--- a/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp
+++ b/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp
@@ -29,6 +29,8 @@
#else // defined(_MSC_VER)
+// Ignore GCC force inline warnings
+#pragma GCC diagnostic ignored "-Wattributes"
#define FORCE_INLINE __attribute__((always_inline))
inline uint32_t rotl32 ( uint32_t x, int8_t r )
diff --git a/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h b/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h
index adb52004e2..bb02cd508f 100644
--- a/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h
+++ b/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h
@@ -20,4 +20,4 @@ void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out
//-----------------------------------------------------------------------------
-#endif // _MURMURHASH3_H_ \ No newline at end of file
+#endif // _MURMURHASH3_H_
diff --git a/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.h b/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.h
index 65005ee9c6..226085fbd3 100644
--- a/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.h
+++ b/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.h
@@ -23,8 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef SystemInfo_h
-#define SystemInfo_h
+#ifndef THIRD_PARTY_SYSTEMINFO_SYSTEMINFO_H_
+#define THIRD_PARTY_SYSTEMINFO_SYSTEMINFO_H_
namespace rx {
@@ -32,4 +32,4 @@ bool isWindowsVistaOrGreater();
} // namespace rx
-#endif // SystemInfo_h
+#endif // THIRD_PARTY_SYSTEMINFO_SYSTEMINFO_H_
diff --git a/src/3rdparty/angle/src/third_party/trace_event/trace_event.h b/src/3rdparty/angle/src/third_party/trace_event/trace_event.h
new file mode 100644
index 0000000000..af59dcfcc3
--- /dev/null
+++ b/src/3rdparty/angle/src/third_party/trace_event/trace_event.h
@@ -0,0 +1,795 @@
+// 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(category, name) \
+ INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name)
+#define TRACE_EVENT1(category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val)
+#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_SCOPED(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(category, name) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
+ category, name, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
+ category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
+ category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
+ arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_INSTANT0(category, name) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
+ category, name, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
+ category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(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(category, name) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
+ category, name, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
+ category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
+ category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
+ arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_BEGIN0(category, name) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
+ category, name, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
+ category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(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(category, name) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
+ category, name, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
+ category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
+ category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
+ arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_END0(category, name) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
+ category, name, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
+ category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(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(category, name, value) \
+ INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
+ category, name, TRACE_EVENT_FLAG_NONE, \
+ "value", static_cast<int>(value))
+#define TRACE_COPY_COUNTER1(category, name, value) \
+ INTERNAL_TRACE_EVENT_ADD(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(category, name, value1_name, value1_val, \
+ value2_name, value2_val) \
+ INTERNAL_TRACE_EVENT_ADD(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(category, name, value1_name, value1_val, \
+ value2_name, value2_val) \
+ INTERNAL_TRACE_EVENT_ADD(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(category, name, id, value) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
+ category, name, id, TRACE_EVENT_FLAG_NONE, \
+ "value", static_cast<int>(value))
+#define TRACE_COPY_COUNTER_ID1(category, name, id, value) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(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(category, name, id, value1_name, value1_val, \
+ value2_name, value2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(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(category, name, id, value1_name, value1_val, \
+ value2_name, value2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(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(category, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+ category, name, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+ category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(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(category, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+ category, name, id, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+ category, name, id, TRACE_EVENT_FLAG_COPY, \
+ arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(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(category, name, id, step) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
+ category, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
+#define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \
+ arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
+ category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
+ arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \
+ category, name, id, TRACE_EVENT_FLAG_COPY, "step", step)
+#define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \
+ arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(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(category, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+ category, name, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+ category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(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(category, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+ category, name, id, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+ category, name, id, TRACE_EVENT_FLAG_COPY, \
+ arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(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 \
+ gl::TraceGetTraceCategoryEnabledFlag
+
+// 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 \
+ gl::TraceAddTraceEvent
+
+////////////////////////////////////////////////////////////////////////////////
+
+// 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(category) \
+ static const unsigned char* INTERNALTRACEEVENTUID(catstatic) = 0; \
+ if (!INTERNALTRACEEVENTUID(catstatic)) \
+ INTERNALTRACEEVENTUID(catstatic) = \
+ TRACE_EVENT_API_GET_CATEGORY_ENABLED(category);
+
+// Implementation detail: internal macro to create static category and add
+// event if the category is enabled.
+#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \
+ do { \
+ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
+ if (*INTERNALTRACEEVENTUID(catstatic)) { \
+ gl::TraceEvent::addTraceEvent( \
+ 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(category, name, ...) \
+ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
+ gl::TraceEvent::TraceEndOnScopeClose \
+ INTERNALTRACEEVENTUID(profileScope); \
+ if (*INTERNALTRACEEVENTUID(catstatic)) { \
+ gl::TraceEvent::addTraceEvent( \
+ TRACE_EVENT_PHASE_BEGIN, \
+ INTERNALTRACEEVENTUID(catstatic), \
+ name, gl::TraceEvent::noEventId, \
+ TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
+ INTERNALTRACEEVENTUID(profileScope).initialize( \
+ INTERNALTRACEEVENTUID(catstatic), name); \
+ }
+
+// Implementation detail: internal macro to create static category and add
+// event if the category is enabled.
+#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, \
+ ...) \
+ do { \
+ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \
+ if (*INTERNALTRACEEVENTUID(catstatic)) { \
+ unsigned char traceEventFlags = flags | TRACE_EVENT_FLAG_HAS_ID; \
+ gl::TraceEvent::TraceID traceEventTraceID( \
+ id, &traceEventFlags); \
+ gl::TraceEvent::addTraceEvent( \
+ 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 void addTraceEvent(char phase,
+ const unsigned char* categoryEnabled,
+ const char* name,
+ unsigned long long id,
+ unsigned char flags) {
+ TRACE_EVENT_API_ADD_TRACE_EVENT(
+ phase, categoryEnabled, name, id,
+ zeroNumArgs, 0, 0, 0,
+ flags);
+}
+
+template<class ARG1_TYPE>
+static inline void addTraceEvent(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]);
+ TRACE_EVENT_API_ADD_TRACE_EVENT(
+ phase, categoryEnabled, name, id,
+ numArgs, &arg1Name, argTypes, argValues,
+ flags);
+}
+
+template<class ARG1_TYPE, class ARG2_TYPE>
+static inline void addTraceEvent(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(
+ 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(const unsigned char* categoryEnabled,
+ const char* name)
+ {
+ 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(
+ 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 {
+ const unsigned char* categoryEnabled;
+ const char* name;
+ };
+ Data* m_pdata;
+ Data m_data;
+};
+
+} // namespace TraceEvent
+
+} // namespace gl
+
+#endif
diff --git a/src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch b/src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch
deleted file mode 100644
index ad3187ec7c..0000000000
--- a/src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch
+++ /dev/null
@@ -1,477 +0,0 @@
-From bd27c33a4a7c48bd14b9b6c18c8cdce1c3aae155 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@theqtcompany.com>
-Date: Fri, 14 Nov 2014 10:53:40 +0200
-Subject: [PATCH] General fixes for ANGLE 2.1
-
-- Fix commit.h include (use hard-coded version)
-- Fix export mismatch in libEGL.cpp and libGLESv2.cpp
-- Normalize all precompiled shader names and includes
-- Remove third-party event tracing; it was hardly used in ANGLE
- and not enabled in Qt builds anyway.
-
-Change-Id: I22254aed62e89a26756ca0784bae95909189c0f9
----
- src/3rdparty/angle/src/commit.h | 6 +-
- src/3rdparty/angle/src/common/version.h | 2 +-
- .../src/common/winrt/CoreWindowNativeWindow.cpp | 2 +-
- src/3rdparty/angle/src/libEGL/libEGL.cpp | 3 +
- src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp | 4 ++
- src/3rdparty/angle/src/libGLESv2/libGLESv2.def | 3 -
- .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 3 -
- .../src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp | 66 +++++++++++-----------
- .../src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp | 12 ++--
- .../renderer/d3d/d3d11/PixelTransfer11.cpp | 10 ++--
- .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 4 +-
- .../renderer/d3d/d3d11/shaders/Clear11.hlsl | 4 ++
- .../src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp | 20 +++----
- .../src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 12 ----
- .../libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps | 6 +-
- .../libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs | 4 +-
- 16 files changed, 76 insertions(+), 85 deletions(-)
-
-diff --git a/src/3rdparty/angle/src/commit.h b/src/3rdparty/angle/src/commit.h
-index 4c89a65..08fc893 100644
---- a/src/3rdparty/angle/src/commit.h
-+++ b/src/3rdparty/angle/src/commit.h
-@@ -7,8 +7,6 @@
- // This is a default commit hash header, when git is not available.
- //
-
--#define ANGLE_COMMIT_HASH "unknown hash"
-+#define ANGLE_COMMIT_HASH "30d6c255d238"
- #define ANGLE_COMMIT_HASH_SIZE 12
--#define ANGLE_COMMIT_DATE "unknown date"
--
--#define ANGLE_DISABLE_PROGRAM_BINARY_LOAD
-+#define ANGLE_COMMIT_DATE "2014-11-13 17:37:03 +0000"
-diff --git a/src/3rdparty/angle/src/common/version.h b/src/3rdparty/angle/src/common/version.h
-index d9148d1..f01e024 100644
---- a/src/3rdparty/angle/src/common/version.h
-+++ b/src/3rdparty/angle/src/common/version.h
-@@ -1,4 +1,4 @@
--#include "id/commit.h"
-+#include "../commit.h"
-
- #define ANGLE_MAJOR_VERSION 2
- #define ANGLE_MINOR_VERSION 1
-diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
-index 0de16f4..0e63fa5 100644
---- a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
-+++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
-@@ -184,4 +184,4 @@ long ConvertDipsToPixels(float dips)
- static const float dipsPerInch = 96.0f;
- return lround((dips * GetLogicalDpi() / dipsPerInch));
- }
--}
-\ No newline at end of file
-+}
-diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
-index 851b723..6110698 100644
---- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
-+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
-@@ -6,6 +6,9 @@
-
- // libEGL.cpp: Implements the exported EGL functions.
-
-+#undef EGLAPI
-+#define EGLAPI
-+
- #include <exception>
-
- #include "common/debug.h"
-diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
-index 2306168..587950a 100644
---- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
-@@ -6,6 +6,10 @@
-
- // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
-
-+#undef GL_APICALL
-+#define GL_APICALL
-+#define GL_GLEXT_PROTOTYPES
-+
- #include "common/version.h"
- #include "common/utilities.h"
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
-index 88dceb3..33557eb 100644
---- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
-+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
-@@ -294,6 +294,3 @@ EXPORTS
- glBindTexImage @158 NONAME
- glCreateRenderer @177 NONAME
- glDestroyRenderer @178 NONAME
--
-- ; Setting up TRACE macro callbacks
-- SetTraceFunctionPointers @284
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-index 5c44fe0..bfeaf51 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-@@ -11,8 +11,6 @@
- #include "common/features.h"
- #include "common/utilities.h"
-
--#include "third_party/trace_event/trace_event.h"
--
- // Definitions local to the translation unit
- namespace
- {
-@@ -120,7 +118,6 @@ HLSLCompiler::~HLSLCompiler()
-
- bool HLSLCompiler::initialize()
- {
-- TRACE_EVENT0("gpu", "initializeCompiler");
- #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
- // Find a D3DCompiler module that had already been loaded based on a predefined list of versions.
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
-index 8ed1650..91e7552 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
-@@ -13,39 +13,39 @@
- #include "libGLESv2/main.h"
- #include "libGLESv2/formatutils.h"
-
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h"
--
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2dps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2duips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2duips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2duips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2dps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2duips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr2dips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum2dps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2dps.h"
-+
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3dvs.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough3dgs.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3duips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3duips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3duips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3dps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3duips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughr3dips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlum3dps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3dps.h"
-
- #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h"
- #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h"
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
-index 12905d0..4630762 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
-@@ -15,14 +15,14 @@
- #include "libGLESv2/FramebufferAttachment.h"
-
- // Precompiled shaders
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloatvs.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloatps.h"
-
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuintvs.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuintps.h"
-
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsintvs.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsintps.h"
-
- namespace rx
- {
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
-index 1bc2bd8..a4072d8 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
-@@ -22,11 +22,11 @@
- #include "libGLESv2/Context.h"
-
- // Precompiled shaders
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexturevs.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexturegs.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture_4fps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture_4ips.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture_4uips.h"
-
- namespace rx
- {
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-index 3fcacf6..834b7bd 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-@@ -12,8 +12,8 @@
- #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-
- // Precompiled shaders
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
--#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthrough2dvs.h"
-+#include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dps.h"
-
- #include "common/features.h"
- #include "common/NativeWindow.h"
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl
-index 6deef2b..b4cf380 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/shaders/Clear11.hlsl
-@@ -13,10 +13,12 @@ struct PS_OutputFloat
- float4 color1 : SV_TARGET1;
- float4 color2 : SV_TARGET2;
- float4 color3 : SV_TARGET3;
-+#if SM4
- float4 color4 : SV_TARGET4;
- float4 color5 : SV_TARGET5;
- float4 color6 : SV_TARGET6;
- float4 color7 : SV_TARGET7;
-+#endif
- };
-
- PS_OutputFloat PS_ClearFloat(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR)
-@@ -26,10 +28,12 @@ PS_OutputFloat PS_ClearFloat(in float4 inPosition : SV_POSITION, in float4 inCol
- outColor.color1 = inColor;
- outColor.color2 = inColor;
- outColor.color3 = inColor;
-+#if SM4
- outColor.color4 = inColor;
- outColor.color5 = inColor;
- outColor.color6 = inColor;
- outColor.color7 = inColor;
-+#endif
- return outColor;
- }
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
-index d4fcd17..2ca7a9c 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp
-@@ -27,20 +27,20 @@ namespace
-
- const BYTE* const g_shaderCode[] =
- {
-- g_vs20_standardvs,
-- g_vs20_flipyvs,
-- g_ps20_passthroughps,
-- g_ps20_luminanceps,
-- g_ps20_componentmaskps
-+ g_vs20_VS_standard,
-+ g_vs20_VS_flipy,
-+ g_ps20_PS_passthrough,
-+ g_ps20_PS_luminance,
-+ g_ps20_PS_componentmask
- };
-
- const size_t g_shaderSize[] =
- {
-- sizeof(g_vs20_standardvs),
-- sizeof(g_vs20_flipyvs),
-- sizeof(g_ps20_passthroughps),
-- sizeof(g_ps20_luminanceps),
-- sizeof(g_ps20_componentmaskps)
-+ sizeof(g_vs20_VS_standard),
-+ sizeof(g_vs20_VS_flipy),
-+ sizeof(g_ps20_PS_passthrough),
-+ sizeof(g_ps20_PS_luminance),
-+ sizeof(g_ps20_PS_componentmask)
- };
- }
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-index 3bac4ba..82963ec 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-@@ -42,8 +42,6 @@
- #include "common/features.h"
- #include "common/utilities.h"
-
--#include "third_party/trace_event/trace_event.h"
--
- #include <sstream>
-
- // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
-@@ -185,7 +183,6 @@ EGLint Renderer9::initialize()
- return EGL_NOT_INITIALIZED;
- }
-
-- TRACE_EVENT0("gpu", "GetModuleHandle_d3d9");
- mD3d9Module = GetModuleHandle(TEXT("d3d9.dll"));
-
- if (mD3d9Module == NULL)
-@@ -202,14 +199,12 @@ EGLint Renderer9::initialize()
- // 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)))
- {
-- TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface");
- ASSERT(mD3d9Ex);
- mD3d9Ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void**>(&mD3d9));
- ASSERT(mD3d9);
- }
- else
- {
-- TRACE_EVENT0("gpu", "Direct3DCreate9");
- mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
- }
-
-@@ -228,7 +223,6 @@ EGLint Renderer9::initialize()
-
- // Give up on getting device caps after about one second.
- {
-- TRACE_EVENT0("gpu", "GetDeviceCaps");
- for (int i = 0; i < 10; ++i)
- {
- result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
-@@ -263,7 +257,6 @@ EGLint Renderer9::initialize()
- }
-
- {
-- TRACE_EVENT0("gpu", "GetAdapterIdentifier");
- mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier);
- }
-
-@@ -300,7 +293,6 @@ EGLint Renderer9::initialize()
- static const TCHAR className[] = TEXT("STATIC");
-
- {
-- TRACE_EVENT0("gpu", "CreateWindowEx");
- mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
- }
-
-@@ -308,7 +300,6 @@ EGLint Renderer9::initialize()
- DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
-
- {
-- TRACE_EVENT0("gpu", "D3d9_CreateDevice");
- result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
- }
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
-@@ -318,7 +309,6 @@ EGLint Renderer9::initialize()
-
- if (FAILED(result))
- {
-- TRACE_EVENT0("gpu", "D3d9_CreateDevice2");
- result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
-
- if (FAILED(result))
-@@ -330,13 +320,11 @@ EGLint Renderer9::initialize()
-
- if (mD3d9Ex)
- {
-- TRACE_EVENT0("gpu", "mDevice_QueryInterface");
- result = mDevice->QueryInterface(__uuidof(IDirect3DDevice9Ex), (void**)&mDeviceEx);
- ASSERT(SUCCEEDED(result));
- }
-
- {
-- TRACE_EVENT0("gpu", "ShaderCache initialize");
- mVertexShaderCache.initialize(mDevice);
- mPixelShaderCache.initialize(mDevice);
- }
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps
-index dc357d0..eb43eb3 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.ps
-@@ -11,7 +11,7 @@ uniform float4 add : c1;
-
- // Passthrough Pixel Shader
- // Outputs texture 0 sampled at texcoord 0.
--float4 passthroughps(float4 texcoord : TEXCOORD0) : COLOR
-+float4 PS_passthrough(float4 texcoord : TEXCOORD0) : COLOR
- {
- return tex2D(tex, texcoord.xy);
- };
-@@ -19,7 +19,7 @@ float4 passthroughps(float4 texcoord : TEXCOORD0) : COLOR
- // Luminance Conversion Pixel Shader
- // Performs a mad operation using the LA data from the texture with mult.xw and add.xw.
- // Returns data in the form of llla
--float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR
-+float4 PS_luminance(float4 texcoord : TEXCOORD0) : COLOR
- {
- return (tex2D(tex, texcoord.xy).xw * mult.xw + add.xw).xxxy;
- };
-@@ -27,7 +27,7 @@ float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR
- // RGB/A Component Mask Pixel Shader
- // Performs a mad operation using the texture's RGBA data with mult.xyzw and add.xyzw.
- // Returns data in the form of rgba
--float4 componentmaskps(float4 texcoord : TEXCOORD0) : COLOR
-+float4 PS_componentmask(float4 texcoord : TEXCOORD0) : COLOR
- {
- return tex2D(tex, texcoord.xy) * mult + add;
- };
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs
-index 3a36980..3bd611b 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/shaders/Blit.vs
-@@ -17,7 +17,7 @@ uniform float4 halfPixelSize : c0;
- // Outputs the homogenous position as-is.
- // Outputs a tex coord with (0,0) in the upper-left corner of the screen and (1,1) in the bottom right.
- // C0.X must be negative half-pixel width, C0.Y must be half-pixel height. C0.ZW must be 0.
--VS_OUTPUT standardvs(in float4 position : POSITION)
-+VS_OUTPUT VS_standard(in float4 position : POSITION)
- {
- VS_OUTPUT Out;
-
-@@ -32,7 +32,7 @@ VS_OUTPUT standardvs(in float4 position : POSITION)
- // Outputs the homogenous position as-is.
- // Outputs a tex coord with (0,1) in the upper-left corner of the screen and (1,0) in the bottom right.
- // C0.XY must be the half-pixel width and height. C0.ZW must be 0.
--VS_OUTPUT flipyvs(in float4 position : POSITION)
-+VS_OUTPUT VS_flipy(in float4 position : POSITION)
- {
- VS_OUTPUT Out;
-
---
-1.9.4.msysgit.1
-
diff --git a/src/angle/patches/0001-ANGLE-Improve-Windows-Phone-Support.patch b/src/angle/patches/0001-ANGLE-Improve-Windows-Phone-Support.patch
new file mode 100644
index 0000000000..1361b8b656
--- /dev/null
+++ b/src/angle/patches/0001-ANGLE-Improve-Windows-Phone-Support.patch
@@ -0,0 +1,439 @@
+From ed09eff731b5d286e0bf6a5958b937a50ecc2362 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@intopalo.com>
+Date: Tue, 7 Apr 2015 13:24:59 +0300
+Subject: [PATCH 1/5] ANGLE: Improve Windows Phone Support
+
+This contains compile fixes for Windows Phone as well as improved
+orientation handling.
+
+Change-Id: Ia312b5318b977838a2953f1f530487cbf24974bc
+---
+ src/3rdparty/angle/src/common/platform.h | 2 ++
+ .../renderer/d3d/d3d11/DebugAnnotator11.cpp | 2 +-
+ .../src/libANGLE/renderer/d3d/d3d11/NativeWindow.h | 4 +++
+ .../src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 8 +++--
+ .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 40 ++++++++++++++++++++++
+ .../d3d/d3d11/winrt/CoreWindowNativeWindow.cpp | 31 +++++++++++++++--
+ .../d3d/d3d11/winrt/CoreWindowNativeWindow.h | 34 +++++++++++++++++-
+ .../d3d/d3d11/winrt/InspectableNativeWindow.cpp | 12 +++++++
+ .../d3d/d3d11/winrt/InspectableNativeWindow.h | 14 +++++++-
+ src/3rdparty/angle/src/libANGLE/validationEGL.cpp | 4 ++-
+ 10 files changed, 142 insertions(+), 9 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
+index 56db297..4e3851c 100644
+--- a/src/3rdparty/angle/src/common/platform.h
++++ b/src/3rdparty/angle/src/common/platform.h
+@@ -68,7 +68,9 @@
+ # if defined(ANGLE_ENABLE_WINDOWS_STORE)
+ # include <dxgi1_3.h>
+ # if defined(_DEBUG)
++# if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
+ # include <DXProgrammableCapture.h>
++# endif
+ # include <dxgidebug.h>
+ # endif
+ # endif
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
+index bc7cdcc..fcca904 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
+@@ -60,7 +60,7 @@ bool DebugAnnotator11::getStatus()
+ {
+ // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in Visual Studio 2013.
+
+-#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE)
++#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
+ // In the Windows Store, we can use IDXGraphicsAnalysis. The call to GetDebugInterface1 only succeeds if the app is under capture.
+ // This should only be called in DEBUG mode.
+ // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows Store ingestion checks.
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h
+index ce50c32..81b9ea7 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h
+@@ -49,11 +49,15 @@ namespace rx
+ class NativeWindow
+ {
+ public:
++ enum RotationFlags { RotateNone = 0, RotateLeft = 1, RotateRight = 2 };
+ explicit NativeWindow(EGLNativeWindowType window);
+
+ bool initialize();
+ bool getClientRect(LPRECT rect);
+ bool isIconic();
++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++ RotationFlags rotationFlags() const;
++#endif
+ static bool isValidNativeWindow(EGLNativeWindowType window);
+
+ HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory,
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+index eba40a4..dbed23f 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+@@ -230,7 +230,11 @@ Renderer11::Renderer11(egl::Display *display)
+ }
+ }
+
++#if defined(ANGLE_ENABLE_WINDOWS_STORE)
++ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9)
++#else
+ if (requestedMajorVersion == 9 && requestedMinorVersion == 3)
++#endif
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3);
+ }
+@@ -587,10 +591,10 @@ egl::ConfigSet Renderer11::generateConfigs() const
+ config.bindToTextureRGB = (colorBufferFormatInfo.format == GL_RGB);
+ config.bindToTextureRGBA = (colorBufferFormatInfo.format == GL_RGBA || colorBufferFormatInfo.format == GL_BGRA_EXT);
+ config.colorBufferType = EGL_RGB_BUFFER;
+- config.configCaveat = EGL_NONE;
+ config.configID = static_cast<EGLint>(configs.size() + 1);
+ // Can only support a conformant ES2 with feature level greater than 10.0.
+ config.conformant = (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) ? (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR) : EGL_NONE;
++ config.configCaveat = config.conformant == EGL_NONE ? EGL_NON_CONFORMANT_CONFIG : EGL_NONE;
+ config.depthSize = depthStencilBufferFormatInfo.depthBits;
+ config.level = 0;
+ config.matchNativePixmap = EGL_NONE;
+@@ -2290,7 +2294,7 @@ bool Renderer11::getShareHandleSupport() const
+ // chrome needs BGRA. Once chrome fixes this, we should always support them.
+ // PIX doesn't seem to support using share handles, so disable them.
+ // Also disable share handles on Feature Level 9_3, since it doesn't support share handles on RGBA8 textures/swapchains.
+- return getRendererExtensions().textureFormatBGRA8888 && !gl::DebugAnnotationsActive() && !(mFeatureLevel <= D3D_FEATURE_LEVEL_9_3);
++ return getRendererExtensions().textureFormatBGRA8888 && !gl::DebugAnnotationsActive();// && !(mFeatureLevel <= D3D_FEATURE_LEVEL_9_3); Qt: we don't care about the 9_3 limitation
+ }
+
+ bool Renderer11::getPostSubBufferSupport() const
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+index 2558528..bcb2505 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+@@ -154,8 +154,14 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
+ const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport();
+
+ D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++ const int textureLength = std::max(backbufferWidth, backbufferHeight);
++ offscreenTextureDesc.Width = textureLength;
++ offscreenTextureDesc.Height = textureLength;
++#else
+ offscreenTextureDesc.Width = backbufferWidth;
+ offscreenTextureDesc.Height = backbufferHeight;
++#endif
+ offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
+ offscreenTextureDesc.MipLevels = 1;
+ offscreenTextureDesc.ArraySize = 1;
+@@ -235,8 +241,14 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
+ if (mDepthBufferFormat != GL_NONE)
+ {
+ D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++ const int textureLength = std::max(backbufferWidth, backbufferHeight);
++ depthStencilTextureDesc.Width = textureLength;
++ depthStencilTextureDesc.Height = textureLength;
++#else
+ depthStencilTextureDesc.Width = backbufferWidth;
+ depthStencilTextureDesc.Height = backbufferHeight;
++#endif
+ depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
+ depthStencilTextureDesc.MipLevels = 1;
+ depthStencilTextureDesc.ArraySize = 1;
+@@ -337,6 +349,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
+ return EGL_SUCCESS;
+ }
+
++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
+ // Can only call resize if we have already created our swap buffer and resources
+ ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
+
+@@ -379,6 +392,12 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
+ }
+
+ return resetOffscreenTexture(backbufferWidth, backbufferHeight);
++#else
++ // Do nothing on Windows Phone apart from updating the internal buffer/width height
++ mWidth = backbufferWidth;
++ mHeight = backbufferHeight;
++ return EGL_SUCCESS;
++#endif
+ }
+
+ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
+@@ -539,6 +558,21 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f;
+ float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f;
+
++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++ const float dim = std::max(mWidth, mHeight);
++ float u1 = x / dim;
++ float v1 = y / dim;
++ float u2 = (x + width) / dim;
++ float v2 = (y + height) / dim;
++
++ const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags();
++ const bool rotateL = flags == NativeWindow::RotateLeft;
++ const bool rotateR = flags == NativeWindow::RotateRight;
++ d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1);
++ d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2);
++ d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1);
++ d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2);
++#else
+ float u1 = x / float(mWidth);
+ float v1 = y / float(mHeight);
+ float u2 = (x + width) / float(mWidth);
+@@ -548,6 +582,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
+ d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
+ d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
++#endif
+
+ deviceContext->Unmap(mQuadVB, 0);
+
+@@ -577,8 +612,13 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0;
+ viewport.TopLeftY = 0;
++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++ viewport.Width = (rotateL || rotateR) ? mHeight : mWidth;
++ viewport.Height = (rotateL || rotateR) ? mWidth : mHeight;
++#else
+ viewport.Width = mWidth;
+ viewport.Height = mHeight;
++#endif
+ viewport.MinDepth = 0.0f;
+ viewport.MaxDepth = 1.0f;
+ deviceContext->RSSetViewports(1, &viewport);
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
+index 8cfaa84..350526c 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
+@@ -8,8 +8,6 @@
+
+ #include "libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h"
+
+-#include <windows.graphics.display.h>
+-
+ using namespace ABI::Windows::Foundation::Collections;
+
+ namespace rx
+@@ -21,6 +19,7 @@ CoreWindowNativeWindow::~CoreWindowNativeWindow()
+
+ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet)
+ {
++ mOrientationChangedEventToken.value = 0;
+ ComPtr<IPropertySet> props = propertySet;
+ ComPtr<IInspectable> win = window;
+ SIZE swapChainSize = {};
+@@ -68,6 +67,16 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet
+
+ if (SUCCEEDED(result))
+ {
++ ComPtr<ABI::Windows::Graphics::Display::IDisplayInformationStatics> displayInformation;
++ result = GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), &displayInformation);
++ if (SUCCEEDED(result))
++ {
++ result = displayInformation->GetForCurrentView(&mDisplayInformation);
++ }
++ }
++
++ if (SUCCEEDED(result))
++ {
+ mNewClientRect = mClientRect;
+ mClientRectChanged = false;
+ return registerForSizeChangeEvents();
+@@ -85,6 +94,15 @@ bool CoreWindowNativeWindow::registerForSizeChangeEvents()
+ result = mCoreWindow->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken);
+ }
+
++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++ ComPtr<IDisplayOrientationEventHandler> orientationChangedHandler;
++ result = sizeChangedHandler.As(&orientationChangedHandler);
++ if (SUCCEEDED(result))
++ {
++ result = mDisplayInformation->add_OrientationChanged(orientationChangedHandler.Get(), &mOrientationChangedEventToken);
++ }
++#endif
++
+ if (SUCCEEDED(result))
+ {
+ return true;
+@@ -99,7 +117,14 @@ void CoreWindowNativeWindow::unregisterForSizeChangeEvents()
+ {
+ (void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken);
+ }
++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++ if (mDisplayInformation)
++ {
++ (void)mDisplayInformation->remove_OrientationChanged(mOrientationChangedEventToken);
++ }
++#endif
+ mSizeChangedEventToken.value = 0;
++ mOrientationChangedEventToken.value = 0;
+ }
+
+ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
+@@ -128,7 +153,7 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor
+ if (SUCCEEDED(result))
+ {
+
+-#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++#if 0 //(WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // Qt: allow Windows Phone to resize, but don't modify the backing texture in the swap chain.
+ // Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On
+ // other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed
+ // (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations.
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
+index c230c84..59df9d5 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
+@@ -12,8 +12,10 @@
+ #include "libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h"
+
+ #include <memory>
++#include <windows.graphics.display.h>
+
+ typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t IWindowSizeChangedEventHandler;
++typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_t IDisplayOrientationEventHandler;
+
+ namespace rx
+ {
+@@ -32,11 +34,13 @@ class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enabl
+ private:
+ ComPtr<ABI::Windows::UI::Core::ICoreWindow> mCoreWindow;
+ ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
++ ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation> mDisplayInformation;
++ EventRegistrationToken mOrientationChangedEventToken;
+ };
+
+ [uuid(7F924F66-EBAE-40E5-A10B-B8F35E245190)]
+ class CoreWindowSizeChangedHandler :
+- public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWindowSizeChangedEventHandler>
++ public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWindowSizeChangedEventHandler, IDisplayOrientationEventHandler>
+ {
+ public:
+ CoreWindowSizeChangedHandler() { }
+@@ -68,6 +72,34 @@ class CoreWindowSizeChangedHandler :
+ return S_OK;
+ }
+
++ IFACEMETHOD(Invoke)(ABI::Windows::Graphics::Display::IDisplayInformation *displayInformation, IInspectable *)
++ {
++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++ NativeWindow::RotationFlags flags = NativeWindow::RotateNone;
++ ABI::Windows::Graphics::Display::DisplayOrientations orientation;
++ if (SUCCEEDED(displayInformation->get_CurrentOrientation(&orientation)))
++ {
++ switch (orientation)
++ {
++ case ABI::Windows::Graphics::Display::DisplayOrientations_Landscape:
++ flags = NativeWindow::RotateLeft;
++ break;
++ case ABI::Windows::Graphics::Display::DisplayOrientations_LandscapeFlipped:
++ flags = NativeWindow::RotateRight;
++ break;
++ default:
++ break;
++ }
++ }
++ std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
++ if (host)
++ {
++ host->setRotationFlags(flags);
++ }
++#endif
++ return S_OK;
++ }
++
+ private:
+ std::weak_ptr<InspectableNativeWindow> mHost;
+ };
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
+index 7ac53c7..2bf48c5 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
+@@ -69,6 +69,18 @@ bool NativeWindow::getClientRect(RECT *rect)
+ return false;
+ }
+
++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
++NativeWindow::RotationFlags NativeWindow::rotationFlags() const
++{
++ if (mImpl)
++ {
++ return mImpl->rotationFlags();
++ }
++
++ return NativeWindow::RotateNone;
++}
++#endif
++
+ bool NativeWindow::isIconic()
+ {
+ return false;
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
+index e89c900..575bdf8 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
+@@ -34,7 +34,8 @@ class InspectableNativeWindow
+ mRequiresSwapChainScaling(false),
+ mClientRectChanged(false),
+ mClientRect({0,0,0,0}),
+- mNewClientRect({0,0,0,0})
++ mNewClientRect({0,0,0,0}),
++ mRotationFlags(NativeWindow::RotateNone)
+ {
+ mSizeChangedEventToken.value = 0;
+ }
+@@ -72,12 +73,23 @@ class InspectableNativeWindow
+ }
+ }
+
++ NativeWindow::RotationFlags rotationFlags() const
++ {
++ return mRotationFlags;
++ }
++
++ void setRotationFlags(NativeWindow::RotationFlags flags)
++ {
++ mRotationFlags = flags;
++ }
++
+ protected:
+ bool mSupportsSwapChainResize;
+ bool mRequiresSwapChainScaling;
+ RECT mClientRect;
+ RECT mNewClientRect;
+ bool mClientRectChanged;
++ NativeWindow::RotationFlags mRotationFlags;
+
+ EventRegistrationToken mSizeChangedEventToken;
+ };
+diff --git a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp
+index 4e3b44b..12ee6a2 100644
+--- a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp
++++ b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp
+@@ -160,7 +160,7 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context
+ return Error(EGL_BAD_CONFIG);
+ }
+
+- if (clientMajorVersion == 3 && !(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR))
++ if (clientMajorVersion == 3 && !(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR) && !(configuration->configCaveat & EGL_NON_CONFORMANT_CONFIG))
+ {
+ return Error(EGL_BAD_CONFIG);
+ }
+@@ -488,11 +488,13 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E
+ return Error(EGL_BAD_ATTRIBUTE);
+ }
+
++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) // On Windows Store, we know the originating texture came from D3D11, so bypass this check
+ const Caps &caps = display->getCaps();
+ if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
+ {
+ return Error(EGL_BAD_MATCH);
+ }
++#endif
+ }
+
+ return Error(EGL_SUCCESS);
+--
+2.1.4
+
diff --git a/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch b/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch
new file mode 100644
index 0000000000..e28bc797e3
--- /dev/null
+++ b/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch
@@ -0,0 +1,927 @@
+From 6f98a957829fd37106fb1f1c9f43a5bad626cdfc Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@intopalo.com>
+Date: Wed, 25 Mar 2015 20:21:33 +0200
+Subject: [PATCH 2/5] ANGLE: Fix compilation with MinGW
+
+This adds definition guards for Direct3D 11 and DirectX SDK layers, which
+are only available in very recent versions (4.9.2 rev 4) of MinGW builds.
+It additionally adds a few missing includes needed for compilation.
+
+Change-Id: I254c208209c0071fae5efb6727f2b3cfd5542da6
+---
+ src/3rdparty/angle/src/common/mathutil.h | 4 +
+ src/3rdparty/angle/src/common/platform.h | 10 +-
+ src/3rdparty/angle/src/libANGLE/angletypes.h | 1 +
+ .../src/libANGLE/renderer/d3d/HLSLCompiler.cpp | 9 ++
+ .../src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp | 6 +
+ .../src/libANGLE/renderer/d3d/d3d11/Clear11.cpp | 4 +
+ .../renderer/d3d/d3d11/DebugAnnotator11.cpp | 10 ++
+ .../libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h | 2 +
+ .../src/libANGLE/renderer/d3d/d3d11/Query11.cpp | 7 +
+ .../src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 83 +++++++++--
+ .../src/libANGLE/renderer/d3d/d3d11/Renderer11.h | 3 +-
+ .../renderer/d3d/d3d11/renderer11_utils.cpp | 152 +++++++++++++++++++++
+ .../src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp | 4 +-
+ 13 files changed, 283 insertions(+), 12 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h
+index e096b1a..1015bd2 100644
+--- a/src/3rdparty/angle/src/common/mathutil.h
++++ b/src/3rdparty/angle/src/common/mathutil.h
+@@ -119,6 +119,9 @@ inline bool supportsSSE2()
+ return supports;
+ }
+
++#if defined(__GNUC__)
++ supports = __builtin_cpu_supports("sse2");
++#else
+ int info[4];
+ __cpuid(info, 0);
+
+@@ -128,6 +131,7 @@ inline bool supportsSSE2()
+
+ supports = (info[3] >> 26) & 1;
+ }
++#endif
+
+ checked = true;
+
+diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
+index 4e3851c..be4cb94 100644
+--- a/src/3rdparty/angle/src/common/platform.h
++++ b/src/3rdparty/angle/src/common/platform.h
+@@ -59,9 +59,17 @@
+ # if defined(ANGLE_ENABLE_D3D11)
+ # include <d3d10_1.h>
+ # include <d3d11.h>
+-# include <d3d11_1.h>
+ # include <dxgi.h>
++# if defined(__MINGW32__) && !defined(__d3d11sdklayers_h__)
++# define ANGLE_MINGW32_COMPAT
++# endif
++# if defined(_MSC_VER) && _MSC_VER >= 1800
++# define ANGLE_ENABLE_D3D11_1
++# endif
++# if defined(ANGLE_ENABLE_D3D11_1)
++# include <d3d11_1.h>
+ # include <dxgi1_2.h>
++# endif
+ # include <d3dcompiler.h>
+ # endif
+
+diff --git a/src/3rdparty/angle/src/libANGLE/angletypes.h b/src/3rdparty/angle/src/libANGLE/angletypes.h
+index a5f471d..e4e08b5 100644
+--- a/src/3rdparty/angle/src/libANGLE/angletypes.h
++++ b/src/3rdparty/angle/src/libANGLE/angletypes.h
+@@ -13,6 +13,7 @@
+ #include "libANGLE/RefCountObject.h"
+
+ #include <stdint.h>
++#include <float.h>
+
+ namespace gl
+ {
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
+index d709dca..9c72d6f 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
+@@ -22,6 +22,15 @@ namespace
+
+ #define CREATE_COMPILER_FLAG_INFO(flag) { flag, #flag }
+
++#if defined(ANGLE_MINGW32_COMPAT)
++#ifndef D3DCOMPILE_RESERVED16
++#define D3DCOMPILE_RESERVED16 0x10000
++#endif
++#ifndef D3DCOMPILE_RESERVED17
++#define D3DCOMPILE_RESERVED17 0x20000
++#endif
++#endif
++
+ struct CompilerFlagInfo
+ {
+ UINT mFlag;
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
+index 3b36c64..d56b0ea 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
+@@ -12,6 +12,12 @@
+ #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+ #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+
++#if defined(ANGLE_MINGW32_COMPAT)
++typedef enum D3D11_MAP_FLAG {
++ D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000
++} D3D11_MAP_FLAG;
++#endif
++
+ namespace rx
+ {
+
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
+index ae373f5..057c3be 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
+@@ -133,12 +133,14 @@ Clear11::Clear11(Renderer11 *renderer)
+ mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint );
+ }
+
++#if defined(ANGLE_ENABLE_D3D11_1)
+ if (renderer->getDeviceContext1IfSupported())
+ {
+ D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options;
+ device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
+ mSupportsClearView = (d3d11Options.ClearView != FALSE);
+ }
++#endif
+ }
+
+ Clear11::~Clear11()
+@@ -321,6 +323,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
+
+ if (needScissoredClear)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ // We shouldn't reach here if deviceContext1 is unavailable.
+ ASSERT(deviceContext1);
+
+@@ -331,6 +334,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
+ rect.bottom = clearParams.scissor.y + clearParams.scissor.height;
+
+ deviceContext1->ClearView(framebufferRTV, clearValues, &rect, 1);
++#endif
+ }
+ else
+ {
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
+index fcca904..f1fe2bb 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
+@@ -27,7 +27,9 @@ DebugAnnotator11::~DebugAnnotator11()
+ {
+ if (mInitialized)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ SafeRelease(mUserDefinedAnnotation);
++#endif
+
+ #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ FreeLibrary(mD3d11Module);
+@@ -39,21 +41,27 @@ void DebugAnnotator11::beginEvent(const std::wstring &eventName)
+ {
+ initializeDevice();
+
++#if defined(ANGLE_ENABLE_D3D11_1)
+ mUserDefinedAnnotation->BeginEvent(eventName.c_str());
++#endif
+ }
+
+ void DebugAnnotator11::endEvent()
+ {
+ initializeDevice();
+
++#if defined(ANGLE_ENABLE_D3D11_1)
+ mUserDefinedAnnotation->EndEvent();
++#endif
+ }
+
+ void DebugAnnotator11::setMarker(const std::wstring &markerName)
+ {
+ initializeDevice();
+
++#if defined(ANGLE_ENABLE_D3D11_1)
+ mUserDefinedAnnotation->SetMarker(markerName.c_str());
++#endif
+ }
+
+ bool DebugAnnotator11::getStatus()
+@@ -96,8 +104,10 @@ void DebugAnnotator11::initializeDevice()
+ hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context);
+ ASSERT(SUCCEEDED(hr));
+
++#if defined(ANGLE_ENABLE_D3D11_1)
+ mUserDefinedAnnotation = d3d11::DynamicCastComObject<ID3DUserDefinedAnnotation>(context);
+ ASSERT(mUserDefinedAnnotation != nullptr);
++#endif
+
+ SafeRelease(device);
+ SafeRelease(context);
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h
+index 0638364..3df62b0 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h
+@@ -11,6 +11,8 @@
+
+ #include "common/debug.h"
+
++struct ID3DUserDefinedAnnotation;
++
+ namespace rx
+ {
+
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
+index e010190..4979ff5 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
+@@ -13,6 +13,13 @@
+
+ #include <GLES2/gl2ext.h>
+
++#if defined(ANGLE_MINGW32_COMPAT)
++typedef struct D3D11_QUERY_DATA_SO_STATISTICS {
++ UINT64 NumPrimitivesWritten;
++ UINT64 PrimitivesStorageNeeded;
++} D3D11_QUERY_DATA_SO_STATISTICS;
++#endif
++
+ namespace rx
+ {
+
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+index dbed23f..5291a3a 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+@@ -62,6 +62,67 @@
+ #define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1
+ #endif
+
++#ifndef __d3d11sdklayers_h__
++#define D3D11_MESSAGE_CATEGORY UINT
++#define D3D11_MESSAGE_SEVERITY UINT
++#define D3D11_MESSAGE_ID UINT
++struct D3D11_MESSAGE;
++typedef struct D3D11_INFO_QUEUE_FILTER_DESC
++{
++ UINT NumCategories;
++ D3D11_MESSAGE_CATEGORY *pCategoryList;
++ UINT NumSeverities;
++ D3D11_MESSAGE_SEVERITY *pSeverityList;
++ UINT NumIDs;
++ D3D11_MESSAGE_ID *pIDList;
++} D3D11_INFO_QUEUE_FILTER_DESC;
++typedef struct D3D11_INFO_QUEUE_FILTER
++{
++ D3D11_INFO_QUEUE_FILTER_DESC AllowList;
++ D3D11_INFO_QUEUE_FILTER_DESC DenyList;
++} D3D11_INFO_QUEUE_FILTER;
++static const IID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 };
++MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") ID3D11InfoQueue : public IUnknown
++{
++public:
++ virtual HRESULT __stdcall SetMessageCountLimit(UINT64) = 0;
++ virtual void __stdcall ClearStoredMessages() = 0;
++ virtual HRESULT __stdcall GetMessage(UINT64, D3D11_MESSAGE *, SIZE_T *) = 0;
++ virtual UINT64 __stdcall GetNumMessagesAllowedByStorageFilter() = 0;
++ virtual UINT64 __stdcall GetNumMessagesDeniedByStorageFilter() = 0;
++ virtual UINT64 __stdcall GetNumStoredMessages() = 0;
++ virtual UINT64 __stdcall GetNumStoredMessagesAllowedByRetrievalFilter() = 0;
++ virtual UINT64 __stdcall GetNumMessagesDiscardedByMessageCountLimit() = 0;
++ virtual UINT64 __stdcall GetMessageCountLimit() = 0;
++ virtual HRESULT __stdcall AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
++ virtual HRESULT __stdcall GetStorageFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
++ virtual void __stdcall ClearStorageFilter() = 0;
++ virtual HRESULT __stdcall PushEmptyStorageFilter() = 0;
++ virtual HRESULT __stdcall PushCopyOfStorageFilter() = 0;
++ virtual HRESULT __stdcall PushStorageFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
++ virtual void __stdcall PopStorageFilter() = 0;
++ virtual UINT __stdcall GetStorageFilterStackSize() = 0;
++ virtual HRESULT __stdcall AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
++ virtual HRESULT __stdcall GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
++ virtual void __stdcall ClearRetrievalFilter() = 0;
++ virtual HRESULT __stdcall PushEmptyRetrievalFilter() = 0;
++ virtual HRESULT __stdcall PushCopyOfRetrievalFilter() = 0;
++ virtual HRESULT __stdcall PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
++ virtual void __stdcall PopRetrievalFilter() = 0;
++ virtual UINT __stdcall GetRetrievalFilterStackSize() = 0;
++ virtual HRESULT __stdcall AddMessage(D3D11_MESSAGE_CATEGORY, D3D11_MESSAGE_SEVERITY, D3D11_MESSAGE_ID, LPCSTR) = 0;
++ virtual HRESULT __stdcall AddApplicationMessage(D3D11_MESSAGE_SEVERITY, LPCSTR) = 0;
++ virtual HRESULT __stdcall SetBreakOnCategory(D3D11_MESSAGE_CATEGORY, BOOL) = 0;
++ virtual HRESULT __stdcall SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY, BOOL) = 0;
++ virtual HRESULT __stdcall SetBreakOnID(D3D11_MESSAGE_ID, BOOL) = 0;
++ virtual BOOL __stdcall GetBreakOnCategory(D3D11_MESSAGE_CATEGORY) = 0;
++ virtual BOOL __stdcall GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY) = 0;
++ virtual BOOL __stdcall GetBreakOnID(D3D11_MESSAGE_ID) = 0;
++ virtual void __stdcall SetMuteDebugOutput(BOOL) = 0;
++ virtual BOOL __stdcall GetMuteDebugOutput() = 0;
++};
++#endif
++
+ namespace rx
+ {
+
+@@ -164,8 +225,7 @@ void CalculateConstantBufferParams(GLintptr offset, GLsizeiptr size, UINT *outFi
+
+ Renderer11::Renderer11(egl::Display *display)
+ : RendererD3D(display),
+- mStateCache(this),
+- mDebug(nullptr)
++ mStateCache(this)
+ {
+ // Initialize global annotator
+ gl::InitializeDebugAnnotations(&mAnnotator);
+@@ -398,7 +458,9 @@ egl::Error Renderer11::initialize()
+ // Cast the DeviceContext to a DeviceContext1.
+ // This could fail on Windows 7 without the Platform Update.
+ // Don't error in this case- just don't use mDeviceContext1.
++#if defined(ANGLE_ENABLE_D3D11_1)
+ mDeviceContext1 = d3d11::DynamicCastComObject<ID3D11DeviceContext1>(mDeviceContext);
++#endif
+
+ IDXGIDevice *dxgiDevice = NULL;
+ result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
+@@ -421,6 +483,7 @@ egl::Error Renderer11::initialize()
+
+ SafeRelease(dxgiDevice);
+
++#if defined(ANGLE_ENABLE_D3D11_1)
+ IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject<IDXGIAdapter2>(mDxgiAdapter);
+
+ // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter" for the description string.
+@@ -447,6 +510,7 @@ egl::Error Renderer11::initialize()
+ }
+
+ SafeRelease(dxgiAdapter2);
++#endif
+
+ memset(mDescription, 0, sizeof(mDescription));
+ wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
+@@ -463,7 +527,7 @@ egl::Error Renderer11::initialize()
+ // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
+ #if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
+ ID3D11InfoQueue *infoQueue;
+- result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue);
++ result = mDevice->QueryInterface(IID_ID3D11InfoQueue, (void **)&infoQueue);
+
+ if (SUCCEEDED(result))
+ {
+@@ -481,10 +545,6 @@ egl::Error Renderer11::initialize()
+ }
+ #endif
+
+-#if !defined(NDEBUG)
+- mDebug = d3d11::DynamicCastComObject<ID3D11Debug>(mDevice);
+-#endif
+-
+ initializeDevice();
+
+ return egl::Error(EGL_SUCCESS);
+@@ -525,12 +585,14 @@ void Renderer11::initializeDevice()
+
+ const gl::Caps &rendererCaps = getRendererCaps();
+
++#if defined(ANGLE_ENABLE_D3D11_1)
+ if (getDeviceContext1IfSupported())
+ {
+ D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options;
+ mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
+ mSupportsConstantBufferOffsets = (d3d11Options.ConstantBufferOffsetting != FALSE);
+ }
++#endif
+
+ mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
+ mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
+@@ -853,6 +915,7 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
+ mCurrentConstantBufferVSOffset[uniformBufferIndex] != uniformBufferOffset ||
+ mCurrentConstantBufferVSSize[uniformBufferIndex] != uniformBufferSize)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ if (mSupportsConstantBufferOffsets && uniformBufferSize != 0)
+ {
+ UINT firstConstant = 0, numConstants = 0;
+@@ -861,6 +924,7 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
+ 1, &constantBuffer, &firstConstant, &numConstants);
+ }
+ else
++#endif
+ {
+ ASSERT(uniformBufferOffset == 0);
+ mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers() + uniformBufferIndex,
+@@ -901,6 +965,7 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
+ mCurrentConstantBufferPSOffset[uniformBufferIndex] != uniformBufferOffset ||
+ mCurrentConstantBufferPSSize[uniformBufferIndex] != uniformBufferSize)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ if (mSupportsConstantBufferOffsets && uniformBufferSize != 0)
+ {
+ UINT firstConstant = 0, numConstants = 0;
+@@ -909,6 +974,7 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data,
+ 1, &constantBuffer, &firstConstant, &numConstants);
+ }
+ else
++#endif
+ {
+ ASSERT(uniformBufferOffset == 0);
+ mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers() + uniformBufferIndex,
+@@ -2194,7 +2260,9 @@ void Renderer11::release()
+ SafeRelease(mDxgiFactory);
+ SafeRelease(mDxgiAdapter);
+
++#if defined(ANGLE_ENABLE_D3D11_1)
+ SafeRelease(mDeviceContext1);
++#endif
+
+ if (mDeviceContext)
+ {
+@@ -2204,7 +2272,6 @@ void Renderer11::release()
+ }
+
+ SafeRelease(mDevice);
+- SafeRelease(mDebug);
+
+ if (mD3d11Module)
+ {
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
+index d1fec55..cc7d6c2 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
+@@ -20,6 +20,8 @@
+ #include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
+ #include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
+
++struct ID3D11DeviceContext1;
++
+ namespace gl
+ {
+ class FramebufferAttachment;
+@@ -390,7 +392,6 @@ class Renderer11 : public RendererD3D
+ DXGI_ADAPTER_DESC mAdapterDescription;
+ char mDescription[128];
+ DXGIFactory *mDxgiFactory;
+- ID3D11Debug *mDebug;
+
+ DebugAnnotator11 mAnnotator;
+ };
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+index 70b2b79..63085f4 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+@@ -20,6 +20,88 @@
+
+ #include <algorithm>
+
++#ifndef D3D_FL9_1_DEFAULT_MAX_ANISOTROPY
++# define D3D_FL9_1_DEFAULT_MAX_ANISOTROPY 2
++#endif
++#ifndef D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT
++# define D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT 1
++#endif
++#ifndef D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT
++# define D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT 4
++#endif
++#ifndef D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT
++# define D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT 65535
++#endif
++#ifndef D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT
++# define D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT 1048575
++#endif
++#ifndef D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION
++# define D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION 512
++#endif
++#ifndef D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION
++# define D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION 4096
++#endif
++#ifndef D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION
++# define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048
++#endif
++#ifndef D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
++# define D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 256
++#endif
++#ifndef D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION
++# define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
++#endif
++#ifndef D3D11_REQ_TEXTURECUBE_DIMENSION
++# define D3D11_REQ_TEXTURECUBE_DIMENSION 16384
++#endif
++#ifndef D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION
++# define D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION 2048
++#endif
++#ifndef D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
++# define D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 2048
++#endif
++#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP
++# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32
++#endif
++#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP
++# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32
++#endif
++#ifndef D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT
++# define D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT 32
++#endif
++#ifndef D3D11_STANDARD_VERTEX_ELEMENT_COUNT
++# define D3D11_STANDARD_VERTEX_ELEMENT_COUNT 32
++#endif
++#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT
++# define D3D10_1_SO_BUFFER_SLOT_COUNT 4
++#endif
++#ifndef D3D11_SO_BUFFER_SLOT_COUNT
++# define D3D11_SO_BUFFER_SLOT_COUNT 4
++#endif
++#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
++# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14
++#endif
++#ifndef D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT
++# define D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT 16
++#endif
++#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE
++# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -8
++#endif
++#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE
++# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE 7
++#endif
++#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT
++# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096
++#endif
++#ifndef D3D11_PS_INPUT_REGISTER_COUNT
++# define D3D11_PS_INPUT_REGISTER_COUNT 32
++#endif
++#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT
++# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32
++#endif
++#if defined(ANGLE_MINGW32_COMPAT)
++static const IID WKPDID_D3DDebugObjectName = { 0x429b8c22, 0x9188, 0x4b0c, 0x87, 0x42, 0xac, 0xb0, 0xbf, 0x85, 0xc2, 0x00 };
++#endif
++
+ namespace rx
+ {
+
+@@ -232,7 +314,9 @@ GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return 3;
+@@ -298,7 +382,9 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return true;
+@@ -316,7 +402,9 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -336,7 +424,9 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return true;
+@@ -356,7 +446,9 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
+
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+@@ -374,7 +466,9 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
+
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return true;
+@@ -397,7 +491,9 @@ static bool GetFramebufferMultisampleSupport(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return true;
+@@ -414,7 +510,9 @@ static bool GetFramebufferBlitSupport(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return true;
+@@ -437,7 +535,9 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
+
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+@@ -453,7 +553,9 @@ static bool GetShaderTextureLODSupport(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return true;
+@@ -472,7 +574,9 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel
+
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -490,7 +594,9 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -508,7 +614,9 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -526,7 +634,9 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -544,7 +654,9 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -562,7 +674,9 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -586,7 +700,9 @@ static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
+
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
+@@ -608,7 +724,9 @@ static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
+
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
+@@ -625,7 +743,9 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ 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;
+@@ -645,7 +765,9 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+ // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -670,7 +792,9 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -698,7 +822,9 @@ static size_t GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL 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.
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return 2;
+@@ -720,7 +846,9 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
+
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ 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);
+@@ -739,7 +867,9 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -761,7 +891,9 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+ // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -786,7 +918,9 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -805,7 +939,9 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -824,7 +960,9 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -843,7 +981,9 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -862,7 +1002,9 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ 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;
+@@ -885,7 +1027,9 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
+
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -904,7 +1048,9 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ 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;
+@@ -922,7 +1068,9 @@ static size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL feat
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0:
+
+ case D3D_FEATURE_LEVEL_10_1:
+@@ -940,7 +1088,9 @@ static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL feature
+ {
+ switch (featureLevel)
+ {
++#if defined(ANGLE_ENABLE_D3D11_1)
+ case D3D_FEATURE_LEVEL_11_1:
++#endif
+ case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponents(featureLevel) /
+ GetMaximumStreamOutputBuffers(featureLevel);
+
+@@ -1054,6 +1204,7 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::
+
+ // Setting a large alignment forces uniform buffers to bind with zero offset
+ caps->uniformBufferOffsetAlignment = static_cast<GLuint>(std::numeric_limits<GLint>::max());
++#if defined(ANGLE_ENABLE_D3D11_1)
+ ID3D11DeviceContext1 *deviceContext1 = d3d11::DynamicCastComObject<ID3D11DeviceContext1>(deviceContext);
+
+ if (deviceContext1)
+@@ -1070,6 +1221,7 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::
+
+ SafeRelease(deviceContext1);
+ }
++#endif
+
+ caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks;
+ caps->maxCombinedVertexUniformComponents = (static_cast<GLint64>(caps->maxVertexUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) +
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+index c59808d..bf1c367 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+@@ -206,7 +206,7 @@ egl::Error Renderer9::initialize()
+ {
+ TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface");
+ ASSERT(mD3d9Ex);
+- mD3d9Ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void**>(&mD3d9));
++ mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
+ ASSERT(mD3d9);
+ }
+ else
+@@ -314,7 +314,7 @@ egl::Error Renderer9::initialize()
+ if (mD3d9Ex)
+ {
+ TRACE_EVENT0("gpu", "mDevice_QueryInterface");
+- result = mDevice->QueryInterface(__uuidof(IDirect3DDevice9Ex), (void**)&mDeviceEx);
++ result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**)&mDeviceEx);
+ ASSERT(SUCCEEDED(result));
+ }
+
+--
+2.1.4
+
diff --git a/src/angle/patches/0003-ANGLE-Fix-compilation-on-MSVC2010-2012.patch b/src/angle/patches/0003-ANGLE-Fix-compilation-on-MSVC2010-2012.patch
new file mode 100644
index 0000000000..62300e1e9b
--- /dev/null
+++ b/src/angle/patches/0003-ANGLE-Fix-compilation-on-MSVC2010-2012.patch
@@ -0,0 +1,363 @@
+From 11304df7f66d0d8bc5dfdc960b86b5cac0f18313 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@intopalo.com>
+Date: Wed, 8 Apr 2015 17:09:47 +0300
+Subject: [PATCH 3/5] ANGLE: Fix compilation on MSVC2010/2012
+
+Allow the D3D11 renderer to build with the June 2010 DirectX SDK.
+This mainly addresses C++11 language incompatibilities, such as replacing
+range-based for loops with iterators.
+
+Change-Id: I2343acedab16845d6a0d4a53cf3145f583efc4a7
+---
+ src/3rdparty/angle/src/common/angleutils.h | 2 ++
+ src/3rdparty/angle/src/common/platform.h | 9 +++++++
+ .../angle/src/compiler/translator/OutputHLSL.cpp | 31 +++++++++++++---------
+ src/3rdparty/angle/src/libANGLE/Context.cpp | 4 +--
+ src/3rdparty/angle/src/libANGLE/Error.h | 1 +
+ src/3rdparty/angle/src/libANGLE/Framebuffer.cpp | 23 ++++++++--------
+ src/3rdparty/angle/src/libANGLE/State.cpp | 3 ++-
+ src/3rdparty/angle/src/libANGLE/Texture.cpp | 2 +-
+ .../angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp | 6 +++--
+ .../src/libANGLE/renderer/d3d/RendererD3D.cpp | 4 +--
+ .../libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp | 3 ++-
+ 11 files changed, 55 insertions(+), 33 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/common/angleutils.h b/src/3rdparty/angle/src/common/angleutils.h
+index f3d2019..4cf84a3 100644
+--- a/src/3rdparty/angle/src/common/angleutils.h
++++ b/src/3rdparty/angle/src/common/angleutils.h
+@@ -25,12 +25,14 @@ namespace angle
+
+ class NonCopyable
+ {
++#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
+ public:
+ NonCopyable() = default;
+ ~NonCopyable() = default;
+ protected:
+ NonCopyable(const NonCopyable&) = delete;
+ void operator=(const NonCopyable&) = delete;
++#endif
+ };
+
+ }
+diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
+index be4cb94..3a2aa91 100644
+--- a/src/3rdparty/angle/src/common/platform.h
++++ b/src/3rdparty/angle/src/common/platform.h
+@@ -53,7 +53,9 @@
+
+ # if defined(ANGLE_ENABLE_D3D9)
+ # include <d3d9.h>
++# if !defined(ANGLE_TRANSLATOR_IMPLEMENTATION)
+ # include <d3dcompiler.h>
++# endif
+ # endif
+
+ # if defined(ANGLE_ENABLE_D3D11)
+@@ -70,7 +72,9 @@
+ # include <d3d11_1.h>
+ # include <dxgi1_2.h>
+ # endif
++# if !defined(ANGLE_TRANSLATOR_IMPLEMENTATION)
+ # include <d3dcompiler.h>
++# endif
+ # endif
+
+ # if defined(ANGLE_ENABLE_WINDOWS_STORE)
+@@ -83,6 +87,11 @@
+ # endif
+ # endif
+
++# if defined(_MSC_VER) && (_MSC_VER <= 1600)
++# define final
++# define override
++# endif
++
+ # undef near
+ # undef far
+ #endif
+diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
+index c3240f5..94225b8 100644
+--- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
++++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
+@@ -158,13 +158,13 @@ OutputHLSL::~OutputHLSL()
+ SafeDelete(mUnfoldShortCircuit);
+ SafeDelete(mStructureHLSL);
+ SafeDelete(mUniformHLSL);
+- for (auto &eqFunction : mStructEqualityFunctions)
++ for (auto it = mStructEqualityFunctions.begin(); it != mStructEqualityFunctions.end(); ++it)
+ {
+- SafeDelete(eqFunction);
++ SafeDelete(*it);
+ }
+- for (auto &eqFunction : mArrayEqualityFunctions)
++ for (auto it = mArrayEqualityFunctions.begin(); it != mArrayEqualityFunctions.end(); ++it)
+ {
+- SafeDelete(eqFunction);
++ SafeDelete(*it);
+ }
+ }
+
+@@ -340,17 +340,17 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator)
+ if (!mEqualityFunctions.empty())
+ {
+ out << "\n// Equality functions\n\n";
+- for (const auto &eqFunction : mEqualityFunctions)
++ for (auto it = mEqualityFunctions.cbegin(); it != mEqualityFunctions.cend(); ++it)
+ {
+- out << eqFunction->functionDefinition << "\n";
++ out << (*it)->functionDefinition << "\n";
+ }
+ }
+ if (!mArrayAssignmentFunctions.empty())
+ {
+ out << "\n// Assignment functions\n\n";
+- for (const auto &assignmentFunction : mArrayAssignmentFunctions)
++ for (auto it = mArrayAssignmentFunctions.cbegin(); it != mArrayAssignmentFunctions.cend(); ++it)
+ {
+- out << assignmentFunction.functionDefinition << "\n";
++ out << it->functionDefinition << "\n";
+ }
+ }
+
+@@ -1858,8 +1858,9 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
+
+ if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
+ {
+- for (const auto &seqElement : *sequence)
++ for (auto it = sequence->cbegin(); it != sequence->cend(); ++it)
+ {
++ const auto &seqElement = *it;
+ if (isSingleStatement(seqElement))
+ {
+ mUnfoldShortCircuit->traverse(seqElement);
+@@ -2941,8 +2942,9 @@ void OutputHLSL::writeDeferredGlobalInitializers(TInfoSinkBase &out)
+ << "void initializeDeferredGlobals()\n"
+ << "{\n";
+
+- for (const auto &deferredGlobal : mDeferredGlobalInitializers)
++ for (auto it = mDeferredGlobalInitializers.cbegin(); it != mDeferredGlobalInitializers.cend(); ++it)
+ {
++ const auto &deferredGlobal = *it;
+ TIntermSymbol *symbol = deferredGlobal.first;
+ TIntermTyped *expression = deferredGlobal.second;
+ ASSERT(symbol);
+@@ -2967,8 +2969,9 @@ TString OutputHLSL::addStructEqualityFunction(const TStructure &structure)
+ {
+ const TFieldList &fields = structure.fields();
+
+- for (const auto &eqFunction : mStructEqualityFunctions)
++ for (auto it = mStructEqualityFunctions.cbegin(); it != mStructEqualityFunctions.cend(); ++it)
+ {
++ auto *eqFunction = *it;
+ if (eqFunction->structure == &structure)
+ {
+ return eqFunction->functionName;
+@@ -3021,8 +3024,9 @@ TString OutputHLSL::addStructEqualityFunction(const TStructure &structure)
+
+ TString OutputHLSL::addArrayEqualityFunction(const TType& type)
+ {
+- for (const auto &eqFunction : mArrayEqualityFunctions)
++ for (auto it = mArrayEqualityFunctions.cbegin(); it != mArrayEqualityFunctions.cend(); ++it)
+ {
++ const auto &eqFunction = *it;
+ if (eqFunction->type == type)
+ {
+ return eqFunction->functionName;
+@@ -3072,8 +3076,9 @@ TString OutputHLSL::addArrayEqualityFunction(const TType& type)
+
+ TString OutputHLSL::addArrayAssignmentFunction(const TType& type)
+ {
+- for (const auto &assignFunction : mArrayAssignmentFunctions)
++ for (auto it = mArrayAssignmentFunctions.cbegin(); it != mArrayAssignmentFunctions.cend(); ++it)
+ {
++ const auto &assignFunction = *it;
+ if (assignFunction.type == type)
+ {
+ return assignFunction.functionName;
+diff --git a/src/3rdparty/angle/src/libANGLE/Context.cpp b/src/3rdparty/angle/src/libANGLE/Context.cpp
+index 5ea039f..1da5fda 100644
+--- a/src/3rdparty/angle/src/libANGLE/Context.cpp
++++ b/src/3rdparty/angle/src/libANGLE/Context.cpp
+@@ -158,9 +158,9 @@ Context::~Context()
+ deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
+ }
+
+- for (auto &zeroTexture : mZeroTextures)
++ for (auto it = mZeroTextures.begin(); it != mZeroTextures.end(); ++it)
+ {
+- zeroTexture.second.set(NULL);
++ it->second.set(NULL);
+ }
+ mZeroTextures.clear();
+
+diff --git a/src/3rdparty/angle/src/libANGLE/Error.h b/src/3rdparty/angle/src/libANGLE/Error.h
+index 5812943..896b777 100644
+--- a/src/3rdparty/angle/src/libANGLE/Error.h
++++ b/src/3rdparty/angle/src/libANGLE/Error.h
+@@ -10,6 +10,7 @@
+ #define LIBANGLE_ERROR_H_
+
+ #include "angle_gl.h"
++#include "common/platform.h"
+ #include <EGL/egl.h>
+
+ #include <string>
+diff --git a/src/3rdparty/angle/src/libANGLE/Framebuffer.cpp b/src/3rdparty/angle/src/libANGLE/Framebuffer.cpp
+index 5fa7513..b1dd4a1 100644
+--- a/src/3rdparty/angle/src/libANGLE/Framebuffer.cpp
++++ b/src/3rdparty/angle/src/libANGLE/Framebuffer.cpp
+@@ -48,9 +48,9 @@ Framebuffer::Data::Data(const Caps &caps)
+
+ Framebuffer::Data::~Data()
+ {
+- for (auto &colorAttachment : mColorAttachments)
++ for (auto it = mColorAttachments.begin(); it != mColorAttachments.end(); ++it)
+ {
+- SafeDelete(colorAttachment);
++ SafeDelete(*it);
+ }
+ SafeDelete(mDepthAttachment);
+ SafeDelete(mStencilAttachment);
+@@ -66,11 +66,11 @@ FramebufferAttachment *Framebuffer::Data::getReadAttachment() const
+
+ FramebufferAttachment *Framebuffer::Data::getFirstColorAttachment() const
+ {
+- for (FramebufferAttachment *colorAttachment : mColorAttachments)
++ for (auto it = mColorAttachments.cbegin(); it != mColorAttachments.cend(); ++it)
+ {
+- if (colorAttachment != nullptr)
++ if (*it != nullptr)
+ {
+- return colorAttachment;
++ return *it;
+ }
+ }
+
+@@ -115,9 +115,9 @@ void Framebuffer::detachRenderbuffer(GLuint renderbufferId)
+
+ void Framebuffer::detachResourceById(GLenum resourceType, GLuint resourceId)
+ {
+- for (auto &colorAttachment : mData.mColorAttachments)
++ for (auto it = mData.mColorAttachments.begin(); it != mData.mColorAttachments.end(); ++it)
+ {
+- DeleteMatchingAttachment(colorAttachment, resourceType, resourceId);
++ DeleteMatchingAttachment(*it, resourceType, resourceId);
+ }
+
+ DeleteMatchingAttachment(mData.mDepthAttachment, resourceType, resourceId);
+@@ -278,8 +278,9 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const
+ int samples = -1;
+ bool missingAttachment = true;
+
+- for (const FramebufferAttachment *colorAttachment : mData.mColorAttachments)
++ for (auto it = mData.mColorAttachments.cbegin(); it != mData.mColorAttachments.cend(); ++it)
+ {
++ const auto &colorAttachment = *it;
+ if (colorAttachment != nullptr)
+ {
+ if (colorAttachment->getWidth() == 0 || colorAttachment->getHeight() == 0)
+@@ -533,11 +534,11 @@ int Framebuffer::getSamples(const gl::Data &data) const
+ {
+ // for a complete framebuffer, all attachments must have the same sample count
+ // in this case return the first nonzero sample size
+- for (const FramebufferAttachment *colorAttachment : mData.mColorAttachments)
++ for (auto it = mData.mColorAttachments.cbegin(); it != mData.mColorAttachments.cend(); ++it)
+ {
+- if (colorAttachment != nullptr)
++ if (*it != nullptr)
+ {
+- return colorAttachment->getSamples();
++ return (*it)->getSamples();
+ }
+ }
+ }
+diff --git a/src/3rdparty/angle/src/libANGLE/State.cpp b/src/3rdparty/angle/src/libANGLE/State.cpp
+index 15274c6..4c044d2 100644
+--- a/src/3rdparty/angle/src/libANGLE/State.cpp
++++ b/src/3rdparty/angle/src/libANGLE/State.cpp
+@@ -633,8 +633,9 @@ void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
+
+ void State::initializeZeroTextures(const TextureMap &zeroTextures)
+ {
+- for (const auto &zeroTexture : zeroTextures)
++ for (auto it = zeroTextures.cbegin(); it != zeroTextures.cend(); ++it)
+ {
++ const auto &zeroTexture = *it;
+ auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
+
+ for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
+diff --git a/src/3rdparty/angle/src/libANGLE/Texture.cpp b/src/3rdparty/angle/src/libANGLE/Texture.cpp
+index 2d68bec..cd4584f 100644
+--- a/src/3rdparty/angle/src/libANGLE/Texture.cpp
++++ b/src/3rdparty/angle/src/libANGLE/Texture.cpp
+@@ -316,7 +316,7 @@ void Texture::setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInt
+ }
+
+ Texture::ImageDesc::ImageDesc()
+- : ImageDesc(Extents(0, 0, 0), GL_NONE)
++ : size(0, 0, 0), internalFormat(GL_NONE)
+ {
+ }
+
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp
+index db5f445..add5d62 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp
+@@ -276,8 +276,9 @@ bool DisplayD3D::testDeviceLost()
+ egl::Error DisplayD3D::restoreLostDevice()
+ {
+ // Release surface resources to make the Reset() succeed
+- for (auto &surface : mSurfaceSet)
++ for (auto it = mSurfaceSet.cbegin(); it != mSurfaceSet.cend(); ++it)
+ {
++ const auto &surface = *it;
+ if (surface->getBoundTexture())
+ {
+ surface->releaseTexImage(EGL_BACK_BUFFER);
+@@ -292,8 +293,9 @@ egl::Error DisplayD3D::restoreLostDevice()
+ }
+
+ // Restore any surfaces that may have been lost
+- for (const auto &surface : mSurfaceSet)
++ for (auto it = mSurfaceSet.cbegin(); it != mSurfaceSet.cend(); ++it)
+ {
++ const auto &surface = *it;
+ SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+
+ egl::Error error = surfaceD3D->resetSwapChain();
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp
+index ff9600e..2ce0ce5 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp
+@@ -47,9 +47,9 @@ RendererD3D::~RendererD3D()
+ void RendererD3D::cleanup()
+ {
+ mScratchMemoryBuffer.resize(0);
+- for (auto &incompleteTexture : mIncompleteTextures)
++ for (auto it = mIncompleteTextures.begin(); it != mIncompleteTextures.end(); ++it)
+ {
+- incompleteTexture.second.set(NULL);
++ it->second.set(NULL);
+ }
+ mIncompleteTextures.clear();
+ }
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
+index ab2a902..da01f32 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
+@@ -64,8 +64,9 @@ static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *a
+
+ gl::Error Framebuffer11::invalidateSwizzles() const
+ {
+- for (gl::FramebufferAttachment *colorAttachment : mData.mColorAttachments)
++ for (auto it = mData.mColorAttachments.cbegin(); it != mData.mColorAttachments.cend(); ++it)
+ {
++ gl::FramebufferAttachment *colorAttachment = *it;
+ gl::Error error = InvalidateAttachmentSwizzles(colorAttachment);
+ if (error.isError())
+ {
+--
+2.1.4
+
diff --git a/src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch b/src/angle/patches/0004-ANGLE-Dynamically-load-D3D-compiler-from-a-list.patch
index 801db67682..ff93920317 100644
--- a/src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch
+++ b/src/angle/patches/0004-ANGLE-Dynamically-load-D3D-compiler-from-a-list.patch
@@ -1,8 +1,7 @@
-From 4a5960465d1632ab089320fcbba4af294d58fd9a Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@theqtcompany.com>
-Date: Fri, 7 Nov 2014 14:05:36 +0200
-Subject: [PATCH 08/16] ANGLE: Dynamically load D3D compiler from a list or the
- environment
+From bbb62a69dd2b49d7cc4214937077c22b6997ffac Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@intopalo.com>
+Date: Fri, 27 Mar 2015 17:27:38 +0200
+Subject: [PATCH 4/5] ANGLE: Dynamically load D3D compiler from a list
If the default compiler cannot be found, load it from a list of DLL names,
including a non-versioned proxy DLL provided by Qt. On Desktop Windows,
@@ -11,16 +10,16 @@ QT_D3DCOMPILER_DLL.
Change-Id: I0d7a8a8a36cc571836f8fa59ea14513b9b19c19b
---
- .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 27 ++++++++++++++++++++++
- 1 file changed, 27 insertions(+)
+ .../src/libANGLE/renderer/d3d/HLSLCompiler.cpp | 25 ++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-index bfeaf51..9d003b4 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-@@ -11,6 +11,10 @@
- #include "common/features.h"
- #include "common/utilities.h"
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
+index 9c72d6f..8961a36 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
+@@ -12,6 +12,10 @@
+
+ #include "third_party/trace_event/trace_event.h"
+#ifndef QT_D3DCOMPILER_DLL
+#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
@@ -29,7 +28,7 @@ index bfeaf51..9d003b4 100644
// Definitions local to the translation unit
namespace
{
-@@ -132,6 +136,29 @@ bool HLSLCompiler::initialize()
+@@ -143,6 +147,27 @@ bool HLSLCompiler::initialize()
}
#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
@@ -42,8 +41,6 @@ index bfeaf51..9d003b4 100644
+ defaultCompiler,
+ L"d3dcompiler_47.dll",
+ L"d3dcompiler_46.dll",
-+ L"d3dcompiler_45.dll",
-+ L"d3dcompiler_44.dll",
+ L"d3dcompiler_43.dll",
+ 0
+ };
@@ -60,5 +57,5 @@ index bfeaf51..9d003b4 100644
{
// Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
--
-1.9.4.msysgit.1
+2.1.4
diff --git a/src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch b/src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch
deleted file mode 100644
index 45a3f17cca..0000000000
--- a/src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From 3a39939b5eba9f788789961c4800ba62618f758c Mon Sep 17 00:00:00 2001
-From: Friedemann Kleint <Friedemann.Kleint@digia.com>
-Date: Tue, 11 Nov 2014 10:26:32 +0200
-Subject: [PATCH 04/16] Make it possible to link ANGLE statically for
- single-thread use.
-
-Fix exports and provide static instances of thread-local
-data depending on QT_OPENGL_ES_2_ANGLE_STATIC.
-
-Change-Id: Ifab25a820adf5953bb3b09036de53dbf7f1a7fd5
----
- src/3rdparty/angle/include/KHR/khrplatform.h | 2 +-
- src/3rdparty/angle/src/libEGL/main.cpp | 10 ++++++++++
- src/3rdparty/angle/src/libGLESv2/main.cpp | 10 ++++++++--
- 3 files changed, 19 insertions(+), 3 deletions(-)
-
-diff --git a/src/3rdparty/angle/include/KHR/khrplatform.h b/src/3rdparty/angle/include/KHR/khrplatform.h
-index c9e6f17..1ac2d3f 100644
---- a/src/3rdparty/angle/include/KHR/khrplatform.h
-+++ b/src/3rdparty/angle/include/KHR/khrplatform.h
-@@ -97,7 +97,7 @@
- *-------------------------------------------------------------------------
- * This precedes the return type of the function in the function prototype.
- */
--#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
-+#if defined(_WIN32) && !defined(__SCITECH_SNAP__) && !defined(QT_OPENGL_ES_2_ANGLE_STATIC)
- # define KHRONOS_APICALL __declspec(dllimport)
- #elif defined (__SYMBIAN32__)
- # define KHRONOS_APICALL IMPORT_C
-diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
-index d1489f2..e88cad7 100644
---- a/src/3rdparty/angle/src/libEGL/main.cpp
-+++ b/src/3rdparty/angle/src/libEGL/main.cpp
-@@ -49,6 +49,8 @@ void DeallocateCurrent()
-
- }
-
-+#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
-+
- extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
- {
- switch (reason)
-@@ -108,16 +110,24 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
- return TRUE;
- }
-
-+#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
-+
- namespace egl
- {
-
- Current *GetCurrentData()
- {
-+#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
- Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
-
- // ANGLE issue 488: when the dll is loaded after thread initialization,
- // thread local storage (current) might not exist yet.
- return (current ? current : AllocateCurrent());
-+#else
-+ // No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
-+ static Current current = { EGL_SUCCESS, EGL_OPENGL_ES_API, EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE };
-+ return &current;
-+#endif
- }
-
- void recordError(const Error &error)
-diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
-index 3ac00d5..00f63ae 100644
---- a/src/3rdparty/angle/src/libGLESv2/main.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
-@@ -74,7 +74,7 @@ void DeallocateCurrent()
-
- }
-
--#ifdef ANGLE_PLATFORM_WINDOWS
-+#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(QT_OPENGL_ES_2_ANGLE_STATIC)
- extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
- {
- switch (reason)
-@@ -117,18 +117,24 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
-
- return TRUE;
- }
--#endif
-+#endif // ANGLE_PLATFORM_WINDOWS && !QT_OPENGL_ES_2_ANGLE_STATIC
-
- namespace gl
- {
-
- Current *GetCurrentData()
- {
-+#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
- Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
-
- // ANGLE issue 488: when the dll is loaded after thread initialization,
- // thread local storage (current) might not exist yet.
- return (current ? current : AllocateCurrent());
-+#else
-+ // No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
-+ static Current current = { 0, 0 };
-+ return &current;
-+#endif
- }
-
- void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
---
-1.9.4.msysgit.1
-
diff --git a/src/angle/patches/0005-ANGLE-Add-support-for-querying-platform-device.patch b/src/angle/patches/0005-ANGLE-Add-support-for-querying-platform-device.patch
new file mode 100644
index 0000000000..8a5bffebe4
--- /dev/null
+++ b/src/angle/patches/0005-ANGLE-Add-support-for-querying-platform-device.patch
@@ -0,0 +1,84 @@
+From f6bfeecf2c7d14e9fd2b637e6ce9555489e3a256 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@intopalo.com>
+Date: Fri, 27 Mar 2015 17:58:41 +0200
+Subject: [PATCH 5/5] ANGLE: Add support for querying platform device
+
+The EGL_EXT_device_base extension allows for querying the platform
+device of the graphics hardware via eglQueryDisplayAttribEXT().
+As that extension is not supported by ANGLE, this patch adds similar
+functionality to the existing eglQuerySurfacePointerANGLE API. When
+EGL_DEVICE_EXT is passed as the queried attribute, the underlying
+D3D/DXGI device pointer is passed back to the caller via the value
+argument.
+
+The D3D device is needed for video support in QtMultimedia as well as
+the IDXGIDevice3::Trim() calls required by the Windows Store.
+
+Change-Id: Ibdf228d81d6604e56db9dd8597d7cd2983ebc428
+---
+ src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp | 7 +++++--
+ src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h | 1 +
+ src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 5 +++++
+ src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h | 2 ++
+ 4 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
+index a3c457d..4fde295 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
+@@ -385,8 +385,11 @@ EGLint SurfaceD3D::isPostSubBufferSupported() const
+
+ egl::Error SurfaceD3D::querySurfacePointerANGLE(EGLint attribute, void **value)
+ {
+- ASSERT(attribute == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE);
+- *value = mSwapChain->getShareHandle();
++ ASSERT(attribute == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || attribute == EGL_DEVICE_EXT);
++ if (attribute == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE)
++ *value = mSwapChain->getShareHandle();
++ else if (attribute == EGL_DEVICE_EXT)
++ *value = mSwapChain->getDevice();
+ return egl::Error(EGL_SUCCESS);
+ }
+
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h
+index 3bde92e..da36e52 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h
+@@ -41,6 +41,7 @@ class SwapChainD3D : angle::NonCopyable
+ virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0;
+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0;
+ virtual void recreate() = 0;
++ virtual void *getDevice() { return NULL; }
+
+ virtual RenderTargetD3D *getColorRenderTarget() = 0;
+ virtual RenderTargetD3D *getDepthStencilRenderTarget() = 0;
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+index bcb2505..298f3cc 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+@@ -703,4 +703,9 @@ void SwapChain11::recreate()
+ // possibly should use this method instead of reset
+ }
+
++void *rx::SwapChain11::getDevice()
++{
++ return mRenderer->getDevice();
++}
++
+ }
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
+index 4ea6778..48c808a 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
+@@ -43,6 +43,8 @@ class SwapChain11 : public SwapChainD3D
+ EGLint getWidth() const { return mWidth; }
+ EGLint getHeight() const { return mHeight; }
+
++ virtual void *getDevice();
++
+ static SwapChain11 *makeSwapChain11(SwapChainD3D *swapChain);
+
+ private:
+--
+2.1.4
+
diff --git a/src/angle/patches/0009-ANGLE-Support-WinRT.patch b/src/angle/patches/0009-ANGLE-Support-WinRT.patch
deleted file mode 100644
index a38fb4ea13..0000000000
--- a/src/angle/patches/0009-ANGLE-Support-WinRT.patch
+++ /dev/null
@@ -1,837 +0,0 @@
-From 4d150ba3814f824f1cadaedbdb83d0ac79d0e1a2 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@theqtcompany.com>
-Date: Fri, 14 Nov 2014 09:28:11 +0200
-Subject: [PATCH 09/16] ANGLE: Support WinRT
-
-Tweak ANGLE's existing support for WinRT to allow for changing the
-window size on Windows Phone.
-
-Change-Id: Ia312b5318b977838a2953f1f530487cbf24974bc
----
- src/3rdparty/angle/include/EGL/eglplatform.h | 5 +-
- src/3rdparty/angle/src/common/NativeWindow.h | 7 +-
- src/3rdparty/angle/src/common/platform.h | 4 +-
- .../angle/src/common/win32/NativeWindow.cpp | 2 +-
- .../src/common/winrt/CoreWindowNativeWindow.cpp | 87 +++++++++++++---------
- .../src/common/winrt/CoreWindowNativeWindow.h | 48 ++----------
- .../src/common/winrt/InspectableNativeWindow.cpp | 8 +-
- .../src/common/winrt/InspectableNativeWindow.h | 7 +-
- .../common/winrt/SwapChainPanelNativeWindow.cpp | 2 +-
- .../src/common/winrt/SwapChainPanelNativeWindow.h | 2 +-
- src/3rdparty/angle/src/libEGL/Display.h | 1 +
- src/3rdparty/angle/src/libEGL/Surface.cpp | 45 ++++++++---
- src/3rdparty/angle/src/libEGL/Surface.h | 4 +
- src/3rdparty/angle/src/libEGL/libEGL.cpp | 20 +++++
- .../src/libGLESv2/renderer/d3d/d3d11/Renderer11.h | 2 +-
- .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 74 +++++++++++-------
- .../src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h | 2 +
- 17 files changed, 189 insertions(+), 131 deletions(-)
-
-diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h
-index 3793e57..2eb3674 100644
---- a/src/3rdparty/angle/include/EGL/eglplatform.h
-+++ b/src/3rdparty/angle/include/EGL/eglplatform.h
-@@ -73,13 +73,14 @@
- #endif
- #include <windows.h>
-
--typedef HDC EGLNativeDisplayType;
- typedef HBITMAP EGLNativePixmapType;
-
--#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP /* Windows Store */
-+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) /* Windows Store */
- #include <inspectable.h>
-+typedef IInspectable* EGLNativeDisplayType;
- typedef IInspectable* EGLNativeWindowType;
- #else
-+typedef HDC EGLNativeDisplayType;
- typedef HWND EGLNativeWindowType;
- #endif
-
-diff --git a/src/3rdparty/angle/src/common/NativeWindow.h b/src/3rdparty/angle/src/common/NativeWindow.h
-index dc5fc8f..9e93aea 100644
---- a/src/3rdparty/angle/src/common/NativeWindow.h
-+++ b/src/3rdparty/angle/src/common/NativeWindow.h
-@@ -44,10 +44,11 @@ typedef IDXGIFactory DXGIFactory;
-
- namespace rx
- {
-+
- class NativeWindow
- {
-- public:
-- explicit NativeWindow(EGLNativeWindowType window);
-+public:
-+ explicit NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display);
-
- bool initialize();
- bool getClientRect(LPRECT rect);
-@@ -58,9 +59,11 @@ class NativeWindow
- DXGISwapChain** swapChain);
-
- inline EGLNativeWindowType getNativeWindow() const { return mWindow; }
-+ inline EGLNativeDisplayType getNativeDisplay() const { return mDisplay; }
-
- private:
- EGLNativeWindowType mWindow;
-+ EGLNativeDisplayType mDisplay;
-
- #if defined(ANGLE_ENABLE_WINDOWS_STORE)
- std::shared_ptr<InspectableNativeWindow> mImpl;
-diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
-index cd12dba..0065ec7 100644
---- a/src/3rdparty/angle/src/common/platform.h
-+++ b/src/3rdparty/angle/src/common/platform.h
-@@ -34,7 +34,7 @@
- #endif
-
- #ifdef ANGLE_PLATFORM_WINDOWS
--# if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP
-+# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
- # define ANGLE_ENABLE_WINDOWS_STORE 1
- # endif
- # ifndef STRICT
-@@ -67,7 +67,9 @@
- # if defined(ANGLE_ENABLE_WINDOWS_STORE)
- # include <dxgi1_3.h>
- # if defined(_DEBUG)
-+# if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
- # include <DXProgrammableCapture.h>
-+# endif
- # include <dxgidebug.h>
- # endif
- # endif
-diff --git a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
-index aa2bfa4..2440747 100644
---- a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
-+++ b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
-@@ -16,7 +16,7 @@ bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
- return (IsWindow(window) == TRUE);
- }
-
--NativeWindow::NativeWindow(EGLNativeWindowType window) : mWindow(window)
-+NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display) : mWindow(window), mDisplay(display)
- {
- }
-
-diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
-index 0e63fa5..9b65c15 100644
---- a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
-+++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
-@@ -6,21 +6,25 @@
-
- // CoreWindowNativeWindow.cpp: NativeWindow for managing ICoreWindow native window types.
-
--#include <windows.graphics.display.h>
-+#include <algorithm>
- #include "common/winrt/CoreWindowNativeWindow.h"
- using namespace ABI::Windows::Foundation::Collections;
-
- namespace rx
- {
-+
-+typedef ITypedEventHandler<ABI::Windows::UI::Core::CoreWindow *, ABI::Windows::UI::Core::WindowSizeChangedEventArgs *> SizeChangedHandler;
-+
- CoreWindowNativeWindow::~CoreWindowNativeWindow()
- {
- unregisterForSizeChangeEvents();
- }
-
--bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet)
-+bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
- {
- ComPtr<IPropertySet> props = propertySet;
- ComPtr<IInspectable> win = window;
-+ ComPtr<IInspectable> displayInformation = display;
- SIZE swapChainSize = {};
- bool swapChainSizeSpecified = false;
- HRESULT result = S_OK;
-@@ -47,6 +51,29 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet
-
- if (SUCCEEDED(result))
- {
-+ result = displayInformation.As(&mDisplayInformation);
-+ }
-+
-+ if (SUCCEEDED(result))
-+ {
-+#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
-+ ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation2> displayInformation2;
-+ result = mDisplayInformation.As(&displayInformation2);
-+ ASSERT(SUCCEEDED(result));
-+
-+ result = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor);
-+ ASSERT(SUCCEEDED(result));
-+#else
-+ ABI::Windows::Graphics::Display::ResolutionScale resolutionScale;
-+ result = mDisplayInformation->get_ResolutionScale(&resolutionScale);
-+ ASSERT(SUCCEEDED(result));
-+
-+ mScaleFactor = DOUBLE(resolutionScale) / 100.0;
-+#endif
-+ }
-+
-+ if (SUCCEEDED(result))
-+ {
- // If a swapchain size is specfied, then the automatic resize
- // behaviors implemented by the host should be disabled. The swapchain
- // will be still be scaled when being rendered to fit the bounds
-@@ -60,7 +87,14 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet
- }
- else
- {
-- result = GetCoreWindowSizeInPixels(mCoreWindow, &mClientRect);
-+ ABI::Windows::Foundation::Rect rect;
-+ HRESULT result = mCoreWindow->get_Bounds(&rect);
-+ if (SUCCEEDED(result))
-+ {
-+ LONG width = std::floor(rect.Width * mScaleFactor + 0.5);
-+ LONG height = std::floor(rect.Height * mScaleFactor + 0.5);
-+ mClientRect = { 0, 0, width, height };
-+ }
- }
- }
-
-@@ -76,12 +110,8 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet
-
- bool CoreWindowNativeWindow::registerForSizeChangeEvents()
- {
-- ComPtr<IWindowSizeChangedEventHandler> sizeChangedHandler;
-- HRESULT result = Microsoft::WRL::MakeAndInitialize<CoreWindowSizeChangedHandler>(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this());
-- if (SUCCEEDED(result))
-- {
-- result = mCoreWindow->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken);
-- }
-+ HRESULT result = mCoreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &CoreWindowNativeWindow::onSizeChanged).Get(),
-+ &mSizeChangedEventToken);
-
- if (SUCCEEDED(result))
- {
-@@ -126,7 +156,7 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor
- if (SUCCEEDED(result))
- {
-
--#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
-+#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // This block is disabled for Qt applications, as the resize events are expected
- // Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On
- // other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed
- // (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations.
-@@ -152,36 +182,19 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor
- return result;
- }
-
--HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize)
-+// Basically, this shouldn't be used on Phone
-+HRESULT CoreWindowNativeWindow::onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *e)
- {
-- ABI::Windows::Foundation::Rect bounds;
-- HRESULT result = coreWindow->get_Bounds(&bounds);
-- if (SUCCEEDED(result))
-+ ABI::Windows::Foundation::Size size;
-+ if (SUCCEEDED(e->get_Size(&size)))
- {
-- *windowSize = { 0, 0, ConvertDipsToPixels(bounds.Width), ConvertDipsToPixels(bounds.Height) };
-+ SIZE windowSizeInPixels = {
-+ std::floor(size.Width * mScaleFactor + 0.5),
-+ std::floor(size.Height * mScaleFactor + 0.5)
-+ };
-+ setNewClientSize(windowSizeInPixels);
- }
-
-- return result;
--}
--
--static float GetLogicalDpi()
--{
-- ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
-- float dpi = 96.0f;
--
-- if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
-- {
-- if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
-- {
-- return dpi;
-- }
-- }
-- return dpi;
--}
--
--long ConvertDipsToPixels(float dips)
--{
-- static const float dipsPerInch = 96.0f;
-- return lround((dips * GetLogicalDpi() / dipsPerInch));
-+ return S_OK;
- }
- }
-diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
-index 0c6222d..1c55124 100644
---- a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
-+++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
-@@ -11,67 +11,29 @@
-
- #include "common/winrt/InspectableNativeWindow.h"
- #include <memory>
--
--typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t IWindowSizeChangedEventHandler;
-+#include <windows.graphics.display.h>
-
- namespace rx
- {
--long ConvertDipsToPixels(float dips);
-
- class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
- {
- public:
- ~CoreWindowNativeWindow();
-
-- bool initialize(EGLNativeWindowType window, IPropertySet *propertySet);
-+ bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
- bool registerForSizeChangeEvents();
- void unregisterForSizeChangeEvents();
- HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
-
- private:
-+ HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
-+
- ComPtr<ABI::Windows::UI::Core::ICoreWindow> mCoreWindow;
-+ ComPtr<ABI::Windows::Graphics::Display::IDisplayInformation> mDisplayInformation;
- ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
- };
-
--[uuid(7F924F66-EBAE-40E5-A10B-B8F35E245190)]
--class CoreWindowSizeChangedHandler :
-- public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWindowSizeChangedEventHandler>
--{
-- public:
-- CoreWindowSizeChangedHandler() { }
-- HRESULT RuntimeClassInitialize(std::shared_ptr<InspectableNativeWindow> host)
-- {
-- if (!host)
-- {
-- return E_INVALIDARG;
-- }
--
-- mHost = host;
-- return S_OK;
-- }
--
-- // IWindowSizeChangedEventHandler
-- IFACEMETHOD(Invoke)(ABI::Windows::UI::Core::ICoreWindow *sender, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *sizeChangedEventArgs)
-- {
-- std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
-- if (host)
-- {
-- ABI::Windows::Foundation::Size windowSize;
-- if (SUCCEEDED(sizeChangedEventArgs->get_Size(&windowSize)))
-- {
-- SIZE windowSizeInPixels = { ConvertDipsToPixels(windowSize.Width), ConvertDipsToPixels(windowSize.Height) };
-- host->setNewClientSize(windowSizeInPixels);
-- }
-- }
--
-- return S_OK;
-- }
--
-- private:
-- std::weak_ptr<InspectableNativeWindow> mHost;
--};
--
--HRESULT GetCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize);
- }
-
- #endif // COMMON_WINRT_COREWINDOWNATIVEWINDOW_H_
-diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
-index c062a48..0589f6d 100644
---- a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
-+++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
-@@ -11,9 +11,9 @@
-
- namespace rx
- {
--NativeWindow::NativeWindow(EGLNativeWindowType window)
-+NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display)
-+ : mWindow(window), mDisplay(display)
- {
-- mWindow = window;
- }
-
- bool NativeWindow::initialize()
-@@ -40,7 +40,7 @@ bool NativeWindow::initialize()
- mImpl = std::make_shared<CoreWindowNativeWindow>();
- if (mImpl)
- {
-- return mImpl->initialize(mWindow, propertySet.Get());
-+ return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
- }
- }
- else if (IsSwapChainPanel(mWindow, &swapChainPanel))
-@@ -48,7 +48,7 @@ bool NativeWindow::initialize()
- mImpl = std::make_shared<SwapChainPanelNativeWindow>();
- if (mImpl)
- {
-- return mImpl->initialize(mWindow, propertySet.Get());
-+ return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
- }
- }
- else
-diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
-index c625348..402941a 100644
---- a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
-+++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
-@@ -32,13 +32,14 @@ class InspectableNativeWindow
- mRequiresSwapChainScaling(false),
- mClientRectChanged(false),
- mClientRect({0,0,0,0}),
-- mNewClientRect({0,0,0,0})
-+ mNewClientRect({0,0,0,0}),
-+ mScaleFactor(1.0)
- {
- mSizeChangedEventToken.value = 0;
- }
- virtual ~InspectableNativeWindow(){}
-
-- virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0;
-+ virtual bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet) = 0;
- virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
- virtual bool registerForSizeChangeEvents() = 0;
- virtual void unregisterForSizeChangeEvents() = 0;
-@@ -49,6 +50,7 @@ class InspectableNativeWindow
- if (mClientRectChanged && mSupportsSwapChainResize)
- {
- mClientRect = mNewClientRect;
-+ mClientRectChanged = false;
- }
-
- *rect = mClientRect;
-@@ -76,6 +78,7 @@ protected:
- RECT mClientRect;
- RECT mNewClientRect;
- bool mClientRectChanged;
-+ DOUBLE mScaleFactor;
-
- EventRegistrationToken mSizeChangedEventToken;
- };
-diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
-index 4e4fb6d..268dfbd 100644
---- a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
-+++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
-@@ -18,7 +18,7 @@ SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow()
- unregisterForSizeChangeEvents();
- }
-
--bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet)
-+bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
- {
- ComPtr<IPropertySet> props = propertySet;
- ComPtr<IInspectable> win = window;
-diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
-index e88f554..5bbf274 100644
---- a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
-+++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
-@@ -18,7 +18,7 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e
- public:
- ~SwapChainPanelNativeWindow();
-
-- bool initialize(EGLNativeWindowType window, IPropertySet *propertySet);
-+ bool initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet);
- bool registerForSizeChangeEvents();
- void unregisterForSizeChangeEvents();
- HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
-diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
-index 378323a..b3ffcc8 100644
---- a/src/3rdparty/angle/src/libEGL/Display.h
-+++ b/src/3rdparty/angle/src/libEGL/Display.h
-@@ -67,6 +67,7 @@ class Display
-
- const char *getExtensionString() const;
- const char *getVendorString() const;
-+ EGLNativeDisplayType getDisplayId() const { return mDisplayId; }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Display);
-diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
-index 3414656..b664a85 100644
---- a/src/3rdparty/angle/src/libEGL/Surface.cpp
-+++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
-@@ -31,7 +31,7 @@ namespace egl
- {
-
- Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported)
-- : mDisplay(display), mConfig(config), mNativeWindow(window), mPostSubBufferSupported(postSubBufferSupported)
-+ : mDisplay(display), mConfig(config), mNativeWindow(window, display->getDisplayId()), mPostSubBufferSupported(postSubBufferSupported)
- {
- //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
- mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
-@@ -47,6 +47,8 @@ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType win
- mSwapInterval = -1;
- mWidth = width;
- mHeight = height;
-+ mFixedWidth = mWidth;
-+ mFixedHeight = mHeight;
- setSwapInterval(1);
- mFixedSize = fixedSize;
-
-@@ -54,7 +56,7 @@ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType win
- }
-
- Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
-- : mDisplay(display), mNativeWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
-+ : mDisplay(display), mNativeWindow(NULL, NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE)
- {
- //TODO(jmadill): MANGLE refactor. (note, can't call makeRendererD3D because of dll export issues)
- mRenderer = static_cast<rx::RendererD3D*>(mDisplay->getRenderer());
-@@ -71,6 +73,8 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL
- setSwapInterval(1);
- // This constructor is for offscreen surfaces, which are always fixed-size.
- mFixedSize = EGL_TRUE;
-+ mFixedWidth = mWidth;
-+ mFixedHeight = mHeight;
- }
-
- Surface::~Surface()
-@@ -157,10 +161,13 @@ Error Surface::resetSwapChain()
-
- Error Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
- {
-- ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
- ASSERT(mSwapChain);
-
-- EGLint status = mSwapChain->resize(std::max(1, backbufferWidth), std::max(1, backbufferHeight));
-+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
-+ backbufferWidth = std::max(1, backbufferWidth);
-+ backbufferHeight = std::max(1, backbufferHeight);
-+#endif
-+ EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
-
- if (status == EGL_CONTEXT_LOST)
- {
-@@ -209,14 +216,14 @@ Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
- return Error(EGL_SUCCESS);
- }
-
-- if (x + width > mWidth)
-+ if (x + width > abs(mWidth))
- {
-- width = mWidth - x;
-+ width = abs(mWidth) - x;
- }
-
-- if (y + height > mHeight)
-+ if (y + height > abs(mHeight))
- {
-- height = mHeight - y;
-+ height = abs(mHeight) - y;
- }
-
- if (width == 0 || height == 0)
-@@ -224,6 +231,9 @@ Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
- return Error(EGL_SUCCESS);
- }
-
-+ ASSERT(width > 0);
-+ ASSERT(height > 0);
-+
- EGLint status = mSwapChain->swapRect(x, y, width, height);
-
- if (status == EGL_CONTEXT_LOST)
-@@ -352,6 +362,13 @@ bool Surface::checkForOutOfDateSwapChain()
- sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
- }
-
-+ if (mFixedSize && (mWidth != mFixedWidth || mHeight != mFixedHeight))
-+ {
-+ clientWidth = mFixedWidth;
-+ clientHeight = mFixedHeight;
-+ sizeDirty = true;
-+ }
-+
- bool wasDirty = (mSwapIntervalDirty || sizeDirty);
-
- if (mSwapIntervalDirty)
-@@ -378,7 +395,7 @@ bool Surface::checkForOutOfDateSwapChain()
-
- Error Surface::swap()
- {
-- return swapRect(0, 0, mWidth, mHeight);
-+ return swapRect(0, 0, abs(mWidth), abs(mHeight));
- }
-
- Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
-@@ -471,6 +488,16 @@ EGLint Surface::isFixedSize() const
- return mFixedSize;
- }
-
-+void Surface::setFixedWidth(EGLint width)
-+{
-+ mFixedWidth = width;
-+}
-+
-+void Surface::setFixedHeight(EGLint height)
-+{
-+ mFixedHeight = height;
-+}
-+
- EGLenum Surface::getFormat() const
- {
- return mConfig->mRenderTargetFormat;
-diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h
-index 662fe21..46382d0 100644
---- a/src/3rdparty/angle/src/libEGL/Surface.h
-+++ b/src/3rdparty/angle/src/libEGL/Surface.h
-@@ -70,6 +70,8 @@ class Surface
- virtual gl::Texture2D *getBoundTexture() const;
-
- EGLint isFixedSize() const;
-+ void setFixedWidth(EGLint width);
-+ void setFixedHeight(EGLint height);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Surface);
-@@ -91,6 +93,8 @@ class Surface
- const egl::Config *mConfig; // EGL config surface was created with
- EGLint mHeight; // Height of surface
- EGLint mWidth; // Width of surface
-+ EGLint mFixedHeight; // Pending height of the surface
-+ EGLint mFixedWidth; // Pending width of the surface
- // EGLint horizontalResolution; // Horizontal dot pitch
- // EGLint verticalResolution; // Vertical dot pitch
- // EGLBoolean largestPBuffer; // If true, create largest pbuffer possible
-diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
-index 6110698..dc20d85 100644
---- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
-+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
-@@ -706,6 +706,26 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint
- return EGL_FALSE;
- }
-
-+ switch (attribute)
-+ {
-+ case EGL_WIDTH:
-+ if (!eglSurface->isFixedSize() || !value) {
-+ recordError(egl::Error(EGL_BAD_PARAMETER));
-+ return EGL_FALSE;
-+ }
-+ eglSurface->setFixedWidth(value);
-+ return EGL_TRUE;
-+ case EGL_HEIGHT:
-+ if (!eglSurface->isFixedSize() || !value) {
-+ recordError(egl::Error(EGL_BAD_PARAMETER));
-+ return EGL_FALSE;
-+ }
-+ eglSurface->setFixedHeight(value);
-+ return EGL_TRUE;
-+ default:
-+ break;
-+ }
-+
- UNIMPLEMENTED(); // FIXME
-
- recordError(egl::Error(EGL_SUCCESS));
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
-index 1655f1d..c789cae 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
-@@ -231,7 +231,7 @@ class Renderer11 : public RendererD3D
-
- HMODULE mD3d11Module;
- HMODULE mDxgiModule;
-- HDC mDc;
-+ EGLNativeDisplayType mDc;
- std::vector<D3D_FEATURE_LEVEL> mAvailableFeatureLevels;
- D3D_DRIVER_TYPE mDriverType;
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-index 834b7bd..52c8a81 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp
-@@ -42,6 +42,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE
- mPassThroughPS = NULL;
- mWidth = -1;
- mHeight = -1;
-+ mRotateL = false;
-+ mRotateR = false;
- mSwapInterval = 0;
- mAppCreatedShareHandle = mShareHandle != NULL;
- mPassThroughResourcesInit = false;
-@@ -92,10 +94,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
- ASSERT(device != NULL);
-
- // D3D11 does not allow zero size textures
-- ASSERT(backbufferWidth >= 1);
-- ASSERT(backbufferHeight >= 1);
-+ ASSERT(backbufferWidth != 0);
-+ ASSERT(backbufferHeight != 0);
-
- // Preserve the render target content
-+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture;
- if (previousOffscreenTexture)
- {
-@@ -103,6 +106,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
- }
- const int previousWidth = mWidth;
- const int previousHeight = mHeight;
-+#endif
-
- releaseOffscreenTexture();
-
-@@ -136,8 +140,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
- D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
- mOffscreenTexture->GetDesc(&offscreenTextureDesc);
-
-- if (offscreenTextureDesc.Width != (UINT)backbufferWidth ||
-- offscreenTextureDesc.Height != (UINT)backbufferHeight ||
-+ if (offscreenTextureDesc.Width != UINT(abs(backbufferWidth)) ||
-+ offscreenTextureDesc.Height != UINT(abs(backbufferHeight)) ||
- offscreenTextureDesc.Format != backbufferFormatInfo.texFormat ||
- offscreenTextureDesc.MipLevels != 1 ||
- offscreenTextureDesc.ArraySize != 1)
-@@ -152,8 +156,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
- const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport();
-
- D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
-- offscreenTextureDesc.Width = backbufferWidth;
-- offscreenTextureDesc.Height = backbufferHeight;
-+ offscreenTextureDesc.Width = abs(backbufferWidth);
-+ offscreenTextureDesc.Height = abs(backbufferHeight);
- offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
- offscreenTextureDesc.MipLevels = 1;
- offscreenTextureDesc.ArraySize = 1;
-@@ -233,8 +237,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
- if (mDepthBufferFormat != GL_NONE)
- {
- D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
-- depthStencilTextureDesc.Width = backbufferWidth;
-- depthStencilTextureDesc.Height = backbufferHeight;
-+ depthStencilTextureDesc.Width = abs(backbufferWidth);
-+ depthStencilTextureDesc.Height = abs(backbufferHeight);
- depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
- depthStencilTextureDesc.MipLevels = 1;
- depthStencilTextureDesc.ArraySize = 1;
-@@ -286,6 +290,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
- mWidth = backbufferWidth;
- mHeight = backbufferHeight;
-
-+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
- if (previousOffscreenTexture != NULL)
- {
- D3D11_BOX sourceBox = {0};
-@@ -307,6 +312,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei
- swapRect(0, 0, mWidth, mHeight);
- }
- }
-+#endif
-
- return EGL_SUCCESS;
- }
-@@ -320,8 +326,16 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
- return EGL_BAD_ACCESS;
- }
-
-+ // Windows Phone works around the rotation limitation by using negative values for the swap chain size
-+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
-+ mRotateL = backbufferWidth < 0; // Landscape/InvertedLandscape
-+ mRotateR = backbufferHeight < 0; // InvertedPortrait/InvertedLandscape
-+ backbufferWidth = abs(backbufferWidth);
-+ backbufferHeight = abs(backbufferHeight);
-+#endif
-+
- // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
-- if (backbufferWidth < 1 || backbufferHeight < 1)
-+ if (backbufferWidth == 0 || backbufferHeight == 0)
- {
- return EGL_SUCCESS;
- }
-@@ -329,6 +343,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
- // Can only call resize if we have already created our swap buffer and resources
- ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
-
-+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // The swap chain is not directly resized on Windows Phone
- SafeRelease(mBackBufferTexture);
- SafeRelease(mBackBufferRTView);
-
-@@ -366,6 +381,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
- {
- d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
- }
-+#endif
-
- return resetOffscreenTexture(backbufferWidth, backbufferHeight);
- }
-@@ -512,16 +528,6 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
- ID3D11Device *device = mRenderer->getDevice();
- ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
-
-- // Set vertices
-- D3D11_MAPPED_SUBRESOURCE mappedResource;
-- HRESULT result = deviceContext->Map(mQuadVB, 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;
-@@ -533,10 +539,23 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
- float u2 = (x + width) / float(mWidth);
- float v2 = (y + height) / float(mHeight);
-
-- 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);
-+ const bool rotateL = mRotateL;
-+ const bool rotateR = mRotateR;
-+
-+ // Set vertices
-+ D3D11_MAPPED_SUBRESOURCE mappedResource;
-+ HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
-+ if (FAILED(result))
-+ {
-+ return EGL_BAD_ACCESS;
-+ }
-+
-+ d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
-+
-+ d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1);
-+ d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2);
-+ d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1);
-+ d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2);
-
- deviceContext->Unmap(mQuadVB, 0);
-
-@@ -564,10 +583,11 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
-
- // Set the viewport
- D3D11_VIEWPORT viewport;
-- viewport.TopLeftX = 0;
-- viewport.TopLeftY = 0;
-- viewport.Width = mWidth;
-- viewport.Height = mHeight;
-+ viewport.TopLeftX = 0.0f;
-+ viewport.TopLeftY = 0.0f;
-+ const bool invertViewport = (mRotateL || mRotateR) && !(mRotateL && mRotateR);
-+ viewport.Width = FLOAT(invertViewport ? mHeight : mWidth);
-+ viewport.Height = FLOAT(invertViewport ? mWidth : mHeight);
- viewport.MinDepth = 0.0f;
- viewport.MaxDepth = 1.0f;
- deviceContext->RSSetViewports(1, &viewport);
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
-index 22401d8..77509ed 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h
-@@ -52,6 +52,8 @@ class SwapChain11 : public SwapChain
- Renderer11 *mRenderer;
- EGLint mHeight;
- EGLint mWidth;
-+ bool mRotateL;
-+ bool mRotateR;
- bool mAppCreatedShareHandle;
- unsigned int mSwapInterval;
- bool mPassThroughResourcesInit;
---
-1.9.4.msysgit.1
-
diff --git a/src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch b/src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch
deleted file mode 100644
index dd2768cf3e..0000000000
--- a/src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch
+++ /dev/null
@@ -1,637 +0,0 @@
-From 829bf86c57357d3c8ec598b92fcfdb1849e84075 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@theqtcompany.com>
-Date: Tue, 11 Nov 2014 17:11:54 +0200
-Subject: [PATCH 10/16] ANGLE: Enable D3D11 for feature level 9 cards
-
-Enable use of ANGLE on lower-end hardware, such as Surface RT and
-Windows Phone 8.
-
-Change-Id: Ice536802e4eedc1d264abd0dd65960638fce59e4
----
- src/3rdparty/angle/src/libGLESv2/angletypes.cpp | 6 +-
- .../src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp | 69 ++++---
- .../src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp | 4 +-
- .../src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp | 7 +-
- .../renderer/d3d/d3d11/PixelTransfer11.cpp | 9 +-
- .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 226 +++++++++++++--------
- .../src/libGLESv2/renderer/d3d/d3d11/Renderer11.h | 1 +
- .../renderer/d3d/d3d11/TextureStorage11.cpp | 4 +-
- .../libGLESv2/renderer/d3d/d3d11/formatutils11.cpp | 4 +-
- .../renderer/d3d/d3d11/renderer11_utils.cpp | 2 +-
- 10 files changed, 208 insertions(+), 124 deletions(-)
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
-index 6fd02e0..5a0cfc5 100644
---- a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
-@@ -12,6 +12,8 @@
- #include "libGLESv2/State.h"
- #include "libGLESv2/VertexArray.h"
-
-+#include <float.h>
-+
- namespace gl
- {
-
-@@ -24,8 +26,8 @@ SamplerState::SamplerState()
- maxAnisotropy(1.0f),
- baseLevel(0),
- maxLevel(1000),
-- minLod(-1000.0f),
-- maxLod(1000.0f),
-+ minLod(-FLT_MAX),
-+ maxLod(FLT_MAX),
- compareMode(GL_NONE),
- compareFunc(GL_LEQUAL),
- swizzleRed(GL_RED),
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
-index 91e7552..06aea9b 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp
-@@ -209,7 +209,7 @@ Blit11::Blit11(Renderer11 *renderer)
- pointSamplerDesc.BorderColor[2] = 0.0f;
- pointSamplerDesc.BorderColor[3] = 0.0f;
- pointSamplerDesc.MinLOD = 0.0f;
-- pointSamplerDesc.MaxLOD = 0.0f;
-+ pointSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f;
-
- result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler);
- ASSERT(SUCCEEDED(result));
-@@ -228,7 +228,7 @@ Blit11::Blit11(Renderer11 *renderer)
- linearSamplerDesc.BorderColor[2] = 0.0f;
- linearSamplerDesc.BorderColor[3] = 0.0f;
- linearSamplerDesc.MinLOD = 0.0f;
-- linearSamplerDesc.MaxLOD = 0.0f;
-+ linearSamplerDesc.MaxLOD = mRenderer->isLevel9() ? D3D11_FLOAT32_MAX : 0.0f;
-
- result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler);
- ASSERT(SUCCEEDED(result));
-@@ -290,28 +290,31 @@ Blit11::Blit11(Renderer11 *renderer)
- ASSERT(SUCCEEDED(result));
- d3d11::SetDebugName(mQuad2DVS, "Blit11 2D vertex shader");
-
-- result = device->CreatePixelShader(g_PS_PassthroughDepth2D, ArraySize(g_PS_PassthroughDepth2D), NULL, &mDepthPS);
-- ASSERT(SUCCEEDED(result));
-- d3d11::SetDebugName(mDepthPS, "Blit11 2D depth pixel shader");
--
-- D3D11_INPUT_ELEMENT_DESC quad3DLayout[] =
-+ if (!renderer->isLevel9())
- {
-- { "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 },
-- };
--
-- result = device->CreateInputLayout(quad3DLayout, ArraySize(quad3DLayout), g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), &mQuad3DIL);
-- ASSERT(SUCCEEDED(result));
-- d3d11::SetDebugName(mQuad3DIL, "Blit11 3D input layout");
--
-- result = device->CreateVertexShader(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), NULL, &mQuad3DVS);
-- ASSERT(SUCCEEDED(result));
-- d3d11::SetDebugName(mQuad3DVS, "Blit11 3D vertex shader");
-+ result = device->CreatePixelShader(g_PS_PassthroughDepth2D, ArraySize(g_PS_PassthroughDepth2D), NULL, &mDepthPS);
-+ ASSERT(SUCCEEDED(result));
-+ d3d11::SetDebugName(mDepthPS, "Blit11 2D depth pixel shader");
-
-- result = device->CreateGeometryShader(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), NULL, &mQuad3DGS);
-- ASSERT(SUCCEEDED(result));
-- d3d11::SetDebugName(mQuad3DGS, "Renderer11 copy 3D texture geometry shader");
-+ 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 },
-+ };
-+
-+ result = device->CreateInputLayout(quad3DLayout, ArraySize(quad3DLayout), g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), &mQuad3DIL);
-+ ASSERT(SUCCEEDED(result));
-+ d3d11::SetDebugName(mQuad3DIL, "Blit11 3D input layout");
-+
-+ result = device->CreateVertexShader(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), NULL, &mQuad3DVS);
-+ ASSERT(SUCCEEDED(result));
-+ d3d11::SetDebugName(mQuad3DVS, "Blit11 3D vertex shader");
-+
-+ result = device->CreateGeometryShader(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), NULL, &mQuad3DGS);
-+ ASSERT(SUCCEEDED(result));
-+ d3d11::SetDebugName(mQuad3DGS, "Renderer11 copy 3D texture geometry shader");
-+ }
-
- buildShaderMap();
-
-@@ -970,22 +973,27 @@ void Blit11::buildShaderMap()
- ID3D11Device *device = mRenderer->getDevice();
-
- add2DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader" ));
-- add2DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI, "Blit11 2D RGBA UI pixel shader" ));
-- add2DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader" ));
- add2DBlitShaderToMap(GL_BGRA_EXT, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader" ));
- add2DBlitShaderToMap(GL_RGB, false, d3d11::CompilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader" ));
-- add2DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader" ));
-- add2DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader" ));
- add2DBlitShaderToMap(GL_RG, false, d3d11::CompilePS(device, g_PS_PassthroughRG2D, "Blit11 2D RG pixel shader" ));
-- add2DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader" ));
-- add2DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader" ));
- add2DBlitShaderToMap(GL_RED, false, d3d11::CompilePS(device, g_PS_PassthroughR2D, "Blit11 2D R pixel shader" ));
-- add2DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader" ));
-- add2DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader" ));
- add2DBlitShaderToMap(GL_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D alpha pixel shader" ));
- add2DBlitShaderToMap(GL_LUMINANCE, false, d3d11::CompilePS(device, g_PS_PassthroughLum2D, "Blit11 2D lum pixel shader" ));
- add2DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha2D, "Blit11 2D luminance alpha pixel shader"));
-
-+ addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader" ));
-+
-+ if (mRenderer->isLevel9())
-+ return;
-+
-+ add2DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI, "Blit11 2D RGBA UI pixel shader" ));
-+ add2DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader" ));
-+ add2DBlitShaderToMap(GL_RGB_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader" ));
-+ add2DBlitShaderToMap(GL_RGB_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader" ));
-+ add2DBlitShaderToMap(GL_RG_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader" ));
-+ add2DBlitShaderToMap(GL_RG_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader" ));
-+ add2DBlitShaderToMap(GL_RED_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader" ));
-+ add2DBlitShaderToMap(GL_RED_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader" ));
- add3DBlitShaderToMap(GL_RGBA, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader" ));
- add3DBlitShaderToMap(GL_RGBA_INTEGER, false, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader" ));
- add3DBlitShaderToMap(GL_RGBA_INTEGER, true, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader" ));
-@@ -1003,7 +1011,6 @@ void Blit11::buildShaderMap()
- add3DBlitShaderToMap(GL_LUMINANCE, false, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader" ));
- add3DBlitShaderToMap(GL_LUMINANCE_ALPHA, false, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader"));
-
-- addSwizzleShaderToMap(GL_FLOAT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader" ));
- addSwizzleShaderToMap(GL_UNSIGNED_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleUI2D, "Blit11 2D UI swizzle pixel shader"));
- addSwizzleShaderToMap(GL_INT, D3D_SRV_DIMENSION_TEXTURE2D, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader" ));
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
-index 2d5fa3c..5aab379 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp
-@@ -753,7 +753,9 @@ void Buffer11::NativeBuffer11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Ren
-
- case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
- bufferDesc->Usage = D3D11_USAGE_DEFAULT;
-- bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT;
-+ bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER;
-+ if (!renderer->isLevel9())
-+ bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT;
- bufferDesc->CPUAccessFlags = 0;
- break;
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
-index 4630762..7185a05 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp
-@@ -104,7 +104,7 @@ Clear11::Clear11(Renderer11 *renderer)
- rsDesc.DepthBias = 0;
- rsDesc.DepthBiasClamp = 0.0f;
- rsDesc.SlopeScaledDepthBias = 0.0f;
-- rsDesc.DepthClipEnable = FALSE;
-+ rsDesc.DepthClipEnable = renderer->isLevel9();
- rsDesc.ScissorEnable = FALSE;
- rsDesc.MultisampleEnable = FALSE;
- rsDesc.AntialiasedLineEnable = FALSE;
-@@ -114,6 +114,11 @@ Clear11::Clear11(Renderer11 *renderer)
- d3d11::SetDebugName(mRasterizerState, "Clear11 masked clear rasterizer state");
-
- mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat);
-+ if (mRenderer->isLevel9()) {
-+ memset(&mUintClearShader, 0, sizeof(ClearShader));
-+ memset(&mIntClearShader, 0, sizeof(ClearShader));
-+ return;
-+ }
- mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint );
- mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint );
- }
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
-index a4072d8..6a3d347 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp
-@@ -133,10 +133,13 @@ gl::Error PixelTransfer11::loadResources()
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture vertex shader.");
- }
-
-- mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
-- if (!mBufferToTextureGS)
-+ if (!mRenderer->isLevel9())
- {
-- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader.");
-+ mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
-+ if (!mBufferToTextureGS)
-+ {
-+ return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader.");
-+ }
- }
-
- gl::Error error = buildShaderMap();
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-index ffc6cc9..f6ba930 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-@@ -153,6 +153,24 @@ Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const eg
- }
- }
-
-+#if !defined(ANGLE_ENABLE_D3D9)
-+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9)
-+ {
-+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3)
-+ {
-+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3);
-+ }
-+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 2)
-+ {
-+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_2);
-+ }
-+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
-+ {
-+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_1);
-+ }
-+ }
-+#endif
-+
- mDriverType = (attributes.get(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_FALSE) == EGL_TRUE) ? D3D_DRIVER_TYPE_WARP
- : D3D_DRIVER_TYPE_HARDWARE;
- }
-@@ -1170,6 +1188,83 @@ gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, cons
- return gl::Error(GL_NO_ERROR);
- }
- }
-+template<typename T>
-+static void fillLineLoopIndices(GLenum type, GLsizei count, const GLvoid *indices, T *data)
-+{
-+ switch (type)
-+ {
-+ case GL_NONE: // Non-indexed draw
-+ for (int i = 0; i < count; i++)
-+ {
-+ data[i] = i;
-+ }
-+ data[count] = 0;
-+ break;
-+ case GL_UNSIGNED_BYTE:
-+ 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_UNSIGNED_SHORT:
-+ 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_UNSIGNED_INT:
-+ 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();
-+ }
-+}
-+
-+template<typename T>
-+static void fillTriangleFanIndices(GLenum type, unsigned int numTris, const GLvoid *indices, T *data)
-+{
-+ switch (type)
-+ {
-+ case GL_NONE: // Non-indexed draw
-+ for (unsigned int i = 0; i < numTris; i++)
-+ {
-+ data[i*3 + 0] = 0;
-+ data[i*3 + 1] = i + 1;
-+ data[i*3 + 2] = i + 2;
-+ }
-+ break;
-+ case GL_UNSIGNED_BYTE:
-+ for (unsigned int i = 0; i < numTris; i++)
-+ {
-+ data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
-+ data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
-+ data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
-+ }
-+ break;
-+ case GL_UNSIGNED_SHORT:
-+ for (unsigned int i = 0; i < numTris; i++)
-+ {
-+ data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
-+ data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
-+ data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
-+ }
-+ break;
-+ case GL_UNSIGNED_INT:
-+ for (unsigned int i = 0; i < numTris; i++)
-+ {
-+ data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
-+ data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
-+ data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
-+ }
-+ break;
-+ default: UNREACHABLE();
-+ }
-+}
-
- gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
- {
-@@ -1189,10 +1284,13 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
- indices = bufferData + offset;
- }
-
-+ // TODO: some level 9 hardware supports 32-bit indices; test and store support instead
-+ const int indexType = isLevel9() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
-+
- if (!mLineLoopIB)
- {
- mLineLoopIB = new StreamingIndexBufferInterface(this);
-- gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
-+ gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType);
- if (error.isError())
- {
- SafeDelete(mLineLoopIB);
-@@ -1203,7 +1301,8 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
- // Checked by Renderer11::applyPrimitiveType
- ASSERT(count >= 0);
-
-- if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int)))
-+ int indexTypeSize = indexType == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int);
-+ if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / indexTypeSize))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required.");
- }
-@@ -1223,42 +1322,12 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind
- return error;
- }
-
-- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
-+ if (indexType == GL_UNSIGNED_SHORT)
-+ fillLineLoopIndices(type, count, indices, reinterpret_cast<unsigned short*>(mappedMemory));
-+ else
-+ fillLineLoopIndices(type, count, indices, reinterpret_cast<unsigned int*>(mappedMemory));
- unsigned int indexBufferOffset = offset;
-
-- switch (type)
-- {
-- case GL_NONE: // Non-indexed draw
-- for (int i = 0; i < count; i++)
-- {
-- data[i] = i;
-- }
-- data[count] = 0;
-- break;
-- case GL_UNSIGNED_BYTE:
-- 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_UNSIGNED_SHORT:
-- 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_UNSIGNED_INT:
-- 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();
-- }
--
- error = mLineLoopIB->unmapBuffer();
- if (error.isError())
- {
-@@ -1300,10 +1369,12 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
- indices = bufferData + offset;
- }
-
-+ const int indexType = isLevel9() ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
-+
- if (!mTriangleFanIB)
- {
- mTriangleFanIB = new StreamingIndexBufferInterface(this);
-- gl::Error error = mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
-+ gl::Error error = mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType);
- if (error.isError())
- {
- SafeDelete(mTriangleFanIB);
-@@ -1316,13 +1387,14 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
-
- const unsigned int numTris = count - 2;
-
-- if (numTris > (std::numeric_limits<unsigned int>::max() / (sizeof(unsigned int) * 3)))
-+ int indexTypeSize = indexType == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int);
-+ if (numTris > (std::numeric_limits<unsigned int>::max() / (indexTypeSize * 3)))
- {
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required.");
- }
-
-- const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
-- gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
-+ const unsigned int spaceNeeded = (numTris * 3) * indexTypeSize;
-+ gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, indexType);
- if (error.isError())
- {
- return error;
-@@ -1336,45 +1408,12 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *
- return error;
- }
-
-- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
-- unsigned int indexBufferOffset = offset;
-+ if (indexType == GL_UNSIGNED_SHORT)
-+ fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned short*>(mappedMemory));
-+ else
-+ fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned int*>(mappedMemory));
-
-- switch (type)
-- {
-- case GL_NONE: // Non-indexed draw
-- for (unsigned int i = 0; i < numTris; i++)
-- {
-- data[i*3 + 0] = 0;
-- data[i*3 + 1] = i + 1;
-- data[i*3 + 2] = i + 2;
-- }
-- break;
-- case GL_UNSIGNED_BYTE:
-- for (unsigned int i = 0; i < numTris; i++)
-- {
-- data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
-- data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
-- data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
-- }
-- break;
-- case GL_UNSIGNED_SHORT:
-- for (unsigned int i = 0; i < numTris; i++)
-- {
-- data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
-- data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
-- data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
-- }
-- break;
-- case GL_UNSIGNED_INT:
-- for (unsigned int i = 0; i < numTris; i++)
-- {
-- data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
-- data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
-- data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
-- }
-- break;
-- default: UNREACHABLE();
-- }
-+ unsigned int indexBufferOffset = offset;
-
- error = mTriangleFanIB->unmapBuffer();
- if (error.isError())
-@@ -1634,7 +1673,7 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto
- }
-
- // needed for the point sprite geometry shader
-- if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
-+ if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 && mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
- {
- mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
- mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
-@@ -1938,7 +1977,10 @@ int Renderer11::getMajorShaderModel() const
- {
- 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_10_0:
-+ case D3D_FEATURE_LEVEL_9_3:
-+ case D3D_FEATURE_LEVEL_9_2:
-+ case D3D_FEATURE_LEVEL_9_1: return D3D10_SHADER_MAJOR_VERSION; // 4
- default: UNREACHABLE(); return 0;
- }
- }
-@@ -1949,7 +1991,10 @@ int Renderer11::getMinorShaderModel() const
- {
- 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_10_0:
-+ case D3D_FEATURE_LEVEL_9_3:
-+ case D3D_FEATURE_LEVEL_9_2:
-+ case D3D_FEATURE_LEVEL_9_1: return D3D10_SHADER_MINOR_VERSION; // 0
- default: UNREACHABLE(); return 0;
- }
- }
-@@ -2455,6 +2500,7 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
-
- unsigned int profileMajorVersion = 0;
- unsigned int profileMinorVersion = 0;
-+ const char *profileSuffix = NULL;
- switch (mFeatureLevel)
- {
- case D3D_FEATURE_LEVEL_11_0:
-@@ -2469,12 +2515,30 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin
- profileMajorVersion = 4;
- profileMinorVersion = 0;
- break;
-+ case D3D_FEATURE_LEVEL_9_3:
-+ profileMajorVersion = 4;
-+ profileMinorVersion = 0;
-+ profileSuffix = "_level_9_3";
-+ break;
-+ case D3D_FEATURE_LEVEL_9_2:
-+ profileMajorVersion = 4;
-+ profileMinorVersion = 0;
-+ profileSuffix = "_level_9_2";
-+ break;
-+ case D3D_FEATURE_LEVEL_9_1:
-+ profileMajorVersion = 4;
-+ profileMinorVersion = 0;
-+ profileSuffix = "_level_9_1";
-+ break;
-+ break;
- default:
- UNREACHABLE();
- return gl::Error(GL_INVALID_OPERATION);
- }
-
- std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion);
-+ if (profileSuffix)
-+ profile += profileSuffix;
-
- UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2;
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
-index c789cae..d44bd2f 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
-@@ -188,6 +188,7 @@ class Renderer11 : public RendererD3D
- ID3D11Device *getDevice() { return mDevice; }
- ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
- DXGIFactory *getDxgiFactory() { return mDxgiFactory; };
-+ bool isLevel9() { return mFeatureLevel <= D3D_FEATURE_LEVEL_9_3; }
-
- Blit11 *getBlitter() { return mBlit; }
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
-index 4287918..74af27e 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp
-@@ -744,7 +744,7 @@ gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource)
- D3D11_TEXTURE2D_DESC desc;
- desc.Width = mTextureWidth; // Compressed texture size constraints?
- desc.Height = mTextureHeight;
-- desc.MipLevels = mMipLevels;
-+ desc.MipLevels = mRenderer->isLevel9() ? 1 : mMipLevels;
- desc.ArraySize = 1;
- desc.Format = mTextureFormat;
- desc.SampleDesc.Count = 1;
-@@ -863,7 +863,7 @@ gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORM
- srvDesc.Format = format;
- srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
- srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
-- srvDesc.Texture2D.MipLevels = mipLevels;
-+ srvDesc.Texture2D.MipLevels = mRenderer->isLevel9() ? -1 : mipLevels;
-
- ID3D11Device *device = mRenderer->getDevice();
- HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV);
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
-index 1ea916d..90a879e 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp
-@@ -557,7 +557,7 @@ D3D11LoadFunctionMap BuildD3D11LoadFunctionMap()
- InsertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT_OES, LoadA16FToRGBA16F );
-
- // From GL_EXT_texture_storage
-- InsertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadToNative<GLubyte, 1> );
-+ InsertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadA8ToRGBA8 );
- InsertLoadFunction(&map, GL_LUMINANCE8_EXT, GL_UNSIGNED_BYTE, LoadL8ToRGBA8 );
- InsertLoadFunction(&map, GL_LUMINANCE8_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadLA8ToRGBA8 );
- InsertLoadFunction(&map, GL_ALPHA32F_EXT, GL_FLOAT, LoadA32FToRGBA32F );
-@@ -795,7 +795,7 @@ static D3D11ES3FormatMap BuildD3D11FormatMap()
-
- // From GL_EXT_texture_storage
- // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format |
-- InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN );
-+ InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_LUMINANCE8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
- InsertD3D11FormatInfo(&map, GL_LUMINANCE32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN );
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-index 9ffc32e..cbfe557 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-@@ -284,7 +284,7 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
- // 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;
-+ case D3D_FEATURE_LEVEL_9_1: return true; // Provided that mipmaps & wrap modes are not used
-
- default: UNREACHABLE(); return false;
- }
---
-1.9.4.msysgit.1
-
diff --git a/src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch b/src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch
deleted file mode 100644
index afc9f256a1..0000000000
--- a/src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From bbfd3cfcf6e1195d86368b61ce39504ce6acda50 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@theqtcompany.com>
-Date: Wed, 12 Nov 2014 17:09:23 +0200
-Subject: [PATCH 12/16] ANGLE: fix semantic index lookup
-
-The sorted semantic index table was returning a direct mapping to the
-new indices, instead of the old indices. This caused a mismatch in the
-GL type lookup for the translated attribute.
-
-Change-Id: I75d05ed707f56c45210e3dcbc277f894e3dc5a48
----
- src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp | 2 +-
- .../angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp | 4 ++--
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
-index 0619023..6d64b38 100644
---- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
-@@ -1216,7 +1216,7 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- int oldIndex = mAttributesByLayout[i];
-- sortedSemanticIndices[i] = mSemanticIndex[oldIndex];
-+ sortedSemanticIndices[i] = oldIndex;
- attributes[i] = oldTranslatedAttributes[oldIndex];
- }
- }
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
-index e41f238..ff90a6a 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp
-@@ -113,10 +113,10 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl
- // Record the type of the associated vertex shader vector in our key
- // This will prevent mismatched vertex shaders from using the same input layout
- GLint attributeSize;
-- programBinary->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL);
-+ programBinary->getActiveAttribute(sortedSemanticIndices[i], 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL);
-
- ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName;
-- ilKey.elements[ilKey.elementCount].desc.SemanticIndex = sortedSemanticIndices[i];
-+ ilKey.elements[ilKey.elementCount].desc.SemanticIndex = i;
- ilKey.elements[ilKey.elementCount].desc.Format = vertexFormatInfo.nativeFormat;
- ilKey.elements[ilKey.elementCount].desc.InputSlot = i;
- ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0;
---
-1.9.4.msysgit.1
-
diff --git a/src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch b/src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch
deleted file mode 100644
index b43dcc368b..0000000000
--- a/src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From 5ef9348de2624c21be1c9fddd265fec5a0851d25 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@theqtcompany.com>
-Date: Thu, 13 Nov 2014 15:34:26 +0200
-Subject: [PATCH 13/16] ANGLE: Add support for querying platform device
-
-The EGL_EXT_device_base extension allows for querying the platform
-device of the graphics hardware via eglQueryDisplayAttribEXT().
-As that extension is not supported by ANGLE, this patch adds similar
-functionality to the existing eglQuerySurfacePointerANGLE API. When
-EGL_DEVICE_EXT is passed as the queried attribute, the underlying
-D3D/DXGI device pointer is passed back to the caller via the value
-argument.
-
-The D3D device is needed for video support in QtMultimedia as well as
-the IDXGIDevice3::Trim() calls required by the Windows Store.
-
-Change-Id: Ibdf228d81d6604e56db9dd8597d7cd2983ebc428
----
- src/3rdparty/angle/src/libEGL/libEGL.cpp | 50 +++++++++++++++++++++++++-------
- 1 file changed, 39 insertions(+), 11 deletions(-)
-
-diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
-index dc20d85..68399d6 100644
---- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
-+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
-@@ -17,6 +17,9 @@
- #include "libGLESv2/Texture.h"
- #include "libGLESv2/main.h"
- #include "libGLESv2/renderer/SwapChain.h"
-+#if defined(ANGLE_ENABLE_D3D11)
-+# include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
-+#endif
-
- #include "libEGL/main.h"
- #include "libEGL/Display.h"
-@@ -582,25 +585,50 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
- egl::Display *display = static_cast<egl::Display*>(dpy);
- egl::Surface *eglSurface = (egl::Surface*)surface;
-
-- if (!validateSurface(display, eglSurface))
-- {
-- return EGL_FALSE;
-- }
--
-- if (surface == EGL_NO_SURFACE)
-- {
-- recordError(egl::Error(EGL_BAD_SURFACE));
-- return EGL_FALSE;
-- }
--
- switch (attribute)
- {
- case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
- {
-+ if (!validateSurface(display, eglSurface))
-+ {
-+ return EGL_FALSE;
-+ }
-+
-+ if (surface == EGL_NO_SURFACE)
-+ {
-+ recordError(egl::Error(EGL_BAD_SURFACE));
-+ return EGL_FALSE;
-+ }
-+
- rx::SwapChain *swapchain = eglSurface->getSwapChain();
- *value = (void*) (swapchain ? swapchain->getShareHandle() : NULL);
- }
- break;
-+#if defined(ANGLE_ENABLE_D3D11)
-+ case EGL_DEVICE_EXT:
-+ {
-+ if (!validateDisplay(display))
-+ {
-+ return EGL_FALSE;
-+ }
-+
-+ rx::Renderer *renderer = display->getRenderer();
-+ if (!renderer)
-+ {
-+ *value = NULL;
-+ break;
-+ }
-+
-+ if (renderer->getMajorShaderModel() < 4)
-+ {
-+ recordError(egl::Error(EGL_BAD_CONTEXT));
-+ return EGL_FALSE;
-+ }
-+
-+ *value = static_cast<rx::Renderer11*>(renderer)->getDevice();
-+ }
-+ break;
-+#endif
- default:
- recordError(egl::Error(EGL_BAD_ATTRIBUTE));
- return EGL_FALSE;
---
-1.9.4.msysgit.1
-
diff --git a/src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch b/src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch
deleted file mode 100644
index 9ceb34d964..0000000000
--- a/src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 5b3bc73210ed1847d9bd7a94f06cc0d5de8e0b89 Mon Sep 17 00:00:00 2001
-From: Michael Bruning <michael.bruning@digia.com>
-Date: Thu, 13 Nov 2014 15:40:10 +0200
-Subject: [PATCH 14/16] Let ANGLE use multithreaded devices if necessary.
-
-This is needed to prevent lock-ups in application that use ANGLE from
-multiple threads, as e.g. QtWebEngine based applications do.
-
-The environment variable QT_D3DCREATE_MULTITHREADED is used to
-communicate this from the QtWebEngine module.
-
-Change-Id: Ibd5a5c75eb68af567d420d9a35efb3490c93b27c
----
- src/3rdparty/angle/src/common/platform.h | 1 +
- .../angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 10 ++++++++++
- .../angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 4 ++++
- 3 files changed, 15 insertions(+)
-
-diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
-index 0065ec7..8b2190d 100644
---- a/src/3rdparty/angle/src/common/platform.h
-+++ b/src/3rdparty/angle/src/common/platform.h
-@@ -57,6 +57,7 @@
-
- # if defined(ANGLE_ENABLE_D3D11)
- # include <d3d10_1.h>
-+# include <d3d10.h>
- # include <d3d11.h>
- # include <d3d11_1.h>
- # include <dxgi.h>
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-index f6ba930..46b9984 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-@@ -258,6 +258,16 @@ EGLint Renderer11::initialize()
- }
-
- #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
-+ static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED");
-+ if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1"))
-+ {
-+ ID3D10Multithread *multithread;
-+ result = mDevice->QueryInterface(IID_PPV_ARGS(&multithread));
-+ ASSERT(SUCCEEDED(result));
-+ result = multithread->SetMultithreadProtected(true);
-+ ASSERT(SUCCEEDED(result));
-+ multithread->Release();
-+ }
- #if !ANGLE_SKIP_DXGI_1_2_CHECK
- // 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.
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-index 82963ec..4c552b2 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-@@ -299,6 +299,10 @@ EGLint Renderer9::initialize()
- D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
- DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
-
-+ static wchar_t *qt_d3dcreate_multihreaded_var = _wgetenv(L"QT_D3DCREATE_MULTITHREADED");
-+ if (qt_d3dcreate_multihreaded_var && wcsstr(qt_d3dcreate_multihreaded_var, L"1"))
-+ behaviorFlags |= D3DCREATE_MULTITHREADED;
-+
- {
- result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
- }
---
-1.9.4.msysgit.1
-
diff --git a/src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch b/src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch
deleted file mode 100644
index f78474f11a..0000000000
--- a/src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch
+++ /dev/null
@@ -1,536 +0,0 @@
-From d9a9219ea2181dd4c1939d05747a21b67f16a906 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@theqtcompany.com>
-Date: Thu, 13 Nov 2014 16:33:53 +0200
-Subject: [PATCH 15/16] ANGLE: Fix -angle-d3d11 on MSVC2010
-
-Allow the D3D11 renderer to build with the June 2010 DirectX SDK.
-
-Change-Id: I2343acedab16845d6a0d4a53cf3145f583efc4a7
----
- src/3rdparty/angle/src/common/platform.h | 8 +-
- src/3rdparty/angle/src/libGLESv2/Context.cpp | 8 +-
- src/3rdparty/angle/src/libGLESv2/Data.h | 2 +-
- src/3rdparty/angle/src/libGLESv2/State.cpp | 6 +-
- .../src/libGLESv2/renderer/d3d/RendererD3D.cpp | 4 +-
- .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 4 +-
- .../renderer/d3d/d3d11/renderer11_utils.cpp | 137 +++++++++++++++++++++
- 7 files changed, 156 insertions(+), 13 deletions(-)
-
-diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
-index 8b2190d..972eee2 100644
---- a/src/3rdparty/angle/src/common/platform.h
-+++ b/src/3rdparty/angle/src/common/platform.h
-@@ -52,17 +52,23 @@
-
- # if defined(ANGLE_ENABLE_D3D9)
- # include <d3d9.h>
-+# if !defined(COMPILER_IMPLEMENTATION)
- # include <d3dcompiler.h>
-+# endif
- # endif
-
- # if defined(ANGLE_ENABLE_D3D11)
- # include <d3d10_1.h>
- # include <d3d10.h>
- # include <d3d11.h>
--# include <d3d11_1.h>
- # include <dxgi.h>
-+# if defined(_MSC_VER) && (_MSC_VER >= 1700)
-+# include <d3d11_1.h>
- # include <dxgi1_2.h>
-+# endif
-+# if !defined(COMPILER_IMPLEMENTATION)
- # include <d3dcompiler.h>
-+# endif
- # endif
-
- # if defined(ANGLE_ENABLE_WINDOWS_STORE)
-diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp
-index fe9b1a2..b87689c 100644
---- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp
-@@ -168,9 +168,9 @@ Context::~Context()
- }
- mIncompleteTextures.clear();
-
-- for (auto &zeroTexture : mZeroTextures)
-+ for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
- {
-- zeroTexture.second.set(NULL);
-+ i->second.set(NULL);
- }
- mZeroTextures.clear();
-
-@@ -354,7 +354,7 @@ void Context::deleteFenceSync(GLsync fenceSync)
-
- void Context::deleteVertexArray(GLuint vertexArray)
- {
-- auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
-+ VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray);
-
- if (vertexArrayObject != mVertexArrayMap.end())
- {
-@@ -460,7 +460,7 @@ FenceSync *Context::getFenceSync(GLsync handle) const
-
- VertexArray *Context::getVertexArray(GLuint handle) const
- {
-- auto vertexArray = mVertexArrayMap.find(handle);
-+ VertexArrayMap::const_iterator vertexArray = mVertexArrayMap.find(handle);
-
- if (vertexArray == mVertexArrayMap.end())
- {
-diff --git a/src/3rdparty/angle/src/libGLESv2/Data.h b/src/3rdparty/angle/src/libGLESv2/Data.h
-index cff872a..9234403 100644
---- a/src/3rdparty/angle/src/libGLESv2/Data.h
-+++ b/src/3rdparty/angle/src/libGLESv2/Data.h
-@@ -14,7 +14,7 @@
- namespace gl
- {
-
--struct Data final
-+struct Data
- {
- public:
- Data(GLint clientVersion, const State &state, const Caps &caps,
-diff --git a/src/3rdparty/angle/src/libGLESv2/State.cpp b/src/3rdparty/angle/src/libGLESv2/State.cpp
-index e7acda2..b5b62f5 100644
---- a/src/3rdparty/angle/src/libGLESv2/State.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/State.cpp
-@@ -665,13 +665,13 @@ void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
-
- void State::initializeZeroTextures(const TextureMap &zeroTextures)
- {
-- for (const auto &zeroTexture : zeroTextures)
-+ for (TextureMap::const_iterator i = zeroTextures.begin(); i != zeroTextures.end(); i++)
- {
-- auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
-+ TextureBindingVector &samplerTextureArray = mSamplerTextures[i->first];
-
- for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
- {
-- samplerTextureArray[textureUnit].set(zeroTexture.second.get());
-+ samplerTextureArray[textureUnit].set(i->second.get());
- }
- }
- }
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
-index 6f58243..97da6da 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
-@@ -27,9 +27,9 @@ RendererD3D::RendererD3D(egl::Display *display)
-
- RendererD3D::~RendererD3D()
- {
-- for (auto &incompleteTexture : mIncompleteTextures)
-+ for (gl::TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); ++i)
- {
-- incompleteTexture.second.set(NULL);
-+ i->second.set(NULL);
- }
- mIncompleteTextures.clear();
- }
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-index 46b9984..a28fd78 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-@@ -873,7 +873,7 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
-
- void Renderer11::unsetSRVsWithResource(gl::SamplerType samplerType, const ID3D11Resource *resource)
- {
-- auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
-+ std::vector<ID3D11ShaderResourceView *> &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
-
- for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
- {
-@@ -3398,7 +3398,7 @@ Workarounds Renderer11::generateWorkarounds() const
-
- void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv)
- {
-- auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
-+ std::vector<ID3D11ShaderResourceView *> &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
-
- ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-index cbfe557..5831c57 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-@@ -18,6 +18,85 @@
-
- #include <algorithm>
-
-+#ifndef D3D_FL9_1_DEFAULT_MAX_ANISOTROPY
-+# define D3D_FL9_1_DEFAULT_MAX_ANISOTROPY 2
-+#endif
-+#ifndef D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT
-+# define D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT 1
-+#endif
-+#ifndef D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT
-+# define D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT 4
-+#endif
-+#ifndef D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT
-+# define D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT 65535
-+#endif
-+#ifndef D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT
-+# define D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT 1048575
-+#endif
-+#ifndef D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION
-+# define D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION 512
-+#endif
-+#ifndef D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION
-+# define D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION 4096
-+#endif
-+#ifndef D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION
-+# define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048
-+#endif
-+#ifndef D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
-+# define D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 256
-+#endif
-+#ifndef D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION
-+# define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096
-+#endif
-+#ifndef D3D11_REQ_TEXTURECUBE_DIMENSION
-+# define D3D11_REQ_TEXTURECUBE_DIMENSION 16384
-+#endif
-+#ifndef D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION
-+# define D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION 2048
-+#endif
-+#ifndef D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
-+# define D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 2048
-+#endif
-+#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP
-+# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32
-+#endif
-+#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP
-+# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32
-+#endif
-+#ifndef D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT
-+# define D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT 32
-+#endif
-+#ifndef D3D11_STANDARD_VERTEX_ELEMENT_COUNT
-+# define D3D11_STANDARD_VERTEX_ELEMENT_COUNT 32
-+#endif
-+#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT
-+# define D3D10_1_SO_BUFFER_SLOT_COUNT 4
-+#endif
-+#ifndef D3D11_SO_BUFFER_SLOT_COUNT
-+# define D3D11_SO_BUFFER_SLOT_COUNT 4
-+#endif
-+#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
-+# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14
-+#endif
-+#ifndef D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT
-+# define D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT 16
-+#endif
-+#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE
-+# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -8
-+#endif
-+#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE
-+# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE 7
-+#endif
-+#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT
-+# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096
-+#endif
-+#ifndef D3D11_PS_INPUT_REGISTER_COUNT
-+# define D3D11_PS_INPUT_REGISTER_COUNT 32
-+#endif
-+#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT
-+# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32
-+#endif
-+
- namespace rx
- {
-
-@@ -276,7 +355,9 @@ static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0:
- case D3D_FEATURE_LEVEL_10_1:
- case D3D_FEATURE_LEVEL_10_0: return true;
-@@ -294,7 +375,9 @@ static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -314,7 +397,9 @@ static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0:
- case D3D_FEATURE_LEVEL_10_1:
- case D3D_FEATURE_LEVEL_10_0: return true;
-@@ -334,7 +419,9 @@ static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
-
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0:
- case D3D_FEATURE_LEVEL_10_1:
- case D3D_FEATURE_LEVEL_10_0:
-@@ -352,7 +439,9 @@ static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
-
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0:
- case D3D_FEATURE_LEVEL_10_1:
- case D3D_FEATURE_LEVEL_10_0:
-@@ -375,7 +464,9 @@ static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
-
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0:
- case D3D_FEATURE_LEVEL_10_1:
- case D3D_FEATURE_LEVEL_10_0:
-@@ -393,7 +484,9 @@ static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel
-
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -411,7 +504,9 @@ static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -429,7 +524,9 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -447,7 +544,9 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -465,7 +564,9 @@ static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -483,7 +584,9 @@ static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -507,7 +610,9 @@ static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
-
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0:
- case D3D_FEATURE_LEVEL_10_1:
- case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
-@@ -529,7 +634,9 @@ static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
-
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0:
- case D3D_FEATURE_LEVEL_10_1:
- case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
-@@ -546,7 +653,9 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- 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;
-@@ -566,7 +675,9 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
- // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -591,7 +702,9 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -618,7 +731,9 @@ static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
-
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
-
- case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
-@@ -637,7 +752,9 @@ static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -659,7 +776,9 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
- // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -684,7 +803,9 @@ static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -703,7 +824,9 @@ static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -722,7 +845,9 @@ static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -741,7 +866,9 @@ static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -760,7 +887,9 @@ static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- 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;
-@@ -783,7 +912,9 @@ static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
-
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -802,7 +933,9 @@ static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- 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;
-@@ -820,7 +953,9 @@ static size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL feat
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0:
-
- case D3D_FEATURE_LEVEL_10_1:
-@@ -838,7 +973,9 @@ static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL feature
- {
- switch (featureLevel)
- {
-+#if !defined(_MSC_VER) || (_MSC_VER >= 1800)
- case D3D_FEATURE_LEVEL_11_1:
-+#endif
- case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponents(featureLevel) /
- GetMaximumStreamOutputBuffers(featureLevel);
-
---
-1.9.4.msysgit.1
-
diff --git a/src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch b/src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch
deleted file mode 100644
index e3df95d8bf..0000000000
--- a/src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch
+++ /dev/null
@@ -1,169 +0,0 @@
-From 43c8ceb17ccd6d5ae13a07c6d01b45eb40983917 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@theqtcompany.com>
-Date: Tue, 11 Nov 2014 14:36:43 +0200
-Subject: [PATCH 16/16] ANGLE: Fix compilation with MinGW + D3D11
-
-Provide workarounds for things GCC doesn't like, and define a few
-missing definitions not found in the MinGW headers.
-
-Change-Id: I254c208209c0071fae5efb6727f2b3cfd5542da6
----
- src/3rdparty/angle/src/common/platform.h | 73 ++++++++++++++++++++++
- .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 6 ++
- .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 2 +-
- .../renderer/d3d/d3d11/renderer11_utils.cpp | 2 +-
- .../src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 4 +-
- 5 files changed, 83 insertions(+), 4 deletions(-)
-
-diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
-index 972eee2..0001e71 100644
---- a/src/3rdparty/angle/src/common/platform.h
-+++ b/src/3rdparty/angle/src/common/platform.h
-@@ -81,6 +81,79 @@
- # endif
- # endif
-
-+# if defined(__MINGW32__) // Missing defines on MinGW
-+typedef enum D3D11_MAP_FLAG
-+{
-+ D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000L
-+} D3D11_MAP_FLAG;
-+typedef struct D3D11_QUERY_DATA_SO_STATISTICS
-+{
-+ UINT64 NumPrimitivesWritten;
-+ UINT64 PrimitivesStorageNeeded;
-+} D3D11_QUERY_DATA_SO_STATISTICS;
-+typedef HRESULT (WINAPI *PFN_D3D11_CREATE_DEVICE)(
-+ IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL *,
-+ UINT FeatureLevels, UINT, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **);
-+#define D3D11_MESSAGE_CATEGORY UINT
-+#define D3D11_MESSAGE_SEVERITY UINT
-+#define D3D11_MESSAGE_ID UINT
-+struct D3D11_MESSAGE;
-+typedef struct D3D11_INFO_QUEUE_FILTER_DESC
-+{
-+ UINT NumCategories;
-+ D3D11_MESSAGE_CATEGORY *pCategoryList;
-+ UINT NumSeverities;
-+ D3D11_MESSAGE_SEVERITY *pSeverityList;
-+ UINT NumIDs;
-+ D3D11_MESSAGE_ID *pIDList;
-+} D3D11_INFO_QUEUE_FILTER_DESC;
-+typedef struct D3D11_INFO_QUEUE_FILTER
-+{
-+ D3D11_INFO_QUEUE_FILTER_DESC AllowList;
-+ D3D11_INFO_QUEUE_FILTER_DESC DenyList;
-+} D3D11_INFO_QUEUE_FILTER;
-+static const IID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 };
-+MIDL_INTERFACE("6543dbb6-1b48-42f5-ab82-e97ec74326f6") ID3D11InfoQueue : public IUnknown
-+{
-+public:
-+ virtual HRESULT __stdcall SetMessageCountLimit(UINT64) = 0;
-+ virtual void __stdcall ClearStoredMessages() = 0;
-+ virtual HRESULT __stdcall GetMessage(UINT64, D3D11_MESSAGE *, SIZE_T *) = 0;
-+ virtual UINT64 __stdcall GetNumMessagesAllowedByStorageFilter() = 0;
-+ virtual UINT64 __stdcall GetNumMessagesDeniedByStorageFilter() = 0;
-+ virtual UINT64 __stdcall GetNumStoredMessages() = 0;
-+ virtual UINT64 __stdcall GetNumStoredMessagesAllowedByRetrievalFilter() = 0;
-+ virtual UINT64 __stdcall GetNumMessagesDiscardedByMessageCountLimit() = 0;
-+ virtual UINT64 __stdcall GetMessageCountLimit() = 0;
-+ virtual HRESULT __stdcall AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
-+ virtual HRESULT __stdcall GetStorageFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
-+ virtual void __stdcall ClearStorageFilter() = 0;
-+ virtual HRESULT __stdcall PushEmptyStorageFilter() = 0;
-+ virtual HRESULT __stdcall PushCopyOfStorageFilter() = 0;
-+ virtual HRESULT __stdcall PushStorageFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
-+ virtual void __stdcall PopStorageFilter() = 0;
-+ virtual UINT __stdcall GetStorageFilterStackSize() = 0;
-+ virtual HRESULT __stdcall AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *) = 0;
-+ virtual HRESULT __stdcall GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *, SIZE_T *) = 0;
-+ virtual void __stdcall ClearRetrievalFilter() = 0;
-+ virtual HRESULT __stdcall PushEmptyRetrievalFilter() = 0;
-+ virtual HRESULT __stdcall PushCopyOfRetrievalFilter() = 0;
-+ virtual HRESULT __stdcall PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *) = 0;
-+ virtual void __stdcall PopRetrievalFilter() = 0;
-+ virtual UINT __stdcall GetRetrievalFilterStackSize() = 0;
-+ virtual HRESULT __stdcall AddMessage(D3D11_MESSAGE_CATEGORY, D3D11_MESSAGE_SEVERITY, D3D11_MESSAGE_ID, LPCSTR) = 0;
-+ virtual HRESULT __stdcall AddApplicationMessage(D3D11_MESSAGE_SEVERITY, LPCSTR) = 0;
-+ virtual HRESULT __stdcall SetBreakOnCategory(D3D11_MESSAGE_CATEGORY, BOOL) = 0;
-+ virtual HRESULT __stdcall SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY, BOOL) = 0;
-+ virtual HRESULT __stdcall SetBreakOnID(D3D11_MESSAGE_ID, BOOL) = 0;
-+ virtual BOOL __stdcall GetBreakOnCategory(D3D11_MESSAGE_CATEGORY) = 0;
-+ virtual BOOL __stdcall GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY) = 0;
-+ virtual BOOL __stdcall GetBreakOnID(D3D11_MESSAGE_ID) = 0;
-+ virtual void __stdcall SetMuteDebugOutput(BOOL) = 0;
-+ virtual BOOL __stdcall GetMuteDebugOutput() = 0;
-+};
-+#endif // __MINGW32__
-+
- # undef near
- # undef far
- #endif
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-index 9d003b4..776d92b 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp
-@@ -14,6 +14,12 @@
- #ifndef QT_D3DCOMPILER_DLL
- #define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
- #endif
-+#ifndef D3DCOMPILE_RESERVED16
-+#define D3DCOMPILE_RESERVED16 (1 << 16)
-+#endif
-+#ifndef D3DCOMPILE_RESERVED17
-+#define D3DCOMPILE_RESERVED17 (1 << 17)
-+#endif
-
- // Definitions local to the translation unit
- namespace
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-index a28fd78..e6d7f30 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-@@ -333,7 +333,7 @@ EGLint Renderer11::initialize()
- // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
- #if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
- ID3D11InfoQueue *infoQueue;
-- result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue);
-+ result = mDevice->QueryInterface(IID_ID3D11InfoQueue, (void **)&infoQueue);
-
- if (SUCCEEDED(result))
- {
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-index 5831c57..121aa3b 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp
-@@ -1196,7 +1196,7 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo
-
- HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
- {
--#if defined(_DEBUG)
-+#if defined(_DEBUG) && !defined(__MINGW32__)
- return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
- #else
- return S_OK;
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-index 4c552b2..601cd24 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-@@ -200,7 +200,7 @@ EGLint Renderer9::initialize()
- if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
- {
- ASSERT(mD3d9Ex);
-- mD3d9Ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void**>(&mD3d9));
-+ mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
- ASSERT(mD3d9);
- }
- else
-@@ -324,7 +324,7 @@ EGLint Renderer9::initialize()
-
- if (mD3d9Ex)
- {
-- result = mDevice->QueryInterface(__uuidof(IDirect3DDevice9Ex), (void**)&mDeviceEx);
-+ result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**)&mDeviceEx);
- ASSERT(SUCCEEDED(result));
- }
-
---
-1.9.4.msysgit.1
-
diff --git a/src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch b/src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch
deleted file mode 100644
index 4ada6d41d2..0000000000
--- a/src/angle/patches/0017-ANGLE-Fix-compilation-with-D3D9.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From d7839cc052de126cc3b457fe41963fd9c7e91846 Mon Sep 17 00:00:00 2001
-From: Kai Koehne <kai.koehne@theqtcompany.com>
-Date: Mon, 17 Nov 2014 15:10:10 +0100
-Subject: [PATCH] ANGLE: Fix compilation with D3D9
-
-Fixes a regression introduced in c6df5fe3ed0f2a722 that
-broke compilation with d3d9 (namely, -target xp).
-
-Task-number: QTBUG-42714
-Change-Id: I1a5e9682d5463bfa082a5d0c062399a131a7cf52
----
- src/3rdparty/angle/src/common/NativeWindow.h | 7 ++++++-
- src/3rdparty/angle/src/common/platform.h | 1 +
- src/3rdparty/angle/src/common/win32/NativeWindow.cpp | 2 +-
- 3 files changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/src/3rdparty/angle/src/common/NativeWindow.h b/src/3rdparty/angle/src/common/NativeWindow.h
-index 9e93aea..c4a0e42 100644
---- a/src/3rdparty/angle/src/common/NativeWindow.h
-+++ b/src/3rdparty/angle/src/common/NativeWindow.h
-@@ -54,7 +54,12 @@ public:
- bool getClientRect(LPRECT rect);
- bool isIconic();
-
-- HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory,
-+# if defined(ANGLE_ENABLE_D3D11)
-+ typedef ID3D11Device Device;
-+#else
-+ typedef IDirect3DDevice9 Device;
-+#endif
-+ HRESULT createSwapChain(Device* device, DXGIFactory* factory,
- DXGI_FORMAT format, UINT width, UINT height,
- DXGISwapChain** swapChain);
-
-diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h
-index 0001e71..5bf97f9 100644
---- a/src/3rdparty/angle/src/common/platform.h
-+++ b/src/3rdparty/angle/src/common/platform.h
-@@ -52,6 +52,7 @@
-
- # if defined(ANGLE_ENABLE_D3D9)
- # include <d3d9.h>
-+# include <dxgi.h>
- # if !defined(COMPILER_IMPLEMENTATION)
- # include <d3dcompiler.h>
- # endif
-diff --git a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
-index 2440747..46082a2 100644
---- a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
-+++ b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
-@@ -35,7 +35,7 @@ bool NativeWindow::isIconic()
- return IsIconic(mWindow) == TRUE;
- }
-
--HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory,
-+HRESULT NativeWindow::createSwapChain(NativeWindow::Device* device, DXGIFactory* factory,
- DXGI_FORMAT format, unsigned int width, unsigned int height,
- DXGISwapChain** swapChain)
- {
---
-1.9.4.msysgit.0
-
diff --git a/src/angle/patches/0018-ANGLE-Fix-releasing-textures-after-we-kill-D3D11.patch b/src/angle/patches/0018-ANGLE-Fix-releasing-textures-after-we-kill-D3D11.patch
deleted file mode 100644
index 97847ad684..0000000000
--- a/src/angle/patches/0018-ANGLE-Fix-releasing-textures-after-we-kill-D3D11.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 014d3fcf6011109491b0489da9c1abb1fdc6dbdc Mon Sep 17 00:00:00 2001
-From: Kai Koehne <kai.koehne@theqtcompany.com>
-Date: Mon, 24 Nov 2014 10:52:03 +0100
-Subject: [PATCH] ANGLE: Fix releasing textures after we kill D3D11
-
-Cherry-pick upstream commit cc4cd2925b9a4f1142a86df131345a861c9d7cd9
-to fix crashes on exit.
-
-Task-number: QTBUG-42772
-Change-Id: Ib74be17f2b5fdd58f9e0568e1da74ba19e943019
----
- src/3rdparty/angle/src/libGLESv2/Context.cpp | 6 ------
- src/3rdparty/angle/src/libGLESv2/Context.h | 1 -
- src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp | 5 +++++
- src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h | 2 ++
- src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 2 ++
- src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 2 ++
- 6 files changed, 11 insertions(+), 7 deletions(-)
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp
-index b87689c..3772da6 100644
---- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp
-@@ -162,12 +162,6 @@ Context::~Context()
- deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
- }
-
-- for (TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); i++)
-- {
-- i->second.set(NULL);
-- }
-- mIncompleteTextures.clear();
--
- for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
- {
- i->second.set(NULL);
-diff --git a/src/3rdparty/angle/src/libGLESv2/Context.h b/src/3rdparty/angle/src/libGLESv2/Context.h
-index 1e890de..0699592 100644
---- a/src/3rdparty/angle/src/libGLESv2/Context.h
-+++ b/src/3rdparty/angle/src/libGLESv2/Context.h
-@@ -247,7 +247,6 @@ class Context
- int mClientVersion;
-
- TextureMap mZeroTextures;
-- TextureMap mIncompleteTextures;
-
- typedef std::unordered_map<GLuint, Framebuffer*> FramebufferMap;
- FramebufferMap mFramebufferMap;
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
-index 97da6da..5cddd8a 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
-@@ -27,6 +27,11 @@ RendererD3D::RendererD3D(egl::Display *display)
-
- RendererD3D::~RendererD3D()
- {
-+ cleanup();
-+}
-+
-+void RendererD3D::cleanup()
-+{
- for (gl::TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); ++i)
- {
- i->second.set(NULL);
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
-index 9919207..a2f7787 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
-@@ -160,6 +160,8 @@ class RendererD3D : public Renderer
- const gl::Rectangle *scissor, bool blitRenderTarget,
- bool blitDepth, bool blitStencil, GLenum filter) = 0;
-
-+ void cleanup();
-+
- egl::Display *mDisplay;
-
- private:
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-index e6d7f30..777308e 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
-@@ -1870,6 +1870,8 @@ bool Renderer11::testDeviceResettable()
-
- void Renderer11::release()
- {
-+ RendererD3D::cleanup();
-+
- releaseShaderCompiler();
- releaseDeviceResources();
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-index 601cd24..18e6e2d 100644
---- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
-@@ -151,6 +151,8 @@ Renderer9::~Renderer9()
-
- void Renderer9::release()
- {
-+ RendererD3D::cleanup();
-+
- releaseShaderCompiler();
- releaseDeviceResources();
-
---
-1.9.4.msysgit.0
-
diff --git a/src/angle/patches/0019-ANGLE-Fix-handling-of-shader-source-with-fixed-lengt.patch b/src/angle/patches/0019-ANGLE-Fix-handling-of-shader-source-with-fixed-lengt.patch
deleted file mode 100644
index 5fa244c1b5..0000000000
--- a/src/angle/patches/0019-ANGLE-Fix-handling-of-shader-source-with-fixed-lengt.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 5e277b05a16e7be24d36c600f158f8119ee583d8 Mon Sep 17 00:00:00 2001
-From: Andrew Knight <andrew.knight@theqtcompany.com>
-Date: Mon, 1 Dec 2014 11:58:08 +0200
-Subject: [PATCH] ANGLE: Fix handling of shader source with fixed length
-
-This is a cherry-pick of upstream f60fab6d154f4c9bf599e92976cd8cee7f8633e0
-(See https://chromium-review.googlesource.com/231612)
-
-Task-number: QTBUG-42882
-Change-Id: I7b4bdc4b68a1b93ff514f09ce35dbf4e9360af9b
----
- src/3rdparty/angle/src/libGLESv2/Shader.cpp | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
-index 1cc17a0..5bca746 100644
---- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
-@@ -51,7 +51,14 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le
-
- for (int i = 0; i < count; i++)
- {
-- stream << string[i];
-+ if (length == nullptr || length[i] < 0)
-+ {
-+ stream.write(string[i], std::strlen(string[i]));
-+ }
-+ else
-+ {
-+ stream.write(string[i], length[i]);
-+ }
- }
-
- mSource = stream.str();
---
-1.9.4.msysgit.1
-
diff --git a/src/angle/patches/0020-ANGLE-Do-not-use-std-strlen.patch b/src/angle/patches/0020-ANGLE-Do-not-use-std-strlen.patch
deleted file mode 100644
index 324244f6eb..0000000000
--- a/src/angle/patches/0020-ANGLE-Do-not-use-std-strlen.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 071b8936386b0b44475c91511d85479e5c633bc5 Mon Sep 17 00:00:00 2001
-From: Kai Koehne <kai.koehne@theqtcompany.com>
-Date: Thu, 11 Dec 2014 13:54:23 +0100
-Subject: [PATCH] ANGLE: Do not use std::strlen
-
-This is a cherry-pick from upstream change
-
-e7cfb3dd2029c1bfe5c175ad994c03cac221ad4d
-
-Change-Id: Iefe01545319f9ad268c0c6bf8e8b2181e09d8a84
----
- src/3rdparty/angle/src/libGLESv2/Shader.cpp | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
-index 5bca746..024ef8f 100644
---- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
-@@ -53,7 +53,7 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le
- {
- if (length == nullptr || length[i] < 0)
- {
-- stream.write(string[i], std::strlen(string[i]));
-+ stream.write(string[i], strlen(string[i]));
- }
- else
- {
---
-1.9.4.msysgit.0
-
diff --git a/src/angle/patches/0020-ANGLE-Fix-compilation-with-MSVC2013-Update4.patch b/src/angle/patches/0020-ANGLE-Fix-compilation-with-MSVC2013-Update4.patch
deleted file mode 100644
index 49b229d905..0000000000
--- a/src/angle/patches/0020-ANGLE-Fix-compilation-with-MSVC2013-Update4.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From a48dfb3f1ecb57a59084c0e87155506586b73188 Mon Sep 17 00:00:00 2001
-From: Maurice Kalinowski <maurice.kalinowski@theqtcompany.com>
-Date: Thu, 11 Dec 2014 13:11:55 +0100
-Subject: [PATCH] [ANGLE] Fix compilation with MSVC2013 Update4
-
-Update4 provides a native Sleep implementation. Hence the wrapper
-needs to be disabled.
-
-Change-Id: I162da45934b02c262ac09b557c66c3363c276e54
----
- src/3rdparty/angle/src/common/utilities.cpp | 2 +-
- src/3rdparty/angle/src/common/utilities.h | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/src/3rdparty/angle/src/common/utilities.cpp b/src/3rdparty/angle/src/common/utilities.cpp
-index 9d797a6..924573e 100644
---- a/src/3rdparty/angle/src/common/utilities.cpp
-+++ b/src/3rdparty/angle/src/common/utilities.cpp
-@@ -486,7 +486,7 @@ void writeFile(const char* path, const void* content, size_t size)
- }
- #endif // !ANGLE_ENABLE_WINDOWS_STORE
-
--#if defined(ANGLE_ENABLE_WINDOWS_STORE)
-+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && _MSC_FULL_VER < 180031101
-
- void Sleep(unsigned long dwMilliseconds)
- {
-diff --git a/src/3rdparty/angle/src/common/utilities.h b/src/3rdparty/angle/src/common/utilities.h
-index 2cf6bed..7583d3e 100644
---- a/src/3rdparty/angle/src/common/utilities.h
-+++ b/src/3rdparty/angle/src/common/utilities.h
-@@ -51,7 +51,7 @@ std::string getTempPath();
- void writeFile(const char* path, const void* data, size_t size);
- #endif
-
--#if defined(ANGLE_ENABLE_WINDOWS_STORE)
-+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && _MSC_FULL_VER < 180031101
- void Sleep(_In_ unsigned long dwMilliseconds);
- #endif
-
---
-1.9.4.msysgit.2
-
diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri
index 7d3f46d65f..63b80347d1 100644
--- a/src/angle/src/common/common.pri
+++ b/src/angle/src/common/common.pri
@@ -46,20 +46,4 @@ win32-msvc2012|win32-msvc2013|winrt {
}
}
-static: DEFINES *= QT_OPENGL_ES_2_ANGLE_STATIC
-
-HEADERS += \
- $$ANGLE_DIR/src/common/angleutils.h \
- $$ANGLE_DIR/src/common/debug.h \
- $$ANGLE_DIR/src/common/mathutil.h \
- $$ANGLE_DIR/src/common/platform.h \
- $$ANGLE_DIR/src/common/RefCountObject.h \
- $$ANGLE_DIR/src/common/tls.h \
- $$ANGLE_DIR/src/common/version.h
-
-SOURCES += \
- $$ANGLE_DIR/src/common/angleutils.cpp \
- $$ANGLE_DIR/src/common/debug.cpp \
- $$ANGLE_DIR/src/common/RefCountObject.cpp \
- $$ANGLE_DIR/src/common/tls.cpp
-
+static: DEFINES *= LIBGLESV2_EXPORT_H_ ANGLE_EXPORT=
diff --git a/src/angle/src/compiler/preprocessor/preprocessor.pro b/src/angle/src/compiler/preprocessor/preprocessor.pro
index 420cb90b36..8c5b1555dc 100644
--- a/src/angle/src/compiler/preprocessor/preprocessor.pro
+++ b/src/angle/src/compiler/preprocessor/preprocessor.pro
@@ -48,7 +48,7 @@ flex.dependency_type = TYPE_C
flex.variable_out = GENERATED_SOURCES
QMAKE_EXTRA_COMPILERS += flex
-bison.commands = $$addGnuPath(bison) --no-lines --skeleton=yacc.c --output=${QMAKE_FILE_BASE}.cpp ${QMAKE_FILE_NAME}
+bison.commands = $$addGnuPath(win_bison) --no-lines --skeleton=yacc.c --output=${QMAKE_FILE_BASE}.cpp ${QMAKE_FILE_NAME}
bison.output = ${QMAKE_FILE_BASE}.cpp
bison.input = BISON_SOURCES
bison.dependency_type = TYPE_C
diff --git a/src/angle/src/compiler/translator.pro b/src/angle/src/compiler/translator.pro
index 6f0128d6de..e9d16ca5af 100644
--- a/src/angle/src/compiler/translator.pro
+++ b/src/angle/src/compiler/translator.pro
@@ -1,14 +1,11 @@
CONFIG += static
include(../config.pri)
-# Mingw 4.7 chokes on implicit move semantics, so disable C++11 here
-mingw: CONFIG -= c++11
-
INCLUDEPATH += \
$$ANGLE_DIR/src \
$$ANGLE_DIR/include
-DEFINES += _SECURE_SCL=0 _LIB COMPILER_IMPLEMENTATION
+DEFINES += _SECURE_SCL=0 _LIB ANGLE_TRANSLATOR_IMPLEMENTATION ANGLE_TRANSLATOR_STATIC ANGLE_ENABLE_HLSL
FLEX_SOURCES = $$ANGLE_DIR/src/compiler/translator/glslang.l
BISON_SOURCES = $$ANGLE_DIR/src/compiler/translator/glslang.y
@@ -23,26 +20,31 @@ HEADERS += \
$$ANGLE_DIR/src/common/platform.h \
$$ANGLE_DIR/src/common/tls.h \
$$ANGLE_DIR/src/common/utilities.h \
+ $$ANGLE_DIR/src/compiler/translator/blocklayout.h \
+ $$ANGLE_DIR/src/compiler/translator/blocklayoutHLSL.h \
$$ANGLE_DIR/src/compiler/translator/BaseTypes.h \
$$ANGLE_DIR/src/compiler/translator/BuiltInFunctionEmulator.h \
+ $$ANGLE_DIR/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h \
+ $$ANGLE_DIR/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h \
$$ANGLE_DIR/src/compiler/translator/Common.h \
- $$ANGLE_DIR/src/compiler/translator/Compiler.h \
$$ANGLE_DIR/src/compiler/translator/compilerdebug.h \
+ $$ANGLE_DIR/src/compiler/translator/Compiler.h \
$$ANGLE_DIR/src/compiler/translator/ConstantUnion.h \
- $$ANGLE_DIR/src/compiler/translator/depgraph/DependencyGraph.h \
$$ANGLE_DIR/src/compiler/translator/depgraph/DependencyGraphBuilder.h \
+ $$ANGLE_DIR/src/compiler/translator/depgraph/DependencyGraph.h \
$$ANGLE_DIR/src/compiler/translator/depgraph/DependencyGraphOutput.h \
$$ANGLE_DIR/src/compiler/translator/DetectCallDepth.h \
$$ANGLE_DIR/src/compiler/translator/DetectDiscontinuity.h \
$$ANGLE_DIR/src/compiler/translator/Diagnostics.h \
$$ANGLE_DIR/src/compiler/translator/DirectiveHandler.h \
$$ANGLE_DIR/src/compiler/translator/ExtensionBehavior.h \
+ $$ANGLE_DIR/src/compiler/translator/EmulatePrecision.h \
$$ANGLE_DIR/src/compiler/translator/FlagStd140Structs.h \
$$ANGLE_DIR/src/compiler/translator/ForLoopUnroll.h \
$$ANGLE_DIR/src/compiler/translator/HashNames.h \
$$ANGLE_DIR/src/compiler/translator/InfoSink.h \
- $$ANGLE_DIR/src/compiler/translator/Initialize.h \
$$ANGLE_DIR/src/compiler/translator/InitializeDll.h \
+ $$ANGLE_DIR/src/compiler/translator/Initialize.h \
$$ANGLE_DIR/src/compiler/translator/InitializeParseContext.h \
$$ANGLE_DIR/src/compiler/translator/InitializeVariables.h \
$$ANGLE_DIR/src/compiler/translator/intermediate.h \
@@ -51,21 +53,23 @@ HEADERS += \
$$ANGLE_DIR/src/compiler/translator/MMap.h \
$$ANGLE_DIR/src/compiler/translator/NodeSearch.h \
$$ANGLE_DIR/src/compiler/translator/osinclude.h \
+ $$ANGLE_DIR/src/compiler/translator/Operator.h \
$$ANGLE_DIR/src/compiler/translator/OutputESSL.h \
- $$ANGLE_DIR/src/compiler/translator/OutputGLSL.h \
$$ANGLE_DIR/src/compiler/translator/OutputGLSLBase.h \
+ $$ANGLE_DIR/src/compiler/translator/OutputGLSL.h \
$$ANGLE_DIR/src/compiler/translator/OutputHLSL.h \
$$ANGLE_DIR/src/compiler/translator/ParseContext.h \
$$ANGLE_DIR/src/compiler/translator/PoolAlloc.h \
$$ANGLE_DIR/src/compiler/translator/Pragma.h \
$$ANGLE_DIR/src/compiler/translator/QualifierAlive.h \
$$ANGLE_DIR/src/compiler/translator/RegenerateStructNames.h \
- $$ANGLE_DIR/src/compiler/translator/RemoveTree.h \
+ $$ANGLE_DIR/src/compiler/translator/RemoveSwitchFallThrough.h \
$$ANGLE_DIR/src/compiler/translator/RenameFunction.h \
$$ANGLE_DIR/src/compiler/translator/RewriteElseBlocks.h \
$$ANGLE_DIR/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h \
$$ANGLE_DIR/src/compiler/translator/SearchSymbol.h \
$$ANGLE_DIR/src/compiler/translator/ShHandle.h \
+ $$ANGLE_DIR/src/compiler/translator/SimplifyArrayAssignment.h \
$$ANGLE_DIR/src/compiler/translator/StructureHLSL.h \
$$ANGLE_DIR/src/compiler/translator/SymbolTable.h \
$$ANGLE_DIR/src/compiler/translator/timing/RestrictFragmentShaderTiming.h \
@@ -74,13 +78,14 @@ HEADERS += \
$$ANGLE_DIR/src/compiler/translator/TranslatorGLSL.h \
$$ANGLE_DIR/src/compiler/translator/TranslatorHLSL.h \
$$ANGLE_DIR/src/compiler/translator/Types.h \
- $$ANGLE_DIR/src/compiler/translator/UnfoldShortCircuit.h \
$$ANGLE_DIR/src/compiler/translator/UnfoldShortCircuitAST.h \
+ $$ANGLE_DIR/src/compiler/translator/UnfoldShortCircuit.h \
$$ANGLE_DIR/src/compiler/translator/UniformHLSL.h \
- $$ANGLE_DIR/src/compiler/translator/UtilsHLSL.h \
$$ANGLE_DIR/src/compiler/translator/util.h \
+ $$ANGLE_DIR/src/compiler/translator/UtilsHLSL.h \
$$ANGLE_DIR/src/compiler/translator/ValidateLimitations.h \
$$ANGLE_DIR/src/compiler/translator/ValidateOutputs.h \
+ $$ANGLE_DIR/src/compiler/translator/ValidateSwitch.h \
$$ANGLE_DIR/src/compiler/translator/VariableInfo.h \
$$ANGLE_DIR/src/compiler/translator/VariablePacker.h \
$$ANGLE_DIR/src/compiler/translator/VersionGLSL.h \
@@ -89,7 +94,11 @@ HEADERS += \
SOURCES += \
$$ANGLE_DIR/src/common/tls.cpp \
+ $$ANGLE_DIR/src/compiler/translator/blocklayout.cpp \
+ $$ANGLE_DIR/src/compiler/translator/blocklayoutHLSL.cpp \
$$ANGLE_DIR/src/compiler/translator/BuiltInFunctionEmulator.cpp \
+ $$ANGLE_DIR/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp \
+ $$ANGLE_DIR/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp \
$$ANGLE_DIR/src/compiler/translator/CodeGen.cpp \
$$ANGLE_DIR/src/compiler/translator/Compiler.cpp \
$$ANGLE_DIR/src/compiler/translator/compilerdebug.cpp \
@@ -101,6 +110,7 @@ SOURCES += \
$$ANGLE_DIR/src/compiler/translator/DetectDiscontinuity.cpp \
$$ANGLE_DIR/src/compiler/translator/Diagnostics.cpp \
$$ANGLE_DIR/src/compiler/translator/DirectiveHandler.cpp \
+ $$ANGLE_DIR/src/compiler/translator/EmulatePrecision.cpp \
$$ANGLE_DIR/src/compiler/translator/FlagStd140Structs.cpp \
$$ANGLE_DIR/src/compiler/translator/ForLoopUnroll.cpp \
$$ANGLE_DIR/src/compiler/translator/InfoSink.cpp \
@@ -113,6 +123,7 @@ SOURCES += \
$$ANGLE_DIR/src/compiler/translator/intermOut.cpp \
$$ANGLE_DIR/src/compiler/translator/IntermTraverse.cpp \
$$ANGLE_DIR/src/compiler/translator/LoopInfo.cpp \
+ $$ANGLE_DIR/src/compiler/translator/Operator.cpp \
$$ANGLE_DIR/src/compiler/translator/OutputESSL.cpp \
$$ANGLE_DIR/src/compiler/translator/OutputGLSL.cpp \
$$ANGLE_DIR/src/compiler/translator/OutputGLSLBase.cpp \
@@ -122,12 +133,13 @@ SOURCES += \
$$ANGLE_DIR/src/compiler/translator/PoolAlloc.cpp \
$$ANGLE_DIR/src/compiler/translator/QualifierAlive.cpp \
$$ANGLE_DIR/src/compiler/translator/RegenerateStructNames.cpp \
- $$ANGLE_DIR/src/compiler/translator/RemoveTree.cpp \
+ $$ANGLE_DIR/src/compiler/translator/RemoveSwitchFallThrough.cpp \
$$ANGLE_DIR/src/compiler/translator/RewriteElseBlocks.cpp \
$$ANGLE_DIR/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \
$$ANGLE_DIR/src/compiler/translator/SearchSymbol.cpp \
$$ANGLE_DIR/src/compiler/translator/ShaderLang.cpp \
$$ANGLE_DIR/src/compiler/translator/ShaderVars.cpp \
+ $$ANGLE_DIR/src/compiler/translator/SimplifyArrayAssignment.cpp \
$$ANGLE_DIR/src/compiler/translator/StructureHLSL.cpp \
$$ANGLE_DIR/src/compiler/translator/SymbolTable.cpp \
$$ANGLE_DIR/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \
@@ -143,6 +155,7 @@ SOURCES += \
$$ANGLE_DIR/src/compiler/translator/util.cpp \
$$ANGLE_DIR/src/compiler/translator/ValidateLimitations.cpp \
$$ANGLE_DIR/src/compiler/translator/ValidateOutputs.cpp \
+ $$ANGLE_DIR/src/compiler/translator/ValidateSwitch.cpp \
$$ANGLE_DIR/src/compiler/translator/VariableInfo.cpp \
$$ANGLE_DIR/src/compiler/translator/VariablePacker.cpp \
$$ANGLE_DIR/src/compiler/translator/VersionGLSL.cpp \
@@ -157,7 +170,7 @@ flex.dependency_type = TYPE_C
flex.variable_out = GENERATED_SOURCES
QMAKE_EXTRA_COMPILERS += flex
-bison.commands = $$addGnuPath(bison) --no-lines --skeleton=yacc.c --defines=${QMAKE_FILE_BASE}_tab.h \
+bison.commands = $$addGnuPath(win_bison) --no-lines --skeleton=yacc.c --defines=${QMAKE_FILE_BASE}_tab.h \
--output=${QMAKE_FILE_BASE}_tab.cpp ${QMAKE_FILE_NAME}
bison.output = ${QMAKE_FILE_BASE}_tab.h
bison.input = BISON_SOURCES
diff --git a/src/angle/src/config.pri b/src/angle/src/config.pri
index 9a7bc8a68c..0d75245ec5 100644
--- a/src/angle/src/config.pri
+++ b/src/angle/src/config.pri
@@ -37,8 +37,6 @@ DEFINES += _WINDOWS \
NOMINMAX \
WIN32_LEAN_AND_MEAN=1
-!winrt: DEFINES += ANGLE_ENABLE_D3D9 ANGLE_SKIP_DXGI_1_2_CHECK
-
CONFIG += angle_d3d11 # Remove to disable D3D11 renderer
equals(QMAKE_TARGET_OS, xp): CONFIG -= angle_d3d11
@@ -70,11 +68,12 @@ msvc {
# 4245: 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch
# 4267: coversion from 'size_t' to 'int', possible loss of data
# 4275: non - DLL-interface classkey 'identifier' used as base for DLL-interface classkey 'identifier'
+ # 4480: nonstandard extension used: specifying underlying type for enum
# 4512: 'class' : assignment operator could not be generated
# 4702: unreachable code
# 4996: Function call with parameters that may be unsafe
QMAKE_CFLAGS_WARN_ON -= -W3
- QMAKE_CFLAGS_WARN_ON += -W4 -wd"4100" -wd"4127" -wd"4189" -wd"4239" -wd"4244" -wd"4245" -wd"4267" -wd"4275" -wd"4512" -wd"4702" -wd"4996"
+ QMAKE_CFLAGS_WARN_ON += -W4 -wd"4100" -wd"4127" -wd"4189" -wd"4239" -wd"4244" -wd"4245" -wd"4267" -wd"4275" -wd"4512" -wd"4702" -wd"4996" -wd"4480"
# Optimizations
# /Oy: Omits frame pointer (x86 only).
# /Gy: Enables function-level linking.
diff --git a/src/angle/src/libEGL/libEGL.pro b/src/angle/src/libEGL/libEGL.pro
index a16249309f..94fcebda6b 100644
--- a/src/angle/src/libEGL/libEGL.pro
+++ b/src/angle/src/libEGL/libEGL.pro
@@ -5,40 +5,13 @@ winrt: LIBS_PRIVATE += -ld3d11
LIBS_PRIVATE += -ldxguid -L$$QT_BUILD_TREE/lib -l$$qtLibraryTarget(libGLESv2)
+DEFINES += GL_APICALL= GL_GLEXT_PROTOTYPES= EGLAPI= LIBEGL_IMPLEMENTATION
+
HEADERS += \
- $$ANGLE_DIR/src/common/NativeWindow.h \
- $$ANGLE_DIR/src/libEGL/AttributeMap.h \
- $$ANGLE_DIR/src/libEGL/Config.h \
- $$ANGLE_DIR/src/libEGL/Display.h \
- $$ANGLE_DIR/src/libEGL/Error.h \
- $$ANGLE_DIR/src/libEGL/main.h \
- $$ANGLE_DIR/src/libEGL/resource.h \
- $$ANGLE_DIR/src/libEGL/ShaderCache.h \
- $$ANGLE_DIR/src/libEGL/Surface.h
+ $$ANGLE_DIR/src/libEGL/resource.h
SOURCES += \
- $$ANGLE_DIR/src/libEGL/AttributeMap.cpp \
- $$ANGLE_DIR/src/libEGL/Config.cpp \
- $$ANGLE_DIR/src/libEGL/Display.cpp \
- $$ANGLE_DIR/src/libEGL/Error.cpp \
- $$ANGLE_DIR/src/libEGL/libEGL.cpp \
- $$ANGLE_DIR/src/libEGL/main.cpp \
- $$ANGLE_DIR/src/libEGL/Surface.cpp
-
-!winrt {
- SOURCES += \
- $$ANGLE_DIR/src/common/win32/NativeWindow.cpp
-} else {
- HEADERS += \
- $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.h \
- $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.h \
- $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.h
-
- SOURCES += \
- $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.cpp \
- $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.cpp \
- $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.cpp
-}
+ $$ANGLE_DIR/src/libEGL/libEGL.cpp
!static {
DEF_FILE = $$ANGLE_DIR/src/libEGL/$${TARGET}.def
diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro
index 705768d17d..a783318bb1 100644
--- a/src/angle/src/libGLESv2/libGLESv2.pro
+++ b/src/angle/src/libGLESv2/libGLESv2.pro
@@ -1,7 +1,7 @@
CONFIG += simd installed
include(../common/common.pri)
-INCLUDEPATH += $$OUT_PWD/.. $$ANGLE_DIR/src/libGLESv2
+INCLUDEPATH += $$OUT_PWD/.. $$ANGLE_DIR/src/libANGLE
# Remember to adapt tools/configure/configureapp.cpp if the Direct X version changes.
!winrt: \
@@ -20,237 +20,310 @@ for(libname, STATICLIBS) {
PRE_TARGETDEPS += $$staticlib
}
+DEFINES += LIBANGLE_IMPLEMENTATION LIBGLESV2_IMPLEMENTATION GL_APICALL= GL_GLEXT_PROTOTYPES= EGLAPI= ANGLE_ENABLE_D3D11
+!winrt: DEFINES += ANGLE_ENABLE_D3D9 ANGLE_SKIP_DXGI_1_2_CHECK
+
HEADERS += \
$$ANGLE_DIR/src/common/blocklayout.h \
+ $$ANGLE_DIR/src/common/NativeWindow.h \
$$ANGLE_DIR/src/common/shadervars.h \
$$ANGLE_DIR/src/common/utilities.h \
- $$ANGLE_DIR/src/common/NativeWindow.h \
- $$ANGLE_DIR/src/libGLESv2/angletypes.h \
- $$ANGLE_DIR/src/libGLESv2/BinaryStream.h \
- $$ANGLE_DIR/src/libGLESv2/Buffer.h \
- $$ANGLE_DIR/src/libGLESv2/Caps.h \
- $$ANGLE_DIR/src/libGLESv2/Context.h \
- $$ANGLE_DIR/src/libGLESv2/Data.h \
- $$ANGLE_DIR/src/libGLESv2/Error.h \
- $$ANGLE_DIR/src/libGLESv2/Fence.h \
- $$ANGLE_DIR/src/libGLESv2/formatutils.h \
- $$ANGLE_DIR/src/libGLESv2/Framebuffer.h \
- $$ANGLE_DIR/src/libGLESv2/FramebufferAttachment.h \
- $$ANGLE_DIR/src/libGLESv2/HandleAllocator.h \
- $$ANGLE_DIR/src/libGLESv2/ImageIndex.h \
- $$ANGLE_DIR/src/libGLESv2/main.h \
- $$ANGLE_DIR/src/libGLESv2/Program.h \
- $$ANGLE_DIR/src/libGLESv2/ProgramBinary.h \
- $$ANGLE_DIR/src/libGLESv2/Query.h \
- $$ANGLE_DIR/src/libGLESv2/queryconversions.h \
- $$ANGLE_DIR/src/libGLESv2/Renderbuffer.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/BufferImpl.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/copyimage.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/copyvertex.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/BufferD3D.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/DynamicHLSL.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/HLSLCompiler.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/ImageD3D.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/IndexBuffer.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/IndexDataManager.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/MemoryBuffer.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/ProgramD3D.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RenderbufferD3D.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RendererD3D.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/ShaderD3D.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureD3D.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureStorage.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/VertexArrayImpl.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/VertexBuffer.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/vertexconversion.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/VertexDataManager.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/FenceImpl.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/generatemip.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/Image.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/imageformats.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/IndexCacheRange.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/loadimage.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/ProgramImpl.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/QueryImpl.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/RenderbufferImpl.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/Renderer.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/RenderTarget.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/ShaderExecutable.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/ShaderImpl.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/SwapChain.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/TextureImpl.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/TextureFeedbackImpl.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/VertexDeclarationCache.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/Workarounds.h \
+ $$ANGLE_DIR/src/common/MemoryBuffer.h \
+ $$ANGLE_DIR/src/common/angleutils.h \
+ $$ANGLE_DIR/src/common/debug.h \
+ $$ANGLE_DIR/src/common/event_tracer.h \
+ $$ANGLE_DIR/src/libANGLE/angletypes.h \
+ $$ANGLE_DIR/src/libANGLE/AttributeMap.h \
+ $$ANGLE_DIR/src/libANGLE/BinaryStream.h \
+ $$ANGLE_DIR/src/libANGLE/Buffer.h \
+ $$ANGLE_DIR/src/libANGLE/Caps.h \
+ $$ANGLE_DIR/src/libANGLE/Compiler.h \
+ $$ANGLE_DIR/src/libANGLE/Config.h \
+ $$ANGLE_DIR/src/libANGLE/Constants.h \
+ $$ANGLE_DIR/src/libANGLE/Context.h \
+ $$ANGLE_DIR/src/libANGLE/Data.h \
+ $$ANGLE_DIR/src/libANGLE/Display.h \
+ $$ANGLE_DIR/src/libANGLE/Error.h \
+ $$ANGLE_DIR/src/libANGLE/features.h \
+ $$ANGLE_DIR/src/libANGLE/Fence.h \
+ $$ANGLE_DIR/src/libANGLE/formatutils.h \
+ $$ANGLE_DIR/src/libANGLE/Framebuffer.h \
+ $$ANGLE_DIR/src/libANGLE/FramebufferAttachment.h \
+ $$ANGLE_DIR/src/libANGLE/HandleAllocator.h \
+ $$ANGLE_DIR/src/libANGLE/ImageIndex.h \
+ $$ANGLE_DIR/src/libANGLE/Program.h \
+ $$ANGLE_DIR/src/libANGLE/Query.h \
+ $$ANGLE_DIR/src/libANGLE/queryconversions.h \
+ $$ANGLE_DIR/src/libANGLE/RefCountObject.h \
+ $$ANGLE_DIR/src/libANGLE/Renderbuffer.h \
+ $$ANGLE_DIR/src/libANGLE/ResourceManager.h \
+ $$ANGLE_DIR/src/libANGLE/Sampler.h \
+ $$ANGLE_DIR/src/libANGLE/Shader.h \
+ $$ANGLE_DIR/src/libANGLE/State.h \
+ $$ANGLE_DIR/src/libANGLE/Surface.h \
+ $$ANGLE_DIR/src/libANGLE/Texture.h \
+ $$ANGLE_DIR/src/libANGLE/TransformFeedback.h \
+ $$ANGLE_DIR/src/libANGLE/Uniform.h \
+ $$ANGLE_DIR/src/libANGLE/validationEGL.h \
+ $$ANGLE_DIR/src/libANGLE/validationES.h \
+ $$ANGLE_DIR/src/libANGLE/validationES2.h \
+ $$ANGLE_DIR/src/libANGLE/validationES3.h \
+ $$ANGLE_DIR/src/libANGLE/VertexArray.h \
+ $$ANGLE_DIR/src/libANGLE/VertexAttribute.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/BufferD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/CompilerD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/copyimage.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/DisplayD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/DynamicHLSL.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/formatutilsD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/FramebufferD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/generatemip.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/HLSLCompiler.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ImageD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/imageformats.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/IndexBuffer.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/IndexDataManager.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/loadimage.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ProgramD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/RenderbufferD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/RendererD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/RenderTargetD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ShaderD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/SurfaceD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/SwapChainD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/TextureD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/TextureStorage.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/VertexBuffer.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/VertexDataManager.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/BufferImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/CompilerImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/DisplayImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/FenceNVImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/FenceSyncImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/FramebufferImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/Image.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/ImplFactory.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/IndexRangeCache.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/ProgramImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/QueryImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/RenderbufferImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/Renderer.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/ShaderImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/SurfaceImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/TextureImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/TransformFeedbackImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/VertexArrayImpl.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/Workarounds.h \
+ $$ANGLE_DIR/src/libANGLE/resource.h \
+ $$ANGLE_DIR/src/libANGLE/ResourceManager.h \
+ $$ANGLE_DIR/src/libANGLE/Sampler.h \
+ $$ANGLE_DIR/src/libANGLE/Shader.h \
+ $$ANGLE_DIR/src/libANGLE/State.h \
+ $$ANGLE_DIR/src/libANGLE/Texture.h \
+ $$ANGLE_DIR/src/libANGLE/TransformFeedback.h \
+ $$ANGLE_DIR/src/libANGLE/Uniform.h \
+ $$ANGLE_DIR/src/libANGLE/validationES2.h \
+ $$ANGLE_DIR/src/libANGLE/validationES3.h \
+ $$ANGLE_DIR/src/libANGLE/validationES.h \
+ $$ANGLE_DIR/src/libANGLE/VertexArray.h \
+ $$ANGLE_DIR/src/libANGLE/VertexAttribute.h \
+ $$ANGLE_DIR/src/libANGLE/vertexconversion.h \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_egl.h \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_egl_ext.h \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_gles_2_0.h \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_gles_2_0_ext.h \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_gles_3_0.h \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_gles_3_0_ext.h \
+ $$ANGLE_DIR/src/libGLESv2/global_state.h \
$$ANGLE_DIR/src/libGLESv2/resource.h \
- $$ANGLE_DIR/src/libGLESv2/ResourceManager.h \
- $$ANGLE_DIR/src/libGLESv2/Sampler.h \
- $$ANGLE_DIR/src/libGLESv2/Shader.h \
- $$ANGLE_DIR/src/libGLESv2/State.h \
- $$ANGLE_DIR/src/libGLESv2/Texture.h \
- $$ANGLE_DIR/src/libGLESv2/TransformFeedback.h \
- $$ANGLE_DIR/src/libGLESv2/Uniform.h \
- $$ANGLE_DIR/src/libGLESv2/validationES.h \
- $$ANGLE_DIR/src/libGLESv2/validationES2.h \
- $$ANGLE_DIR/src/libGLESv2/validationES3.h \
- $$ANGLE_DIR/src/libGLESv2/VertexArray.h \
- $$ANGLE_DIR/src/libGLESv2/VertexAttribute.h \
- $$ANGLE_DIR/src/libGLESv2/vertexconversion.h \
- $$ANGLE_DIR/src/third_party/murmurhash/MurmurHash3.h \
+ $$ANGLE_DIR/src/third_party/murmurhash/MurmurHash3.h
SOURCES += \
- $$ANGLE_DIR/src/common/blocklayout.cpp \
$$ANGLE_DIR/src/common/mathutil.cpp \
$$ANGLE_DIR/src/common/utilities.cpp \
+ $$ANGLE_DIR/src/common/MemoryBuffer.cpp \
+ $$ANGLE_DIR/src/common/angleutils.cpp \
+ $$ANGLE_DIR/src/common/debug.cpp \
+ $$ANGLE_DIR/src/common/event_tracer.cpp \
$$ANGLE_DIR/src/third_party/murmurhash/MurmurHash3.cpp \
- $$ANGLE_DIR/src/libGLESv2/angletypes.cpp \
- $$ANGLE_DIR/src/libGLESv2/Buffer.cpp \
- $$ANGLE_DIR/src/libGLESv2/Caps.cpp \
- $$ANGLE_DIR/src/libGLESv2/Context.cpp \
- $$ANGLE_DIR/src/libGLESv2/Data.cpp \
- $$ANGLE_DIR/src/libGLESv2/Error.cpp \
- $$ANGLE_DIR/src/libGLESv2/Fence.cpp \
- $$ANGLE_DIR/src/libGLESv2/Float16ToFloat32.cpp \
- $$ANGLE_DIR/src/libGLESv2/Framebuffer.cpp \
- $$ANGLE_DIR/src/libGLESv2/FramebufferAttachment.cpp \
- $$ANGLE_DIR/src/libGLESv2/formatutils.cpp \
- $$ANGLE_DIR/src/libGLESv2/HandleAllocator.cpp \
- $$ANGLE_DIR/src/libGLESv2/ImageIndex.cpp \
- $$ANGLE_DIR/src/libGLESv2/libGLESv2.cpp \
- $$ANGLE_DIR/src/libGLESv2/main.cpp \
- $$ANGLE_DIR/src/libGLESv2/Program.cpp \
- $$ANGLE_DIR/src/libGLESv2/ProgramBinary.cpp \
- $$ANGLE_DIR/src/libGLESv2/Query.cpp \
- $$ANGLE_DIR/src/libGLESv2/queryconversions.cpp \
- $$ANGLE_DIR/src/libGLESv2/Renderbuffer.cpp \
- $$ANGLE_DIR/src/libGLESv2/ResourceManager.cpp \
- $$ANGLE_DIR/src/libGLESv2/Sampler.cpp \
- $$ANGLE_DIR/src/libGLESv2/Shader.cpp \
- $$ANGLE_DIR/src/libGLESv2/State.cpp \
- $$ANGLE_DIR/src/libGLESv2/Texture.cpp \
- $$ANGLE_DIR/src/libGLESv2/TransformFeedback.cpp \
- $$ANGLE_DIR/src/libGLESv2/Uniform.cpp \
- $$ANGLE_DIR/src/libGLESv2/validationES.cpp \
- $$ANGLE_DIR/src/libGLESv2/validationES2.cpp \
- $$ANGLE_DIR/src/libGLESv2/validationES3.cpp \
- $$ANGLE_DIR/src/libGLESv2/VertexArray.cpp \
- $$ANGLE_DIR/src/libGLESv2/VertexAttribute.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/copyimage.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/loadimage.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/Image.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/IndexRangeCache.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/ProgramImpl.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/RenderbufferImpl.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/Renderer.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/RenderTarget.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/BufferD3D.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/ImageD3D.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/IndexBuffer.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/IndexDataManager.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/MemoryBuffer.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/ProgramD3D.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/RendererD3D.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/ShaderD3D.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureD3D.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/TextureStorage.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/TransformFeedbackD3D.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/VertexBuffer.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/VertexDataManager.cpp
+ $$ANGLE_DIR/src/libANGLE/angletypes.cpp \
+ $$ANGLE_DIR/src/libANGLE/AttributeMap.cpp \
+ $$ANGLE_DIR/src/libANGLE/Buffer.cpp \
+ $$ANGLE_DIR/src/libANGLE/Caps.cpp \
+ $$ANGLE_DIR/src/libANGLE/Compiler.cpp \
+ $$ANGLE_DIR/src/libANGLE/Config.cpp \
+ $$ANGLE_DIR/src/libANGLE/Context.cpp \
+ $$ANGLE_DIR/src/libANGLE/Data.cpp \
+ $$ANGLE_DIR/src/libANGLE/Display.cpp \
+ $$ANGLE_DIR/src/libANGLE/Error.cpp \
+ $$ANGLE_DIR/src/libANGLE/Fence.cpp \
+ $$ANGLE_DIR/src/libANGLE/Float16ToFloat32.cpp \
+ $$ANGLE_DIR/src/libANGLE/formatutils.cpp \
+ $$ANGLE_DIR/src/libANGLE/Framebuffer.cpp \
+ $$ANGLE_DIR/src/libANGLE/FramebufferAttachment.cpp \
+ $$ANGLE_DIR/src/libANGLE/HandleAllocator.cpp \
+ $$ANGLE_DIR/src/libANGLE/ImageIndex.cpp \
+ $$ANGLE_DIR/src/libANGLE/Platform.cpp \
+ $$ANGLE_DIR/src/libANGLE/Program.cpp \
+ $$ANGLE_DIR/src/libANGLE/Query.cpp \
+ $$ANGLE_DIR/src/libANGLE/queryconversions.cpp \
+ $$ANGLE_DIR/src/libANGLE/RefCountObject.cpp \
+ $$ANGLE_DIR/src/libANGLE/Renderbuffer.cpp \
+ $$ANGLE_DIR/src/libANGLE/ResourceManager.cpp \
+ $$ANGLE_DIR/src/libANGLE/Sampler.cpp \
+ $$ANGLE_DIR/src/libANGLE/Shader.cpp \
+ $$ANGLE_DIR/src/libANGLE/State.cpp \
+ $$ANGLE_DIR/src/libANGLE/Surface.cpp \
+ $$ANGLE_DIR/src/libANGLE/Texture.cpp \
+ $$ANGLE_DIR/src/libANGLE/TransformFeedback.cpp \
+ $$ANGLE_DIR/src/libANGLE/Uniform.cpp \
+ $$ANGLE_DIR/src/libANGLE/validationEGL.cpp \
+ $$ANGLE_DIR/src/libANGLE/validationES.cpp \
+ $$ANGLE_DIR/src/libANGLE/validationES2.cpp \
+ $$ANGLE_DIR/src/libANGLE/validationES3.cpp \
+ $$ANGLE_DIR/src/libANGLE/VertexArray.cpp \
+ $$ANGLE_DIR/src/libANGLE/VertexAttribute.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/DisplayImpl.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/IndexRangeCache.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/ProgramImpl.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/RenderbufferImpl.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/Renderer.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/SurfaceImpl.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/BufferD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/CompilerD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/copyimage.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/DisplayD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/DynamicHLSL.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/formatutilsD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/FramebufferD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/HLSLCompiler.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ImageD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/IndexBuffer.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/IndexDataManager.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/loadimage.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/loadimageSSE2.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ProgramD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/RendererD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ShaderD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/SurfaceD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/TextureD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/TextureStorage.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/VertexBuffer.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/VertexDataManager.cpp \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_egl.cpp \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_egl_ext.cpp \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_gles_2_0.cpp \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_gles_2_0_ext.cpp \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_gles_3_0.cpp \
+ $$ANGLE_DIR/src/libGLESv2/entry_points_gles_3_0_ext.cpp \
+ $$ANGLE_DIR/src/libGLESv2/global_state.cpp \
+ $$ANGLE_DIR/src/libGLESv2/libGLESv2.cpp
+
angle_d3d11 {
HEADERS += \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Blit11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Clear11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Fence11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/formatutils11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Image11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Query11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Blit11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Buffer11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Clear11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Fence11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/formatutils11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Image11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Query11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Renderer11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Trim11.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
SOURCES += \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Image11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Query11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
}
-SSE2_SOURCES += $$ANGLE_DIR/src/libGLESv2/renderer/loadimageSSE2.cpp
-
!winrt {
HEADERS += \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Blit9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Fence9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/formatutils9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Image9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Query9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Blit9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Buffer9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Fence9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/formatutils9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Image9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Query9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Renderer9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h \
$$ANGLE_DIR/src/third_party/systeminfo/SystemInfo.h
SOURCES += \
- $$ANGLE_DIR/src/common/win32/NativeWindow.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/formatutils9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/ShaderExecutable9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp \
- $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/VertexDeclarationCache.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Image9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Query9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp \
$$ANGLE_DIR/src/third_party/systeminfo/SystemInfo.cpp
} else {
HEADERS += \
- $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.h \
- $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.h \
- $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.h
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
SOURCES += \
- $$ANGLE_DIR/src/common/winrt/CoreWindowNativeWindow.cpp \
- $$ANGLE_DIR/src/common/winrt/InspectableNativeWindow.cpp \
- $$ANGLE_DIR/src/common/winrt/SwapChainPanelNativeWindow.cpp
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp \
+ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
}
!static {
@@ -259,87 +332,234 @@ SSE2_SOURCES += $$ANGLE_DIR/src/libGLESv2/renderer/loadimageSSE2.cpp
}
float_converter.target = float_converter
-float_converter.commands = python $$ANGLE_DIR/src/libGLESv2/Float16ToFloat32.py \
- > $$ANGLE_DIR/src/libGLESv2/Float16ToFloat32.cpp
+float_converter.commands = python $$ANGLE_DIR/src/libANGLE/Float16ToFloat32.py \
+ > $$ANGLE_DIR/src/libANGLE/Float16ToFloat32.cpp
QMAKE_EXTRA_TARGETS += float_converter
-# Generate the shader header files.
-SHADER9_INPUT_DIR = $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d9/shaders
-SHADER11_INPUT_DIR = $$ANGLE_DIR/src/libGLESv2/renderer/d3d/d3d11/shaders
+# HLSL shaders
+BLITVS = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs
+standardvs.input = BLITVS
+standardvs.type = vs_2_0
+standardvs.output = standardvs.h
+flipyvs.input = BLITVS
+flipyvs.type = vs_2_0
+flipyvs.output = flipyvs.h
+
+BLITPS = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps
+passthroughps.input = BLITPS
+passthroughps.type = ps_2_0
+passthroughps.output = passthroughps.h
+luminanceps.input = BLITPS
+luminanceps.type = ps_2_0
+luminanceps.output = luminanceps.h
+componentmaskps.input = BLITPS
+componentmaskps.type = ps_2_0
+componentmaskps.output = componentmaskps.h
-BLITPS_INPUT = $$SHADER9_INPUT_DIR/Blit.ps
-BLITPS.shaders = PS_passthrough PS_luminance PS_componentmask
-BLITPS.profile = 2_0
+PASSTHROUGH2D = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl
+VS_Passthrough2D.input = PASSTHROUGH2D
+VS_Passthrough2D.type = vs_4_0_level_9_3
+VS_Passthrough2D.output = passthrough2d11vs.h
+PS_PassthroughRGBA2D.input = PASSTHROUGH2D
+PS_PassthroughRGBA2D.type = ps_4_0_level_9_3
+PS_PassthroughRGBA2D.output = passthroughrgba2d11ps.h
+PS_PassthroughRGB2D.input = PASSTHROUGH2D
+PS_PassthroughRGB2D.type = ps_4_0_level_9_3
+PS_PassthroughRGB2D.output = passthroughrgb2d11ps.h
+PS_PassthroughRG2D.input = PASSTHROUGH2D
+PS_PassthroughRG2D.type = ps_4_0_level_9_3
+PS_PassthroughRG2D.output = passthroughrg2d11ps.h
+PS_PassthroughR2D.input = PASSTHROUGH2D
+PS_PassthroughR2D.type = ps_4_0_level_9_3
+PS_PassthroughR2D.output = passthroughr2d11ps.h
+PS_PassthroughLum2D.input = PASSTHROUGH2D
+PS_PassthroughLum2D.type = ps_4_0_level_9_3
+PS_PassthroughLum2D.output = passthroughlum2d11ps.h
+PS_PassthroughLumAlpha2D.input = PASSTHROUGH2D
+PS_PassthroughLumAlpha2D.type = ps_4_0_level_9_3
+PS_PassthroughLumAlpha2D.output = passthroughlumalpha2d11ps.h
+PS_PassthroughDepth2D.input = PASSTHROUGH2D
+PS_PassthroughDepth2D.type = ps_4_0
+PS_PassthroughDepth2D.output = passthroughdepth2d11ps.h
+PS_PassthroughRGBA2DUI.input = PASSTHROUGH2D
+PS_PassthroughRGBA2DUI.type = ps_4_0
+PS_PassthroughRGBA2DUI.output = passthroughrgba2dui11ps.h
+PS_PassthroughRGBA2DI.input = PASSTHROUGH2D
+PS_PassthroughRGBA2DI.type = ps_4_0
+PS_PassthroughRGBA2DI.output = passthroughrgba2di11ps.h
+PS_PassthroughRGB2DUI.input = PASSTHROUGH2D
+PS_PassthroughRGB2DUI.type = ps_4_0
+PS_PassthroughRGB2DUI.output = passthroughrgb2dui11ps.h
+PS_PassthroughRGB2DI.input = PASSTHROUGH2D
+PS_PassthroughRGB2DI.type = ps_4_0
+PS_PassthroughRGB2DI.output = passthroughrgb2di11ps.h
+PS_PassthroughRG2DUI.input = PASSTHROUGH2D
+PS_PassthroughRG2DUI.type = ps_4_0
+PS_PassthroughRG2DUI.output = passthroughrg2dui11ps.h
+PS_PassthroughRG2DI.input = PASSTHROUGH2D
+PS_PassthroughRG2DI.type = ps_4_0
+PS_PassthroughRG2DI.output = passthroughrg2di11ps.h
+PS_PassthroughR2DUI.input = PASSTHROUGH2D
+PS_PassthroughR2DUI.type = ps_4_0
+PS_PassthroughR2DUI.output = passthroughr2dui11ps.h
+PS_PassthroughR2DI.input = PASSTHROUGH2D
+PS_PassthroughR2DI.type = ps_4_0
+PS_PassthroughR2DI.output = passthroughr2di11ps.h
-BLITVS_INPUT = $$SHADER9_INPUT_DIR/Blit.vs
-BLITVS.shaders = VS_standard VS_flipy
-BLITVS.profile = 2_0
+CLEAR = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/shaders/Clear11.hlsl
+VS_ClearFloat.input = CLEAR
+VS_ClearFloat.type = vs_4_0_level_9_3
+VS_ClearFloat.output = clearfloat11vs.h
+PS_ClearFloat_FL9.input = CLEAR
+PS_ClearFloat_FL9.type = ps_4_0_level_9_3
+PS_ClearFloat_FL9.output = clearfloat11_fl9ps.h
+PS_ClearFloat.input = CLEAR
+PS_ClearFloat.type = ps_4_0
+PS_ClearFloat.output = clearfloat11ps.h
+VS_ClearUint.input = CLEAR
+VS_ClearUint.type = vs_4_0
+VS_ClearUint.output = clearuint11vs.h
+PS_ClearUint.input = CLEAR
+PS_ClearUint.type = ps_4_0
+PS_ClearUint.output = clearuint11ps.h
+VS_ClearSint.input = CLEAR
+VS_ClearSint.type = vs_4_0
+VS_ClearSint.output = clearsint11vs.h
+PS_ClearSint.input = CLEAR
+PS_ClearSint.type = ps_4_0
+PS_ClearSint.output = clearsint11ps.h
-BUFFERTOTEXTURE_INPUT = $$SHADER11_INPUT_DIR/BufferToTexture11.hlsl
-BUFFERTOTEXTURE.shaders = \
- PS_BufferToTexture_4F PS_BufferToTexture_4I PS_BufferToTexture_4UI \
- VS_BufferToTexture GS_BufferToTexture
-BUFFERTOTEXTURE.profile = 4_0
+PASSTHROUGH3D = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough3D11.hlsl
+VS_Passthrough3D.input = PASSTHROUGH3D
+VS_Passthrough3D.type = vs_4_0
+VS_Passthrough3D.output = passthrough3d11vs.h
+GS_Passthrough3D.input = PASSTHROUGH3D
+GS_Passthrough3D.type = gs_4_0
+GS_Passthrough3D.output = passthrough3d11gs.h
+PS_PassthroughRGBA3D.input = PASSTHROUGH3D
+PS_PassthroughRGBA3D.type = ps_4_0
+PS_PassthroughRGBA3D.output = passthroughrgba3d11ps.h
+PS_PassthroughRGBA3DUI.input = PASSTHROUGH3D
+PS_PassthroughRGBA3DUI.type = ps_4_0
+PS_PassthroughRGBA3DUI.output = passthroughrgba3dui11ps.h
+PS_PassthroughRGBA3DI.input = PASSTHROUGH3D
+PS_PassthroughRGBA3DI.type = ps_4_0
+PS_PassthroughRGBA3DI.output = passthroughrgba3di11ps.h
+PS_PassthroughRGB3D.input = PASSTHROUGH3D
+PS_PassthroughRGB3D.type = ps_4_0
+PS_PassthroughRGB3D.output = passthroughrgb3d11ps.h
+PS_PassthroughRGB3DUI.input = PASSTHROUGH3D
+PS_PassthroughRGB3DUI.type = ps_4_0
+PS_PassthroughRGB3DUI.output = passthroughrgb3dui11ps.h
+PS_PassthroughRGB3DI.input = PASSTHROUGH3D
+PS_PassthroughRGB3DI.type = ps_4_0
+PS_PassthroughRGB3DI.output = passthroughrgb3di11ps.h
+PS_PassthroughRG3D.input = PASSTHROUGH3D
+PS_PassthroughRG3D.type = ps_4_0
+PS_PassthroughRG3D.output = passthroughrg3d11ps.h
+PS_PassthroughRG3DUI.input = PASSTHROUGH3D
+PS_PassthroughRG3DUI.type = ps_4_0
+PS_PassthroughRG3DUI.output = passthroughrg3dui11ps.h
+PS_PassthroughRG3DI.input = PASSTHROUGH3D
+PS_PassthroughRG3DI.type = ps_4_0
+PS_PassthroughRG3DI.output = passthroughrg3di11ps.h
+PS_PassthroughR3D.input = PASSTHROUGH3D
+PS_PassthroughR3D.type = ps_4_0
+PS_PassthroughR3D.output = passthroughr3d11ps.h
+PS_PassthroughR3DUI.input = PASSTHROUGH3D
+PS_PassthroughR3DUI.type = ps_4_0
+PS_PassthroughR3DUI.output = passthroughr3dui11ps.h
+PS_PassthroughR3DI.input = PASSTHROUGH3D
+PS_PassthroughR3DI.type = ps_4_0
+PS_PassthroughR3DI.output = passthroughr3di11ps.h
+PS_PassthroughLum3D.input = PASSTHROUGH3D
+PS_PassthroughLum3D.type = ps_4_0
+PS_PassthroughLum3D.output = passthroughlum3d11ps.h
+PS_PassthroughLumAlpha3D.input = PASSTHROUGH3D
+PS_PassthroughLumAlpha3D.type = ps_4_0
+PS_PassthroughLumAlpha3D.output = passthroughlumalpha3d11ps.h
-CLEAR_INPUT = $$SHADER11_INPUT_DIR/Clear11.hlsl
-CLEAR.shaders = \
- PS_ClearUint PS_ClearSint \
- VS_ClearUint VS_ClearSint
-CLEAR.shaders_compat = PS_ClearFloat VS_ClearFloat
-CLEAR.profile = 4_0
+SWIZZLE = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/shaders/Swizzle11.hlsl
+PS_SwizzleF2D.input = SWIZZLE
+PS_SwizzleF2D.type = ps_4_0
+PS_SwizzleF2D.output = swizzlef2dps.h
+PS_SwizzleI2D.input = SWIZZLE
+PS_SwizzleI2D.type = ps_4_0
+PS_SwizzleI2D.output = swizzlei2dps.h
+PS_SwizzleUI2D.input = SWIZZLE
+PS_SwizzleUI2D.type = ps_4_0
+PS_SwizzleUI2D.output = swizzleui2dps.h
+PS_SwizzleF3D.input = SWIZZLE
+PS_SwizzleF3D.type = ps_4_0
+PS_SwizzleF3D.output = swizzlef3dps.h
+PS_SwizzleI3D.input = SWIZZLE
+PS_SwizzleI3D.type = ps_4_0
+PS_SwizzleI3D.output = swizzlei3dps.h
+PS_SwizzleUI3D.input = SWIZZLE
+PS_SwizzleUI3D.type = ps_4_0
+PS_SwizzleUI3D.output = swizzleui3dps.h
+PS_SwizzleF2DArray.input = SWIZZLE
+PS_SwizzleF2DArray.type = ps_4_0
+PS_SwizzleF2DArray.output = swizzlef2darrayps.h
+PS_SwizzleI2DArray.input = SWIZZLE
+PS_SwizzleI2DArray.type = ps_4_0
+PS_SwizzleI2DArray.output = swizzlei2darrayps.h
+PS_SwizzleUI2DArray.input = SWIZZLE
+PS_SwizzleUI2DArray.type = ps_4_0
+PS_SwizzleUI2DArray.output = swizzleui2darrayps.h
-PASSTHROUGH2D_INPUT = $$SHADER11_INPUT_DIR/Passthrough2D11.hlsl
-PASSTHROUGH2D.shaders = \
- PS_PassthroughRGBA2DUI PS_PassthroughRGBA2DI \
- PS_PassthroughRGB2DUI PS_PassthroughRGB2DI \
- PS_PassthroughRG2DUI PS_PassthroughRG2DI \
- PS_PassthroughR2DUI PS_PassthroughR2DI \
- PS_PassthroughDepth2D
-PASSTHROUGH2D.shaders_compat = \
- PS_PassthroughRGBA2D PS_PassthroughRGB2D \
- PS_PassthroughRG2D PS_PassthroughR2D \
- PS_PassthroughLum2D PS_PassthroughLumAlpha2D \
- VS_Passthrough2D
-PASSTHROUGH2D.profile = 4_0
+BUFFERTOTEXTURE = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/shaders/BufferToTexture11.hlsl
+VS_BufferToTexture.input = BUFFERTOTEXTURE
+VS_BufferToTexture.type = vs_4_0
+VS_BufferToTexture.output = buffertotexture11_vs.h
+GS_BufferToTexture.input = BUFFERTOTEXTURE
+GS_BufferToTexture.type = gs_4_0
+GS_BufferToTexture.output = buffertotexture11_gs.h
+PS_BufferToTexture_4F.input = BUFFERTOTEXTURE
+PS_BufferToTexture_4F.type = ps_4_0
+PS_BufferToTexture_4F.output = buffertotexture11_ps_4f.h
+PS_BufferToTexture_4I.input = BUFFERTOTEXTURE
+PS_BufferToTexture_4I.type = ps_4_0
+PS_BufferToTexture_4I.output = buffertotexture11_ps_4i.h
+PS_BufferToTexture_4UI.input = BUFFERTOTEXTURE
+PS_BufferToTexture_4UI.type = ps_4_0
+PS_BufferToTexture_4UI.output = buffertotexture11_ps_4ui.h
-PASSTHROUGH3D_INPUT = $$SHADER11_INPUT_DIR/Passthrough3D11.hlsl
-PASSTHROUGH3D.shaders = \
+# D3D11
+angle_d3d11: SHADERS = VS_Passthrough2D \
+ PS_PassthroughRGB2D PS_PassthroughRGB2DUI PS_PassthroughRGB2DI \
+ PS_PassthroughRGBA2D PS_PassthroughRGBA2DUI PS_PassthroughRGBA2DI \
+ PS_PassthroughRG2D PS_PassthroughRG2DUI PS_PassthroughRG2DI \
+ PS_PassthroughR2D PS_PassthroughR2DUI PS_PassthroughR2DI \
+ PS_PassthroughLum2D PS_PassthroughLumAlpha2D PS_PassthroughDepth2D \
+ VS_ClearFloat VS_ClearUint VS_ClearSint \
+ PS_ClearFloat PS_ClearFloat_FL9 PS_ClearUint PS_ClearSint \
+ VS_Passthrough3D GS_Passthrough3D \
PS_PassthroughRGBA3D PS_PassthroughRGBA3DUI PS_PassthroughRGBA3DI \
PS_PassthroughRGB3D PS_PassthroughRGB3DUI PS_PassthroughRGB3DI \
PS_PassthroughRG3D PS_PassthroughRG3DUI PS_PassthroughRG3DI \
PS_PassthroughR3D PS_PassthroughR3DUI PS_PassthroughR3DI \
PS_PassthroughLum3D PS_PassthroughLumAlpha3D \
- VS_Passthrough3D GS_Passthrough3D
-PASSTHROUGH3D.profile = 4_0
-
-SWIZZLE_INPUT = $$SHADER11_INPUT_DIR/Swizzle11.hlsl
-SWIZZLE.shaders = \
- PS_SwizzleI2D PS_SwizzleUI2D \
+ PS_SwizzleF2D PS_SwizzleI2D PS_SwizzleUI2D \
PS_SwizzleF3D PS_SwizzleI3D PS_SwizzleUI3D \
- PS_SwizzleF2DArray PS_SwizzleI2DArray PS_SwizzleUI2DArray
-SWIZZLE.shaders_compat = PS_SwizzleF2D
-SWIZZLE.profile = 4_0
+ PS_SwizzleF2DArray PS_SwizzleI2DArray PS_SwizzleUI2DArray \
+ VS_BufferToTexture GS_BufferToTexture \
+ PS_BufferToTexture_4F PS_BufferToTexture_4I PS_BufferToTexture_4UI
-angle_d3d11: FXC_JOBS = BUFFERTOTEXTURE CLEAR PASSTHROUGH2D PASSTHROUGH3D SWIZZLE
-!winrt: FXC_JOBS += BLITPS BLITVS
+# D3D9
+!winrt: SHADERS += standardvs flipyvs passthroughps luminanceps componentmaskps
-for (JOB, FXC_JOBS) {
- INPUT = $${JOB}_INPUT
- OUT_DIR = $$OUT_PWD/$$relative_path($$dirname($$INPUT), $$ANGLE_DIR/src/libGLESv2)/compiled
- SHADERS_COMPAT = $$eval($${JOB}.shaders_compat)
- SHADERS = $$eval($${JOB}.shaders) $$SHADERS_COMPAT
- for(SHADER, SHADERS) {
- TYPE = $$lower($$section(SHADER, _, 0, 0))
- PROFILE = $${TYPE}_$$eval($${JOB}.profile)
- contains(SHADERS_COMPAT, $$SHADER): PROFILE = $${PROFILE}_level_9_1
- fxc_$${SHADER}_$${PROFILE}.commands = $$FXC /nologo /E $${SHADER} /T $${PROFILE} /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
- fxc_$${SHADER}_$${PROFILE}.output = $$OUT_DIR/$$section(SHADER, _, 1)$${TYPE}.h
- fxc_$${SHADER}_$${PROFILE}.input = $$INPUT
- fxc_$${SHADER}_$${PROFILE}.dependency_type = TYPE_C
- fxc_$${SHADER}_$${PROFILE}.variable_out = HEADERS
- fxc_$${SHADER}_$${PROFILE}.CONFIG += target_predeps
- QMAKE_EXTRA_COMPILERS += fxc_$${SHADER}_$${PROFILE}
- }
+# Generate headers
+for (SHADER, SHADERS) {
+ INPUT = $$eval($${SHADER}.input)
+ OUT_DIR = $$OUT_PWD/libANGLE/$$relative_path($$dirname($$INPUT), $$ANGLE_DIR/src/libANGLE)/compiled
+ fxc_$${SHADER}.commands = $$FXC /nologo /E $${SHADER} /T $$eval($${SHADER}.type) /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_$${SHADER}.output = $$OUT_DIR/$$eval($${SHADER}.output)
+ fxc_$${SHADER}.input = $$INPUT
+ fxc_$${SHADER}.dependency_type = TYPE_C
+ fxc_$${SHADER}.variable_out = HEADERS
+ fxc_$${SHADER}.CONFIG += target_predeps
+ QMAKE_EXTRA_COMPILERS += fxc_$${SHADER}
}
khr_headers.files = $$ANGLE_DIR/include/KHR/khrplatform.h