summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/3rdparty/angle/AUTHORS2
-rw-r--r--src/3rdparty/angle/CONTRIBUTORS5
-rw-r--r--src/3rdparty/angle/include/EGL/egl.h2
-rw-r--r--src/3rdparty/angle/include/EGL/eglext.h16
-rw-r--r--src/3rdparty/angle/include/EGL/eglplatform.h19
-rw-r--r--src/3rdparty/angle/include/GLSLANG/ShaderLang.h210
-rw-r--r--src/3rdparty/angle/include/GLSLANG/ShaderVars.h64
-rw-r--r--src/3rdparty/angle/include/angle_windowsstore.h37
-rw-r--r--src/3rdparty/angle/src/commit.h4
-rw-r--r--src/3rdparty/angle/src/common/NativeWindow.h77
-rw-r--r--src/3rdparty/angle/src/common/angleutils.cpp25
-rw-r--r--src/3rdparty/angle/src/common/angleutils.h11
-rw-r--r--src/3rdparty/angle/src/common/debug.cpp242
-rw-r--r--src/3rdparty/angle/src/common/debug.h19
-rw-r--r--src/3rdparty/angle/src/common/features.h35
-rw-r--r--src/3rdparty/angle/src/common/mathutil.h4
-rw-r--r--src/3rdparty/angle/src/common/platform.h89
-rw-r--r--src/3rdparty/angle/src/common/tls.cpp107
-rw-r--r--src/3rdparty/angle/src/common/tls.h17
-rw-r--r--src/3rdparty/angle/src/common/utilities.cpp89
-rw-r--r--src/3rdparty/angle/src/common/utilities.h6
-rw-r--r--src/3rdparty/angle/src/common/win32/NativeWindow.cpp66
-rw-r--r--src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp200
-rw-r--r--src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h39
-rw-r--r--src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp274
-rw-r--r--src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h91
-rw-r--r--src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp226
-rw-r--r--src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h79
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h3
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp35
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp4
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Compiler.cpp63
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Compiler.h10
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp52
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h19
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp79
-rw-r--r--src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h3
-rw-r--r--src/3rdparty/angle/src/compiler/translator/IntermNode.cpp76
-rw-r--r--src/3rdparty/angle/src/compiler/translator/IntermNode.h5
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Intermediate.cpp1
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp18
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp57
-rw-r--r--src/3rdparty/angle/src/compiler/translator/OutputHLSL.h1
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ParseContext.cpp13
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ParseContext.h2
-rw-r--r--src/3rdparty/angle/src/compiler/translator/Pragma.h12
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp371
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp165
-rw-r--r--src/3rdparty/angle/src/compiler/translator/SymbolTable.h41
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp11
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp30
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h12
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp1
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp81
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VariableInfo.h17
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp16
-rw-r--r--src/3rdparty/angle/src/compiler/translator/VersionGLSL.h4
-rw-r--r--src/3rdparty/angle/src/compiler/translator/glslang.y34
-rw-r--r--src/3rdparty/angle/src/compiler/translator/intermOut.cpp6
-rw-r--r--src/3rdparty/angle/src/compiler/translator/util.cpp47
-rw-r--r--src/3rdparty/angle/src/compiler/translator/util.h12
-rw-r--r--src/3rdparty/angle/src/libEGL/AttributeMap.cpp40
-rw-r--r--src/3rdparty/angle/src/libEGL/AttributeMap.h33
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.cpp169
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.h22
-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.cpp339
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.h60
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGL.cpp465
-rw-r--r--src/3rdparty/angle/src/libEGL/main.cpp40
-rw-r--r--src/3rdparty/angle/src/libEGL/main.h22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/BinaryStream.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Buffer.h1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Context.cpp865
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Context.h62
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Data.cpp51
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Data.h38
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Fence.cpp176
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Fence.h35
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp277
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Framebuffer.h50
-rw-r--r--src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp91
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ImageIndex.h29
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Program.cpp24
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Program.h5
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp2080
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ProgramBinary.h133
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp235
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Renderbuffer.h113
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp16
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ResourceManager.h7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Shader.cpp10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Shader.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/State.cpp125
-rw-r--r--src/3rdparty/angle/src/libGLESv2/State.h26
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Texture.cpp199
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Texture.h74
-rw-r--r--src/3rdparty/angle/src/libGLESv2/VertexArray.h5
-rw-r--r--src/3rdparty/angle/src/libGLESv2/angletypes.cpp21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/angletypes.h16
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp1045
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.cpp99
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.h21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferImpl.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h36
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image.h25
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.cpp146
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ProgramImpl.h127
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.cpp36
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h41
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.cpp21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderbufferImpl.h41
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp45
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h237
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h13
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderImpl.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h25
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureImpl.h24
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Workarounds.h39
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/copyimage.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.cpp12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/BufferD3D.h17
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp68
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/DynamicHLSL.h35
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp245
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.h28
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.cpp4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ImageD3D.h15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.cpp8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexBuffer.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.cpp24
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/IndexDataManager.h6
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.cpp1814
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ProgramD3D.h184
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.cpp108
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RenderbufferD3D.h51
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp796
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h195
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.cpp118
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/ShaderD3D.h22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.cpp1711
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureD3D.h227
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.cpp18
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/TextureStorage.h21
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.cpp12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexBuffer.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.cpp36
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/VertexDataManager.h13
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.cpp108
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Blit11.h38
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp88
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.cpp19
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Clear11.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.cpp214
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Fence11.h48
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.cpp549
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Image11.h40
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/InputLayoutCache.cpp14
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.cpp116
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.cpp3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Query11.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.cpp15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderStateCache.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.cpp327
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/RenderTarget11.h84
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp1298
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h152
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp169
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h10
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.cpp1817
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/TextureStorage11.h177
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexArray11.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.cpp13
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/formatutils11.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.cpp94
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/renderer11_utils.h6
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.cpp227
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Blit9.h32
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp13
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.cpp63
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Fence9.h19
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.cpp654
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Image9.h43
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/IndexBuffer9.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Query9.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.cpp165
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/RenderTarget9.h60
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp756
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h134
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/ShaderCache.h12
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp26
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.cpp377
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/TextureStorage9.h46
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexArray9.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.cpp16
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/VertexBuffer9.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.cpp28
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/renderer9_utils.h5
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/loadimageSSE2.cpp18
-rw-r--r--src/3rdparty/angle/src/libGLESv2/validationES.cpp66
-rw-r--r--src/3rdparty/angle/src/libGLESv2/validationES3.cpp23
-rw-r--r--src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp5
-rw-r--r--src/angle/patches/0000-General-fixes-for-ANGLE-2.1.patch1194
-rw-r--r--src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch31
-rw-r--r--src/angle/patches/0002-Fix-compilation-of-ANGLE-with-mingw-tdm64-gcc-4.8.1.patch33
-rw-r--r--src/angle/patches/0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch31
-rw-r--r--src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch84
-rw-r--r--src/angle/patches/0006-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch49
-rw-r--r--src/angle/patches/0007-Fix-ANGLE-build-with-Microsoft-Visual-Studio-14-CTP.patch28
-rw-r--r--src/angle/patches/0008-ANGLE-Dynamically-load-D3D-compiler-from-a-list-or-t.patch37
-rw-r--r--src/angle/patches/0009-ANGLE-Support-WinRT.patch1769
-rw-r--r--src/angle/patches/0010-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch266
-rw-r--r--src/angle/patches/0012-ANGLE-fix-semantic-index-lookup.patch16
-rw-r--r--src/angle/patches/0013-ANGLE-Add-support-for-querying-platform-device.patch31
-rw-r--r--src/angle/patches/0014-Let-ANGLE-use-multithreaded-devices-if-necessary.patch37
-rw-r--r--src/angle/patches/0015-ANGLE-Fix-angle-d3d11-on-MSVC2010.patch309
-rw-r--r--src/angle/patches/0016-ANGLE-Fix-compilation-with-MinGW-D3D11.patch322
-rw-r--r--src/angle/src/libEGL/libEGL.pro20
-rw-r--r--src/angle/src/libGLESv2/libGLESv2.pro26
231 files changed, 16557 insertions, 13270 deletions
diff --git a/src/3rdparty/angle/AUTHORS b/src/3rdparty/angle/AUTHORS
index b79bb5d161..be114bcf68 100644
--- a/src/3rdparty/angle/AUTHORS
+++ b/src/3rdparty/angle/AUTHORS
@@ -21,10 +21,12 @@ Mozilla Corporation
Turbulenz
Klarälvdalens Datakonsult AB
Microsoft Open Technologies, Inc.
+NVIDIA Corporation
Jacek Caban
Mark Callow
Ginn Chen
+Tibor den Ouden
James Hauxwell
Sam Hocevar
Pierre Leveille
diff --git a/src/3rdparty/angle/CONTRIBUTORS b/src/3rdparty/angle/CONTRIBUTORS
index 0cae10a0f6..94d009f2b3 100644
--- a/src/3rdparty/angle/CONTRIBUTORS
+++ b/src/3rdparty/angle/CONTRIBUTORS
@@ -78,7 +78,12 @@ Turbulenz
Ulrik Persson (ddefrostt)
Mark Banner (standard8mbp)
David Kilzer
+Jacek Caban
+Tibor den Ouden
Microsoft Open Technologies, Inc.
Cooper Partin
Austin Kinross
+
+NVIDIA Corporation
+ Olli Etuaho
diff --git a/src/3rdparty/angle/include/EGL/egl.h b/src/3rdparty/angle/include/EGL/egl.h
index ab2f0cdfbe..12590a0e20 100644
--- a/src/3rdparty/angle/include/EGL/egl.h
+++ b/src/3rdparty/angle/include/EGL/egl.h
@@ -238,7 +238,7 @@ EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
#ifndef EGL_VERSION_1_5
#define EGL_VERSION_1_5 1
typedef void *EGLSync;
-typedef khronos_intptr_t EGLAttrib;
+typedef intptr_t EGLAttrib;
typedef khronos_utime_nanoseconds_t EGLTime;
#define EGL_CONTEXT_MAJOR_VERSION 0x3098
#define EGL_CONTEXT_MINOR_VERSION 0x30FB
diff --git a/src/3rdparty/angle/include/EGL/eglext.h b/src/3rdparty/angle/include/EGL/eglext.h
index 989359b026..0cc5eec293 100644
--- a/src/3rdparty/angle/include/EGL/eglext.h
+++ b/src/3rdparty/angle/include/EGL/eglext.h
@@ -59,7 +59,7 @@ extern "C" {
#ifndef EGL_KHR_cl_event2
#define EGL_KHR_cl_event2 1
typedef void *EGLSyncKHR;
-typedef khronos_intptr_t EGLAttribKHR;
+typedef intptr_t EGLAttribKHR;
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
@@ -442,20 +442,22 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#define EGL_ANGLE_platform_angle 1
#define EGL_PLATFORM_ANGLE_ANGLE 0x3201
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202
-#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3203
+#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
#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 0x3204
-#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3205
-#define EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE 0x3206
+#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3206
+#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207
+#define EGL_PLATFORM_ANGLE_USE_WARP_ANGLE 0x3208
#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 0x3207
-#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x3208
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x3209
+#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320A
#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 ea9f5778ee..2eb3674a0b 100644
--- a/src/3rdparty/angle/include/EGL/eglplatform.h
+++ b/src/3rdparty/angle/include/EGL/eglplatform.h
@@ -67,23 +67,22 @@
* implementations.
*/
-#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */
-
-struct IUnknown;
-
-typedef IUnknown *EGLNativeDisplayType;
-typedef void *EGLNativePixmapType;
-typedef IUnknown *EGLNativeWindowType;
-
-#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
-typedef HDC EGLNativeDisplayType;
typedef HBITMAP EGLNativePixmapType;
+
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_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
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
diff --git a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
index b7989f5f7e..647fed6a02 100644
--- a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
+++ b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
@@ -27,6 +27,10 @@
#include "KHR/khrplatform.h"
+#include <map>
+#include <string>
+#include <vector>
+
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler.
@@ -42,18 +46,17 @@ typedef unsigned int GLenum;
// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
#include "ShaderVars.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
// Version number for shader translation API.
// It is incremented every time the API changes.
-#define ANGLE_SH_VERSION 130
+#define ANGLE_SH_VERSION 132
typedef enum {
SH_GLES2_SPEC = 0x8B40,
SH_WEBGL_SPEC = 0x8B41,
+ SH_GLES3_SPEC = 0x8B86,
+ SH_WEBGL2_SPEC = 0x8B87,
+
// The CSS Shaders spec is a subset of the WebGL spec.
//
// In both CSS vertex and fragment shaders, ANGLE:
@@ -85,31 +88,6 @@ typedef enum {
SH_HLSL11_OUTPUT = 0x8B48
} ShShaderOutput;
-typedef enum {
- SH_PRECISION_HIGHP = 0x5001,
- SH_PRECISION_MEDIUMP = 0x5002,
- SH_PRECISION_LOWP = 0x5003,
- SH_PRECISION_UNDEFINED = 0
-} ShPrecisionType;
-
-typedef enum {
- SH_INFO_LOG_LENGTH = 0x8B84,
- SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
- SH_ACTIVE_UNIFORMS = 0x8B86,
- SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
- SH_ACTIVE_ATTRIBUTES = 0x8B89,
- SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
- SH_VARYINGS = 0x8BBB,
- SH_VARYING_MAX_LENGTH = 0x8BBC,
- SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
- SH_NAME_MAX_LENGTH = 0x6001,
- SH_HASHED_NAME_MAX_LENGTH = 0x6002,
- SH_HASHED_NAMES_COUNT = 0x6003,
- SH_SHADER_VERSION = 0x6004,
- SH_RESOURCES_STRING_LENGTH = 0x6005,
- SH_OUTPUT_TYPE = 0x6006
-} ShShaderInfo;
-
// Compile options.
typedef enum {
SH_VALIDATE = 0,
@@ -208,14 +186,14 @@ typedef enum {
//
// Driver must call this first, once, before doing any other
// compiler operations.
-// If the function succeeds, the return value is nonzero, else zero.
+// If the function succeeds, the return value is true, else false.
//
-COMPILER_EXPORT int ShInitialize();
+COMPILER_EXPORT bool ShInitialize();
//
// Driver should call this at shutdown.
-// If the function succeeds, the return value is nonzero, else zero.
+// If the function succeeds, the return value is true, else false.
//
-COMPILER_EXPORT int ShFinalize();
+COMPILER_EXPORT bool ShFinalize();
// The 64 bits hash function. The first parameter is the input string; the
// second parameter is the string length.
@@ -246,6 +224,12 @@ typedef struct
int EXT_frag_depth;
int EXT_shader_texture_lod;
+ // Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives
+ // with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate
+ // EXT_draw_buffers by using it in combination with GLES3.0 glDrawBuffers
+ // function. This applies to Tegra K1 devices.
+ int NV_draw_buffers;
+
// Set to 1 if highp precision is supported in the fragment language.
// Default is 0.
int FragmentPrecisionHigh;
@@ -274,8 +258,10 @@ typedef struct
//
// Initialize built-in resources with minimum expected values.
+// Parameters:
+// resources: The object to initialize. Will be comparable with memcmp.
//
-COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
+COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources);
//
// ShHandle held by but opaque to the driver. It is allocated,
@@ -284,18 +270,15 @@ COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
//
// If handle creation fails, 0 will be returned.
//
-typedef void* ShHandle;
+typedef void *ShHandle;
//
-// Returns the a concatenated list of the items in ShBuiltInResources as a string.
+// Returns the a concatenated list of the items in ShBuiltInResources as a
+// null-terminated string.
// This function must be updated whenever ShBuiltInResources is changed.
// Parameters:
// handle: Specifies the handle of the compiler to be used.
-// outStringLen: Specifies the size of the buffer, in number of characters. The size
-// of the buffer required to store the resources string can be obtained
-// by calling ShGetInfo with SH_RESOURCES_STRING_LENGTH.
-// outStr: Returns a null-terminated string representing all the built-in resources.
-COMPILER_EXPORT void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outStr);
+COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
//
// Driver calls these to create and destroy compiler objects.
@@ -313,12 +296,12 @@ COMPILER_EXPORT ShHandle ShConstructCompiler(
sh::GLenum type,
ShShaderSpec spec,
ShShaderOutput output,
- const ShBuiltInResources* resources);
+ const ShBuiltInResources *resources);
COMPILER_EXPORT void ShDestruct(ShHandle handle);
//
// Compiles the given shader source.
-// If the function succeeds, the return value is nonzero, else zero.
+// If the function succeeds, the return value is true, else false.
// Parameters:
// handle: Specifies the handle of compiler to be used.
// shaderStrings: Specifies an array of pointers to null-terminated strings
@@ -340,123 +323,36 @@ COMPILER_EXPORT void ShDestruct(ShHandle handle);
// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
// Can be queried by calling ShGetVariableInfo().
//
-COMPILER_EXPORT int ShCompile(
+COMPILER_EXPORT bool ShCompile(
const ShHandle handle,
- const char* const shaderStrings[],
+ const char * const shaderStrings[],
size_t numStrings,
- int compileOptions
- );
+ int compileOptions);
-// Returns a parameter from a compiled shader.
-// Parameters:
-// handle: Specifies the compiler
-// pname: Specifies the parameter to query.
-// The following parameters are defined:
-// SH_INFO_LOG_LENGTH: the number of characters in the information log
-// including the null termination character.
-// SH_OBJECT_CODE_LENGTH: the number of characters in the object code
-// including the null termination character.
-// SH_ACTIVE_ATTRIBUTES: the number of active attribute variables.
-// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute
-// variable name including the null
-// termination character.
-// SH_ACTIVE_UNIFORMS: the number of active uniform variables.
-// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
-// variable name including the null
-// termination character.
-// SH_VARYINGS: the number of varying variables.
-// SH_VARYING_MAX_LENGTH: the length of the longest varying variable name
-// including the null termination character.
-// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
-// the null termination character.
-// SH_NAME_MAX_LENGTH: the max length of a user-defined name including the
-// null termination character.
-// SH_HASHED_NAME_MAX_LENGTH: the max length of a hashed name including the
-// null termination character.
-// SH_HASHED_NAMES_COUNT: the number of hashed names from the latest compile.
-// SH_SHADER_VERSION: the version of the shader language
-// SH_OUTPUT_TYPE: the currently set language output type
-//
-// params: Requested parameter
-COMPILER_EXPORT void ShGetInfo(const ShHandle handle,
- ShShaderInfo pname,
- size_t* params);
+// Return the version of the shader language.
+COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle);
-// Returns nul-terminated information log for a compiled shader.
+// Return the currently set language output type.
+COMPILER_EXPORT ShShaderOutput ShGetShaderOutputType(
+ const ShHandle handle);
+
+// Returns null-terminated information log for a compiled shader.
// Parameters:
// handle: Specifies the compiler
-// infoLog: Specifies an array of characters that is used to return
-// the information log. It is assumed that infoLog has enough memory
-// to accomodate the information log. The size of the buffer required
-// to store the returned information log can be obtained by calling
-// ShGetInfo with SH_INFO_LOG_LENGTH.
-COMPILER_EXPORT void ShGetInfoLog(const ShHandle handle, char* infoLog);
+COMPILER_EXPORT const std::string &ShGetInfoLog(const ShHandle handle);
// Returns null-terminated object code for a compiled shader.
// Parameters:
// handle: Specifies the compiler
-// infoLog: Specifies an array of characters that is used to return
-// the object code. It is assumed that infoLog has enough memory to
-// accomodate the object code. The size of the buffer required to
-// store the returned object code can be obtained by calling
-// ShGetInfo with SH_OBJECT_CODE_LENGTH.
-COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode);
-
-// Returns information about a shader variable.
-// Parameters:
-// handle: Specifies the compiler
-// variableType: Specifies the variable type; options include
-// SH_ACTIVE_ATTRIBUTES, SH_ACTIVE_UNIFORMS, SH_VARYINGS.
-// index: Specifies the index of the variable to be queried.
-// length: Returns the number of characters actually written in the string
-// indicated by name (excluding the null terminator) if a value other
-// than NULL is passed.
-// size: Returns the size of the variable.
-// type: Returns the data type of the variable.
-// precision: Returns the precision of the variable.
-// staticUse: Returns 1 if the variable is accessed in a statement after
-// pre-processing, whether or not run-time flow of control will
-// cause that statement to be executed.
-// Returns 0 otherwise.
-// name: Returns a null terminated string containing the name of the
-// variable. It is assumed that name has enough memory to accormodate
-// the variable name. The size of the buffer required to store the
-// variable name can be obtained by calling ShGetInfo with
-// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_ACTIVE_UNIFORM_MAX_LENGTH,
-// SH_VARYING_MAX_LENGTH.
-// mappedName: Returns a null terminated string containing the mapped name of
-// the variable, It is assumed that mappedName has enough memory
-// (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care about the
-// mapped name. If the name is not mapped, then name and mappedName
-// are the same.
-COMPILER_EXPORT void ShGetVariableInfo(const ShHandle handle,
- ShShaderInfo variableType,
- int index,
- size_t* length,
- int* size,
- sh::GLenum* type,
- ShPrecisionType* precision,
- int* staticUse,
- char* name,
- char* mappedName);
-
-// Returns information about a name hashing entry from the latest compile.
+COMPILER_EXPORT const std::string &ShGetObjectCode(const ShHandle handle);
+
+// Returns a (original_name, hash) map containing all the user defined
+// names in the shader, including variable names, function names, struct
+// names, and struct field names.
// Parameters:
// handle: Specifies the compiler
-// index: Specifies the index of the name hashing entry to be queried.
-// name: Returns a null terminated string containing the user defined name.
-// It is assumed that name has enough memory to accomodate the name.
-// The size of the buffer required to store the user defined name can
-// be obtained by calling ShGetInfo with SH_NAME_MAX_LENGTH.
-// hashedName: Returns a null terminated string containing the hashed name of
-// the uniform variable, It is assumed that hashedName has enough
-// memory to accomodate the name. The size of the buffer required
-// to store the name can be obtained by calling ShGetInfo with
-// SH_HASHED_NAME_MAX_LENGTH.
-COMPILER_EXPORT void ShGetNameHashingEntry(const ShHandle handle,
- int index,
- char* name,
- char* hashedName);
+COMPILER_EXPORT const std::map<std::string, std::string> *ShGetNameHashingMap(
+ const ShHandle handle);
// Shader variable inspection.
// Returns a pointer to a list of variables of the designated type.
@@ -476,17 +372,17 @@ typedef struct
int size;
} ShVariableInfo;
-// Returns 1 if the passed in variables pack in maxVectors following
+// Returns true if the passed in variables pack in maxVectors following
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
-// Returns 0 otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
+// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
// flag above.
// Parameters:
// maxVectors: the available rows of registers.
// varInfoArray: an array of variable info (types and sizes).
// varInfoArraySize: the size of the variable array.
-COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
+COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
int maxVectors,
- ShVariableInfo* varInfoArray,
+ ShVariableInfo *varInfoArray,
size_t varInfoArraySize);
// Gives the compiler-assigned register for an interface block.
@@ -497,7 +393,7 @@ COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
// interfaceBlockName: Specifies the interface block
// indexOut: output variable that stores the assigned register
COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
- const char *interfaceBlockName,
+ const std::string &interfaceBlockName,
unsigned int *indexOut);
// Gives the compiler-assigned register for uniforms in the default
@@ -509,11 +405,7 @@ COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
// interfaceBlockName: Specifies the uniform
// indexOut: output variable that stores the assigned register
COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle,
- const char *uniformName,
+ const std::string &uniformName,
unsigned int *indexOut);
-#ifdef __cplusplus
-}
-#endif
-
#endif // _COMPILER_INTERFACE_INCLUDED_
diff --git a/src/3rdparty/angle/include/GLSLANG/ShaderVars.h b/src/3rdparty/angle/include/GLSLANG/ShaderVars.h
index 9c38647dda..da21c3e76e 100644
--- a/src/3rdparty/angle/include/GLSLANG/ShaderVars.h
+++ b/src/3rdparty/angle/include/GLSLANG/ShaderVars.h
@@ -52,6 +52,21 @@ struct COMPILER_EXPORT ShaderVariable
unsigned int elementCount() const { return std::max(1u, arraySize); }
bool isStruct() const { return !fields.empty(); }
+ // All of the shader's variables are described using nested data
+ // structures. This is needed in order to disambiguate similar looking
+ // types, such as two structs containing the same fields, but in
+ // different orders. "findInfoByMappedName" provides an easy query for
+ // users to dive into the data structure and fetch the unique variable
+ // instance corresponding to a dereferencing chain of the top-level
+ // variable.
+ // Given a mapped name like 'a[0].b.c[0]', return the ShaderVariable
+ // that defines 'c' in |leafVar|, and the original name 'A[0].B.C[0]'
+ // in |originalName|, based on the assumption that |this| defines 'a'.
+ // If no match is found, return false.
+ bool findInfoByMappedName(const std::string &mappedFullName,
+ const ShaderVariable **leafVar,
+ std::string* originalFullName) const;
+
GLenum type;
GLenum precision;
std::string name;
@@ -60,6 +75,16 @@ struct COMPILER_EXPORT ShaderVariable
bool staticUse;
std::vector<ShaderVariable> fields;
std::string structName;
+
+ protected:
+ bool isSameVariableAtLinkTime(const ShaderVariable &other,
+ bool matchPrecision) const;
+
+ bool operator==(const ShaderVariable &other) const;
+ bool operator!=(const ShaderVariable &other) const
+ {
+ return !operator==(other);
+ }
};
struct COMPILER_EXPORT Uniform : public ShaderVariable
@@ -68,6 +93,16 @@ struct COMPILER_EXPORT Uniform : public ShaderVariable
~Uniform();
Uniform(const Uniform &other);
Uniform &operator=(const Uniform &other);
+ bool operator==(const Uniform &other) const;
+ bool operator!=(const Uniform &other) const
+ {
+ return !operator==(other);
+ }
+
+ // Decide whether two uniforms are the same at shader link time,
+ // assuming one from vertex shader and the other from fragment shader.
+ // See GLSL ES Spec 3.00.3, sec 4.3.5.
+ bool isSameUniformAtLinkTime(const Uniform &other) const;
};
struct COMPILER_EXPORT Attribute : public ShaderVariable
@@ -76,6 +111,11 @@ struct COMPILER_EXPORT Attribute : public ShaderVariable
~Attribute();
Attribute(const Attribute &other);
Attribute &operator=(const Attribute &other);
+ bool operator==(const Attribute &other) const;
+ bool operator!=(const Attribute &other) const
+ {
+ return !operator==(other);
+ }
int location;
};
@@ -86,6 +126,18 @@ struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable
~InterfaceBlockField();
InterfaceBlockField(const InterfaceBlockField &other);
InterfaceBlockField &operator=(const InterfaceBlockField &other);
+ bool operator==(const InterfaceBlockField &other) const;
+ bool operator!=(const InterfaceBlockField &other) const
+ {
+ return !operator==(other);
+ }
+
+ // Decide whether two InterfaceBlock fields are the same at shader
+ // link time, assuming one from vertex shader and the other from
+ // fragment shader.
+ // See GLSL ES Spec 3.00.3, sec 4.3.7.
+ bool isSameInterfaceBlockFieldAtLinkTime(
+ const InterfaceBlockField &other) const;
bool isRowMajorLayout;
};
@@ -94,8 +146,18 @@ struct COMPILER_EXPORT Varying : public ShaderVariable
{
Varying();
~Varying();
- Varying(const Varying &other);
+ Varying(const Varying &otherg);
Varying &operator=(const Varying &other);
+ bool operator==(const Varying &other) const;
+ bool operator!=(const Varying &other) const
+ {
+ return !operator==(other);
+ }
+
+ // Decide whether two varyings are the same at shader link time,
+ // assuming one from vertex shader and the other from fragment shader.
+ // See GLSL ES Spec 3.00.3, sec 4.3.9.
+ bool isSameVaryingAtLinkTime(const Varying &other) const;
InterpolationType interpolation;
bool isInvariant;
diff --git a/src/3rdparty/angle/include/angle_windowsstore.h b/src/3rdparty/angle/include/angle_windowsstore.h
new file mode 100644
index 0000000000..53ec93e037
--- /dev/null
+++ b/src/3rdparty/angle/include/angle_windowsstore.h
@@ -0,0 +1,37 @@
+//
+// 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.
+//
+// angle_windowsstore.h:
+
+#ifndef ANGLE_WINDOWSSTORE_H_
+#define ANGLE_WINDOWSSTORE_H_
+
+// The following properties can be set on the CoreApplication to support additional
+// ANGLE configuration options.
+//
+// The Visual Studio sample templates provided with this version of ANGLE have examples
+// of how to set these property values.
+
+//
+// Property: EGLNativeWindowTypeProperty
+// Type: IInspectable
+// Description: Set this property to specify the window type to use for creating a surface.
+// If this property is missing, surface creation will fail.
+//
+const wchar_t EGLNativeWindowTypeProperty[] = L"EGLNativeWindowTypeProperty";
+
+//
+// Property: EGLRenderSurfaceSizeProperty
+// Type: Size
+// Description: Set this property to specify a preferred size in pixels of the render surface.
+// The render surface size width and height must be greater than 0.
+// If this property is set, then the render surface size is fixed.
+// If this property is missing, a default behavior will be provided.
+// The default behavior uses the window size if a CoreWindow is specified or
+// the size of the SwapChainPanel control if one is specified.
+//
+const wchar_t EGLRenderSurfaceSizeProperty[] = L"EGLRenderSurfaceSizeProperty";
+
+#endif // ANGLE_WINDOWSSTORE_H_
diff --git a/src/3rdparty/angle/src/commit.h b/src/3rdparty/angle/src/commit.h
index a2e761b131..08fc893c25 100644
--- a/src/3rdparty/angle/src/commit.h
+++ b/src/3rdparty/angle/src/commit.h
@@ -7,6 +7,6 @@
// This is a default commit hash header, when git is not available.
//
-#define ANGLE_COMMIT_HASH "abce76206141"
+#define ANGLE_COMMIT_HASH "30d6c255d238"
#define ANGLE_COMMIT_HASH_SIZE 12
-#define ANGLE_COMMIT_DATE "2014-09-23 19:37:05 +0000"
+#define ANGLE_COMMIT_DATE "2014-11-13 17:37:03 +0000"
diff --git a/src/3rdparty/angle/src/common/NativeWindow.h b/src/3rdparty/angle/src/common/NativeWindow.h
new file mode 100644
index 0000000000..9e93aeacde
--- /dev/null
+++ b/src/3rdparty/angle/src/common/NativeWindow.h
@@ -0,0 +1,77 @@
+//
+// 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.
+//
+
+// NativeWindow.h: Defines NativeWindow, a class for managing and
+// performing operations on an EGLNativeWindowType.
+// It is used for HWND (Desktop Windows) and IInspectable objects
+//(Windows Store Applications).
+
+#ifndef COMMON_NATIVEWINDOW_H_
+#define COMMON_NATIVEWINDOW_H_
+
+#include <EGL/eglplatform.h>
+#include "common/debug.h"
+#include "common/platform.h"
+
+// DXGISwapChain and DXGIFactory are typedef'd to specific required
+// types. The HWND NativeWindow implementation requires IDXGISwapChain
+// and IDXGIFactory and the Windows Store NativeWindow
+// implementation requires IDXGISwapChain1 and IDXGIFactory2.
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+typedef IDXGISwapChain1 DXGISwapChain;
+typedef IDXGIFactory2 DXGIFactory;
+
+#include <wrl.h>
+#include <wrl/wrappers/corewrappers.h>
+#include <windows.applicationmodel.core.h>
+#include <memory>
+
+namespace rx
+{
+class InspectableNativeWindow;
+}
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+
+#else
+typedef IDXGISwapChain DXGISwapChain;
+typedef IDXGIFactory DXGIFactory;
+#endif
+
+namespace rx
+{
+
+class NativeWindow
+{
+public:
+ explicit NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display);
+
+ bool initialize();
+ bool getClientRect(LPRECT rect);
+ bool isIconic();
+
+ 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;
+#endif
+
+};
+
+bool IsValidEGLNativeWindowType(EGLNativeWindowType window);
+}
+
+#endif // COMMON_NATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/common/angleutils.cpp b/src/3rdparty/angle/src/common/angleutils.cpp
index 2673abf30a..c1367c460a 100644
--- a/src/3rdparty/angle/src/common/angleutils.cpp
+++ b/src/3rdparty/angle/src/common/angleutils.cpp
@@ -5,26 +5,33 @@
//
#include "common/angleutils.h"
-
+#include "debug.h"
+#include <stdio.h>
#include <vector>
-std::string FormatString(const char *fmt, va_list vararg)
+size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer)
{
- static std::vector<char> buffer(512);
-
// Attempt to just print to the current buffer
- int len = vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
- if (len < 0 || static_cast<size_t>(len) >= buffer.size())
+ int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
+ if (len < 0 || static_cast<size_t>(len) >= outBuffer.size())
{
// Buffer was not large enough, calculate the required size and resize the buffer
len = vsnprintf(NULL, 0, fmt, vararg);
- buffer.resize(len + 1);
+ outBuffer.resize(len + 1);
// Print again
- vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
+ len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
}
+ ASSERT(len >= 0);
+ return static_cast<size_t>(len);
+}
+
+std::string FormatString(const char *fmt, va_list vararg)
+{
+ static std::vector<char> buffer(512);
- return std::string(buffer.data(), len);
+ size_t len = FormatStringIntoVector(fmt, vararg, buffer);
+ return std::string(&buffer[0], len);
}
std::string FormatString(const char *fmt, ...)
diff --git a/src/3rdparty/angle/src/common/angleutils.h b/src/3rdparty/angle/src/common/angleutils.h
index ddbbd5f501..b343ece5bc 100644
--- a/src/3rdparty/angle/src/common/angleutils.h
+++ b/src/3rdparty/angle/src/common/angleutils.h
@@ -17,6 +17,7 @@
#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
@@ -95,6 +96,13 @@ inline void StructZero(T *obj)
memset(obj, 0, sizeof(T));
}
+template <typename T>
+inline bool IsMaskFlagSet(T mask, T flag)
+{
+ // Handles multibit flags as well
+ return (mask & flag) == flag;
+}
+
inline const char* MakeStaticString(const std::string &str)
{
static std::set<std::string> strings;
@@ -132,9 +140,12 @@ inline std::string Str(int i)
return strstr.str();
}
+size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& buffer);
+
std::string FormatString(const char *fmt, va_list vararg);
std::string FormatString(const char *fmt, ...);
+// snprintf is not defined with MSVC prior to to msvc14
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif
diff --git a/src/3rdparty/angle/src/common/debug.cpp b/src/3rdparty/angle/src/common/debug.cpp
index dcad327564..5f55ff1e39 100644
--- a/src/3rdparty/angle/src/common/debug.cpp
+++ b/src/3rdparty/angle/src/common/debug.cpp
@@ -17,41 +17,211 @@
namespace gl
{
-#if defined(ANGLE_ENABLE_PERF)
-typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
-#else
-typedef void (*PerfOutputFunction)(unsigned int, const wchar_t*);
-#endif
+#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;
+};
-static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
+#if defined(ANGLE_ENABLE_D3D9)
+class D3D9DebugAnnotationWrapper : public DebugAnnotationWrapper
{
-#if defined(ANGLE_ENABLE_PERF) || defined(ANGLE_ENABLE_TRACE)
- std::string formattedMessage = FormatString(format, vararg);
+ 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
-#if defined(ANGLE_ENABLE_PERF)
- if (perfActive())
+ // Otherwise, we have to return true here.
+ return true;
+ }
+
+ protected:
+
+ void initializeDevice()
{
- // The perf function only accepts wide strings, widen the ascii message
- static std::wstring wideMessage;
- if (wideMessage.capacity() < formattedMessage.length())
+ if (!mInitialized)
{
- wideMessage.reserve(formattedMessage.size());
+#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
- wideMessage.assign(formattedMessage.begin(), formattedMessage.end());
+enum DebugTraceOutputType
+{
+ DebugTraceOutputTypeNone,
+ DebugTraceOutputTypeSetMarker,
+ 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);
- perfFunc(0, wideMessage.c_str());
+ if (perfActive())
+ {
+ size_t len = FormatStringIntoVector(format, vararg, buffer);
+ std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len);
+
+ switch (outputType)
+ {
+ case DebugTraceOutputTypeNone:
+ break;
+ case DebugTraceOutputTypeBeginEvent:
+ g_DebugAnnotationWrapper->beginEvent(formattedWideMessage);
+ break;
+ case DebugTraceOutputTypeSetMarker:
+ g_DebugAnnotationWrapper->setMarker(formattedWideMessage);
+ break;
+ }
}
-#endif // ANGLE_ENABLE_PERF
+#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
-#if defined(ANGLE_ENABLE_TRACE)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE)
#if defined(NDEBUG)
- if (traceFileDebugOnly)
+ if (traceInDebugOnly)
{
return;
}
#endif // NDEBUG
+ std::string formattedMessage = FormatString(format, vararg);
static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
if (file)
@@ -60,25 +230,29 @@ static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const c
file.flush();
}
-#endif // ANGLE_ENABLE_TRACE
+#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
+ OutputDebugStringA(formattedMessage.c_str());
+#endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
+
+#endif // ANGLE_ENABLE_DEBUG_TRACE
}
-void trace(bool traceFileDebugOnly, const char *format, ...)
+void trace(bool traceInDebugOnly, const char *format, ...)
{
va_list vararg;
va_start(vararg, format);
-#if defined(ANGLE_ENABLE_PERF)
- output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+ output(traceInDebugOnly, DebugTraceOutputTypeSetMarker, format, vararg);
#else
- output(traceFileDebugOnly, NULL, format, vararg);
+ output(traceInDebugOnly, DebugTraceOutputTypeNone, format, vararg);
#endif
va_end(vararg);
}
bool perfActive()
{
-#if defined(ANGLE_ENABLE_PERF)
- static bool active = D3DPERF_GetStatus() != 0;
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+ static bool active = g_DebugAnnotationWrapper->getStatus();
return active;
#else
return false;
@@ -87,26 +261,28 @@ bool perfActive()
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
{
-#if defined(ANGLE_ENABLE_PERF)
-#if !defined(ANGLE_ENABLE_TRACE)
+#if !defined(ANGLE_ENABLE_DEBUG_TRACE)
if (!perfActive())
{
return;
}
-#endif // !ANGLE_ENABLE_TRACE
+#endif // !ANGLE_ENABLE_DEBUG_TRACE
va_list vararg;
va_start(vararg, format);
- output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+ output(true, DebugTraceOutputTypeBeginEvent, format, vararg);
+#else
+ output(true, DebugTraceOutputTypeNone, format, vararg);
+#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
va_end(vararg);
-#endif // ANGLE_ENABLE_PERF
}
ScopedPerfEventHelper::~ScopedPerfEventHelper()
{
-#if defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
if (perfActive())
{
- D3DPERF_EndEvent();
+ g_DebugAnnotationWrapper->endEvent();
}
#endif
}
diff --git a/src/3rdparty/angle/src/common/debug.h b/src/3rdparty/angle/src/common/debug.h
index bf2bca8f24..c177f51314 100644
--- a/src/3rdparty/angle/src/common/debug.h
+++ b/src/3rdparty/angle/src/common/debug.h
@@ -20,8 +20,8 @@
namespace gl
{
- // Outputs text to the debugging log
- void trace(bool traceFileDebugOnly, const char *format, ...);
+ // Outputs text to the debugging log, or the debugging window
+ void trace(bool traceInDebugOnly, const char *format, ...);
// Returns whether D3DPERF is active.
bool perfActive();
@@ -36,31 +36,34 @@ namespace gl
private:
DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper);
};
+
+ 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_TRACE) || defined(ANGLE_ENABLE_PERF)
+#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__)
#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_TRACE) || defined(ANGLE_ENABLE_PERF)
+#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__)
#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_TRACE) || defined(ANGLE_ENABLE_PERF)
+#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__)
#else
#define ERR(message, ...) (void(0))
#endif
// A macro to log a performance event around a scope.
-#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
#if defined(_MSC_VER)
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__);
#else
@@ -83,7 +86,7 @@ namespace gl
#define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
#endif
-#ifndef ANGLE_ENABLE_TRACE
+#ifndef ANGLE_ENABLE_DEBUG_TRACE
#define UNUSED_TRACE_VARIABLE(variable) ((void)variable)
#else
#define UNUSED_TRACE_VARIABLE(variable)
@@ -128,7 +131,7 @@ namespace gl
#endif
// A macro functioning as a compile-time assert to validate constant conditions
-#if defined(_MSC_VER) && _MSC_VER >= 1600
+#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
diff --git a/src/3rdparty/angle/src/common/features.h b/src/3rdparty/angle/src/common/features.h
new file mode 100644
index 0000000000..b49a0ee852
--- /dev/null
+++ b/src/3rdparty/angle/src/common/features.h
@@ -0,0 +1,35 @@
+//
+// 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.
+//
+
+#define ANGLE_DISABLED 0
+#define ANGLE_ENABLED 1
+
+// Feature defaults
+
+// Direct3D9EX
+// The "Debug This Pixel..." feature in PIX often fails when using the
+// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7
+// machine, define "ANGLE_D3D9EX=0" in your project file.
+#if !defined(ANGLE_D3D9EX)
+#define ANGLE_D3D9EX ANGLE_ENABLED
+#endif
+
+// Vsync
+// ENABLED allows Vsync to be configured at runtime
+// DISABLED disallows Vsync
+#if !defined(ANGLE_VSYNC)
+#define ANGLE_VSYNC ANGLE_ENABLED
+#endif
+
+// Program binary loading
+#if !defined(ANGLE_PROGRAM_BINARY_LOAD)
+#define ANGLE_PROGRAM_BINARY_LOAD ANGLE_ENABLED
+#endif
+
+// Shader debug info
+#if !defined(ANGLE_SHADER_DEBUG_INFO)
+#define ANGLE_SHADER_DEBUG_INFO ANGLE_DISABLED
+#endif
diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h
index 52f2bc1c0e..a1717892fd 100644
--- a/src/3rdparty/angle/src/common/mathutil.h
+++ b/src/3rdparty/angle/src/common/mathutil.h
@@ -109,7 +109,7 @@ inline unsigned int unorm(float x)
inline bool supportsSSE2()
{
-#ifdef ANGLE_PLATFORM_WINDOWS
+#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM)
static bool checked = false;
static bool supports = false;
@@ -118,7 +118,6 @@ inline bool supportsSSE2()
return supports;
}
-#if defined(_M_IX86) || defined(_M_AMD64) // ARM doesn't provide __cpuid()
int info[4];
__cpuid(info, 0);
@@ -128,7 +127,6 @@ 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 b53394f337..0001e7142e 100644
--- a/src/3rdparty/angle/src/common/platform.h
+++ b/src/3rdparty/angle/src/common/platform.h
@@ -11,9 +11,6 @@
#if defined(_WIN32) || defined(_WIN64)
# define ANGLE_PLATFORM_WINDOWS 1
-# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
-# define ANGLE_PLATFORM_WINRT 1
-# endif
#elif defined(__APPLE__)
# define ANGLE_PLATFORM_APPLE 1
# define ANGLE_PLATFORM_POSIX 1
@@ -37,6 +34,9 @@
#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,7 +50,7 @@
# include <windows.h>
# include <intrin.h>
-# if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_PERF)
+# if defined(ANGLE_ENABLE_D3D9)
# include <d3d9.h>
# if !defined(COMPILER_IMPLEMENTATION)
# include <d3dcompiler.h>
@@ -62,13 +62,26 @@
# include <d3d10.h>
# include <d3d11.h>
# include <dxgi.h>
-# if _MSC_VER >= 1700
+# if defined(_MSC_VER) && (_MSC_VER >= 1700)
+# include <d3d11_1.h>
# include <dxgi1_2.h>
# endif
# if !defined(COMPILER_IMPLEMENTATION)
# include <d3dcompiler.h>
# endif
-# if defined(__MINGW32__)
+# endif
+
+# 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
+
+# if defined(__MINGW32__) // Missing defines on MinGW
typedef enum D3D11_MAP_FLAG
{
D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000L
@@ -78,8 +91,68 @@ typedef struct D3D11_QUERY_DATA_SO_STATISTICS
UINT64 NumPrimitivesWritten;
UINT64 PrimitivesStorageNeeded;
} D3D11_QUERY_DATA_SO_STATISTICS;
-# endif
-# endif
+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
diff --git a/src/3rdparty/angle/src/common/tls.cpp b/src/3rdparty/angle/src/common/tls.cpp
index c46fab5303..cb1b32d325 100644
--- a/src/3rdparty/angle/src/common/tls.cpp
+++ b/src/3rdparty/angle/src/common/tls.cpp
@@ -10,29 +10,50 @@
#include <assert.h>
-#if defined(ANGLE_PLATFORM_WINRT)
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
#include <vector>
-std::vector<void *> *tls = nullptr;
-std::vector<TLSIndex> *freeIndices = nullptr;
+#include <set>
+#include <map>
+#include <mutex>
+
+#include <wrl/client.h>
+#include <wrl/async.h>
+#include <Windows.System.Threading.h>
+
+using namespace std;
+using namespace Windows::Foundation;
+using namespace ABI::Windows::System::Threading;
+
+// Thread local storage for Windows Store support
+typedef vector<void*> ThreadLocalData;
+
+static __declspec(thread) ThreadLocalData* currentThreadData = nullptr;
+static set<ThreadLocalData*> allThreadData;
+static DWORD nextTlsIndex = 0;
+static vector<DWORD> freeTlsIndices;
+
#endif
TLSIndex CreateTLSIndex()
{
TLSIndex index;
-#if defined(ANGLE_PLATFORM_WINRT)
- if (!tls)
- tls = new std::vector<void *>;
- if (freeIndices && !freeIndices->empty()) {
- index = freeIndices->back();
- freeIndices->pop_back();
- return index;
- } else {
- tls->push_back(nullptr);
- return tls->size() - 1;
+#ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+ if (!freeTlsIndices.empty())
+ {
+ DWORD result = freeTlsIndices.back();
+ freeTlsIndices.pop_back();
+ index = result;
}
-#elif defined(ANGLE_PLATFORM_WINDOWS)
+ else
+ {
+ index = nextTlsIndex++;
+ }
+#else
index = TlsAlloc();
+#endif
+
#elif defined(ANGLE_PLATFORM_POSIX)
// Create global pool key
if ((pthread_key_create(&index, NULL)) != 0)
@@ -53,13 +74,23 @@ bool DestroyTLSIndex(TLSIndex index)
return false;
}
-#if defined(ANGLE_PLATFORM_WINRT)
- if (!freeIndices)
- freeIndices = new std::vector<TLSIndex>;
- freeIndices->push_back(index);
+#ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+ assert(index < nextTlsIndex);
+ assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), index) == freeTlsIndices.end());
+
+ freeTlsIndices.push_back(index);
+ for (auto threadData : allThreadData)
+ {
+ if (threadData->size() > index)
+ {
+ threadData->at(index) = nullptr;
+ }
+ }
return true;
-#elif ANGLE_PLATFORM_WINDOWS
+#else
return (TlsFree(index) == TRUE);
+#endif
#elif defined(ANGLE_PLATFORM_POSIX)
return (pthread_key_delete(index) == 0);
#endif
@@ -73,11 +104,25 @@ bool SetTLSValue(TLSIndex index, void *value)
return false;
}
-#if defined(ANGLE_PLATFORM_WINRT)
- tls->at(index) = value;
+#ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+ ThreadLocalData* threadData = currentThreadData;
+ if (!threadData)
+ {
+ threadData = new ThreadLocalData(index + 1, nullptr);
+ allThreadData.insert(threadData);
+ currentThreadData = threadData;
+ }
+ else if (threadData->size() <= index)
+ {
+ threadData->resize(index + 1, nullptr);
+ }
+
+ threadData->at(index) = value;
return true;
-#elif defined(ANGLE_PLATFORM_WINDOWS)
+#else
return (TlsSetValue(index, value) == TRUE);
+#endif
#elif defined(ANGLE_PLATFORM_POSIX)
return (pthread_setspecific(index, value) == 0);
#endif
@@ -85,18 +130,26 @@ bool SetTLSValue(TLSIndex index, void *value)
void *GetTLSValue(TLSIndex index)
{
-#if !defined(ANGLE_PLATFORM_WINRT) // Valid on WinRT, as Alloc handles the index creation
assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index");
-#endif
if (index == TLS_INVALID_INDEX)
{
return NULL;
}
-#if defined(ANGLE_PLATFORM_WINRT)
- return tls->at(index);
-#elif defined(ANGLE_PLATFORM_WINDOWS)
+#ifdef ANGLE_PLATFORM_WINDOWS
+#ifdef ANGLE_ENABLE_WINDOWS_STORE
+ ThreadLocalData* threadData = currentThreadData;
+ if (threadData && threadData->size() > index)
+ {
+ return threadData->at(index);
+ }
+ else
+ {
+ return nullptr;
+ }
+#else
return TlsGetValue(index);
+#endif
#elif defined(ANGLE_PLATFORM_POSIX)
return pthread_getspecific(index);
#endif
diff --git a/src/3rdparty/angle/src/common/tls.h b/src/3rdparty/angle/src/common/tls.h
index c40ae1a061..8a06e92d1a 100644
--- a/src/3rdparty/angle/src/common/tls.h
+++ b/src/3rdparty/angle/src/common/tls.h
@@ -11,11 +11,15 @@
#include "common/platform.h"
-#if defined(ANGLE_PLATFORM_WINRT)
- typedef size_t TLSIndex;
-# define TLS_OUT_OF_INDEXES (static_cast<TLSIndex>(-1))
-# define TLS_INVALID_INDEX TLS_OUT_OF_INDEXES
-#elif defined(ANGLE_PLATFORM_WINDOWS)
+#ifdef ANGLE_PLATFORM_WINDOWS
+
+// TLS does not exist for Windows Store and needs to be emulated
+# ifdef ANGLE_ENABLE_WINDOWS_STORE
+# define TLS_OUT_OF_INDEXES -1
+# ifndef CREATE_SUSPENDED
+# define CREATE_SUSPENDED 0x00000004
+# endif
+# endif
typedef DWORD TLSIndex;
# define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
#elif defined(ANGLE_PLATFORM_POSIX)
@@ -28,6 +32,9 @@
# error Unsupported platform.
#endif
+// TODO(kbr): for POSIX platforms this will have to be changed to take
+// in a destructor function pointer, to allow the thread-local storage
+// to be properly deallocated upon thread exit.
TLSIndex CreateTLSIndex();
bool DestroyTLSIndex(TLSIndex index);
diff --git a/src/3rdparty/angle/src/common/utilities.cpp b/src/3rdparty/angle/src/common/utilities.cpp
index 4b8e325d22..9d797a6612 100644
--- a/src/3rdparty/angle/src/common/utilities.cpp
+++ b/src/3rdparty/angle/src/common/utilities.cpp
@@ -9,17 +9,16 @@
#include "common/utilities.h"
#include "common/mathutil.h"
#include "common/platform.h"
-#if defined(ANGLE_PLATFORM_WINRT)
-# include <locale>
-# include <codecvt>
-# include <wrl.h>
-# include <windows.storage.h>
- using namespace Microsoft::WRL;
- using namespace ABI::Windows::Storage;
-#endif
#include <set>
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+# include <wrl.h>
+# include <wrl/wrappers/corewrappers.h>
+# include <windows.applicationmodel.core.h>
+# include <windows.graphics.display.h>
+#endif
+
namespace gl
{
@@ -447,50 +446,10 @@ int VariableSortOrder(GLenum type)
}
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
std::string getTempPath()
{
-#if defined(ANGLE_PLATFORM_WINRT)
- static std::string path;
-
- while (path.empty())
- {
- ComPtr<IApplicationDataStatics> factory;
- Wrappers::HStringReference classId(RuntimeClass_Windows_Storage_ApplicationData);
- HRESULT result = RoGetActivationFactory(classId.Get(), IID_PPV_ARGS(&factory));
- if (FAILED(result))
- break;
-
- ComPtr<IApplicationData> applicationData;
- result = factory->get_Current(&applicationData);
- if (FAILED(result))
- break;
-
- ComPtr<IStorageFolder> storageFolder;
- result = applicationData->get_LocalFolder(&storageFolder);
- if (FAILED(result))
- break;
-
- ComPtr<IStorageItem> localFolder;
- result = storageFolder.As(&localFolder);
- if (FAILED(result))
- break;
-
- HSTRING localFolderPath;
- result = localFolder->get_Path(&localFolderPath);
- if (FAILED(result))
- break;
-
- std::wstring_convert< std::codecvt_utf8<wchar_t> > converter;
- path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL));
- if (path.empty())
- {
- UNREACHABLE();
- break;
- }
- }
-
- return path;
-#elif defined(ANGLE_PLATFORM_WINDOWS)
+#ifdef ANGLE_PLATFORM_WINDOWS
char path[MAX_PATH];
DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
if (pathLen == 0)
@@ -525,3 +484,33 @@ void writeFile(const char* path, const void* content, size_t size)
fwrite(content, sizeof(char), size, file);
fclose(file);
}
+#endif // !ANGLE_ENABLE_WINDOWS_STORE
+
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+
+void Sleep(unsigned long dwMilliseconds)
+{
+ static HANDLE singletonEvent = nullptr;
+ HANDLE sleepEvent = singletonEvent;
+ if (!sleepEvent)
+ {
+ sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
+
+ if (!sleepEvent)
+ return;
+
+ HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr);
+
+ if (previousEvent)
+ {
+ // Back out if multiple threads try to demand create at the same time.
+ CloseHandle(sleepEvent);
+ sleepEvent = previousEvent;
+ }
+ }
+
+ // Emulate sleep by waiting with timeout on an event that is never signalled.
+ WaitForSingleObjectEx(sleepEvent, dwMilliseconds, false);
+}
+
+#endif // ANGLE_ENABLE_WINDOWS_STORE
diff --git a/src/3rdparty/angle/src/common/utilities.h b/src/3rdparty/angle/src/common/utilities.h
index a823184ecd..2cf6bed176 100644
--- a/src/3rdparty/angle/src/common/utilities.h
+++ b/src/3rdparty/angle/src/common/utilities.h
@@ -46,7 +46,13 @@ template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(
}
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
std::string getTempPath();
void writeFile(const char* path, const void* data, size_t size);
+#endif
+
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+void Sleep(_In_ unsigned long dwMilliseconds);
+#endif
#endif // LIBGLESV2_UTILITIES_H
diff --git a/src/3rdparty/angle/src/common/win32/NativeWindow.cpp b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
new file mode 100644
index 0000000000..2440747260
--- /dev/null
+++ b/src/3rdparty/angle/src/common/win32/NativeWindow.cpp
@@ -0,0 +1,66 @@
+//
+// 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.
+//
+
+// NativeWindow.cpp: Handler for managing HWND native window types.
+
+#include "common/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)
+{
+}
+
+bool NativeWindow::initialize()
+{
+ return true;
+}
+
+bool NativeWindow::getClientRect(LPRECT rect)
+{
+ return GetClientRect(mWindow, rect) == TRUE;
+}
+
+bool NativeWindow::isIconic()
+{
+ return IsIconic(mWindow) == TRUE;
+}
+
+HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory,
+ DXGI_FORMAT format, unsigned int width, unsigned int height,
+ DXGISwapChain** swapChain)
+{
+ if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
+ {
+ return E_INVALIDARG;
+ }
+
+ DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
+ swapChainDesc.BufferCount = 1;
+ swapChainDesc.BufferDesc.Format = format;
+ swapChainDesc.BufferDesc.Width = width;
+ swapChainDesc.BufferDesc.Height = height;
+ swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+ swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
+ swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.Flags = 0;
+ swapChainDesc.OutputWindow = mWindow;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.Windowed = TRUE;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+
+ return factory->CreateSwapChain(device, &swapChainDesc, swapChain);
+}
+}
diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
new file mode 100644
index 0000000000..9b65c15625
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.cpp
@@ -0,0 +1,200 @@
+//
+// 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.cpp: NativeWindow for managing ICoreWindow native window types.
+
+#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, 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;
+
+ // IPropertySet is an optional parameter and can be null.
+ // If one is specified, cache as an IMap and read the properties
+ // used for initial host initialization.
+ if (propertySet)
+ {
+ result = props.As(&mPropertyMap);
+ if (SUCCEEDED(result))
+ {
+ // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
+ // was prevalidated to contain the EGLNativeWindowType before being passed to
+ // this host.
+ result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = win.As(&mCoreWindow);
+ }
+
+ 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
+ // of the host.
+ // Scaling of the swapchain output occurs automatically because if
+ // the scaling mode setting DXGI_SCALING_STRETCH on the swapchain.
+ if (swapChainSizeSpecified)
+ {
+ mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
+ mSupportsSwapChainResize = false;
+ }
+ 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 };
+ }
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ mNewClientRect = mClientRect;
+ mClientRectChanged = false;
+ return registerForSizeChangeEvents();
+ }
+
+ return false;
+}
+
+bool CoreWindowNativeWindow::registerForSizeChangeEvents()
+{
+ HRESULT result = mCoreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &CoreWindowNativeWindow::onSizeChanged).Get(),
+ &mSizeChangedEventToken);
+
+ if (SUCCEEDED(result))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+void CoreWindowNativeWindow::unregisterForSizeChangeEvents()
+{
+ if (mCoreWindow)
+ {
+ (void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken);
+ }
+ mSizeChangedEventToken.value = 0;
+}
+
+HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
+{
+ if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
+ {
+ return E_INVALIDARG;
+ }
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
+ swapChainDesc.Width = width;
+ swapChainDesc.Height = height;
+ swapChainDesc.Format = format;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+
+ *swapChain = nullptr;
+
+ ComPtr<IDXGISwapChain1> newSwapChain;
+ HRESULT result = factory->CreateSwapChainForCoreWindow(device, mCoreWindow.Get(), &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
+ if (SUCCEEDED(result))
+ {
+
+#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.
+ if (newSwapChain->ResizeBuffers(swapChainDesc.BufferCount, swapChainDesc.Width, swapChainDesc.Height, swapChainDesc.Format, DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) == DXGI_ERROR_UNSUPPORTED)
+ {
+ mSupportsSwapChainResize = false;
+ }
+#endif // (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+
+ result = newSwapChain.CopyTo(swapChain);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ // If automatic swapchain resize behaviors have been disabled, then
+ // unregister for the resize change events.
+ if (mSupportsSwapChainResize == false)
+ {
+ unregisterForSizeChangeEvents();
+ }
+ }
+
+ return result;
+}
+
+// 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::Size size;
+ if (SUCCEEDED(e->get_Size(&size)))
+ {
+ SIZE windowSizeInPixels = {
+ std::floor(size.Width * mScaleFactor + 0.5),
+ std::floor(size.Height * mScaleFactor + 0.5)
+ };
+ setNewClientSize(windowSizeInPixels);
+ }
+
+ return S_OK;
+}
+}
diff --git a/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.h
new file mode 100644
index 0000000000..1c5512417d
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/CoreWindowNativeWindow.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.
+//
+
+// 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/common/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
new file mode 100644
index 0000000000..0589f6dce5
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.cpp
@@ -0,0 +1,274 @@
+//
+// 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.
+//
+
+// InspectableNativeWindow.cpp: NativeWindow base class for managing IInspectable native window types.
+
+#include "common/winrt/CoreWindowNativeWindow.h"
+#include "common/winrt/SwapChainPanelNativeWindow.h"
+
+namespace rx
+{
+NativeWindow::NativeWindow(EGLNativeWindowType window, EGLNativeDisplayType display)
+ : mWindow(window), mDisplay(display)
+{
+}
+
+bool NativeWindow::initialize()
+{
+ // If the native window type is a IPropertySet, extract the
+ // EGLNativeWindowType (IInspectable) and initialize the
+ // proper host with this IPropertySet.
+ ComPtr<ABI::Windows::Foundation::Collections::IPropertySet> propertySet;
+ ComPtr<IInspectable> eglNativeWindow;
+ if (IsEGLConfiguredPropertySet(mWindow, &propertySet, &eglNativeWindow))
+ {
+ // A property set was found and the EGLNativeWindowType was
+ // retrieved. The mWindow member of the host to must be updated
+ // to use the EGLNativeWindowType specified in the property set.
+ // mWindow is treated as a raw pointer not an AddRef'd interface, so
+ // the old mWindow does not need a Release() before this assignment.
+ mWindow = eglNativeWindow.Get();
+ }
+
+ ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWindow;
+ ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> swapChainPanel;
+ if (IsCoreWindow(mWindow, &coreWindow))
+ {
+ mImpl = std::make_shared<CoreWindowNativeWindow>();
+ if (mImpl)
+ {
+ return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
+ }
+ }
+ else if (IsSwapChainPanel(mWindow, &swapChainPanel))
+ {
+ mImpl = std::make_shared<SwapChainPanelNativeWindow>();
+ if (mImpl)
+ {
+ return mImpl->initialize(mWindow, mDisplay, propertySet.Get());
+ }
+ }
+ else
+ {
+ ERR("Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include ICoreWindow, ISwapChainPanel and IPropertySet");
+ }
+
+ return false;
+}
+
+bool NativeWindow::getClientRect(RECT *rect)
+{
+ if (mImpl)
+ {
+ return mImpl->getClientRect(rect);
+ }
+
+ return false;
+}
+
+bool NativeWindow::isIconic()
+{
+ return false;
+}
+
+HRESULT NativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
+{
+ if (mImpl)
+ {
+ return mImpl->createSwapChain(device, factory, format, width, height, swapChain);
+ }
+
+ return E_UNEXPECTED;
+}
+
+bool IsCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow)
+{
+ if (!window)
+ {
+ return false;
+ }
+
+ ComPtr<IInspectable> win = window;
+ ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWin;
+ if (SUCCEEDED(win.As(&coreWin)))
+ {
+ if (coreWindow != nullptr)
+ {
+ *coreWindow = coreWin.Detach();
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel)
+{
+ if (!window)
+ {
+ return false;
+ }
+
+ ComPtr<IInspectable> win = window;
+ ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> panel;
+ if (SUCCEEDED(win.As(&panel)))
+ {
+ if (swapChainPanel != nullptr)
+ {
+ *swapChainPanel = panel.Detach();
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet, IInspectable **eglNativeWindow)
+{
+ if (!window)
+ {
+ return false;
+ }
+
+ ComPtr<IInspectable> props = window;
+ ComPtr<IPropertySet> propSet;
+ ComPtr<IInspectable> nativeWindow;
+ ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> propMap;
+ boolean hasEglNativeWindowPropertyKey = false;
+
+ HRESULT result = props.As(&propSet);
+ if (SUCCEEDED(result))
+ {
+ result = propSet.As(&propMap);
+ }
+
+ // Look for the presence of the EGLNativeWindowType in the property set
+ if (SUCCEEDED(result))
+ {
+ result = propMap->HasKey(HStringReference(EGLNativeWindowTypeProperty).Get(), &hasEglNativeWindowPropertyKey);
+ }
+
+ // If the IPropertySet does not contain the required EglNativeWindowType key, the property set is
+ // considered invalid.
+ if (SUCCEEDED(result) && !hasEglNativeWindowPropertyKey)
+ {
+ ERR("Could not find EGLNativeWindowTypeProperty in IPropertySet. Valid EGLNativeWindowTypeProperty values include ICoreWindow");
+ return false;
+ }
+
+ // The EglNativeWindowType property exists, so retreive the IInspectable that represents the EGLNativeWindowType
+ if (SUCCEEDED(result) && hasEglNativeWindowPropertyKey)
+ {
+ result = propMap->Lookup(HStringReference(EGLNativeWindowTypeProperty).Get(), &nativeWindow);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ if (propertySet != nullptr)
+ {
+ result = propSet.CopyTo(propertySet);
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ if (eglNativeWindow != nullptr)
+ {
+ result = nativeWindow.CopyTo(eglNativeWindow);
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+// A Valid EGLNativeWindowType IInspectable can only be:
+//
+// ICoreWindow
+// IPropertySet
+//
+// Anything else will be rejected as an invalid IInspectable.
+bool IsValidEGLNativeWindowType(EGLNativeWindowType window)
+{
+ return IsCoreWindow(window) || IsSwapChainPanel(window) || IsEGLConfiguredPropertySet(window);
+}
+
+// Attempts to read an optional SIZE property value that is assumed to be in the form of
+// an ABI::Windows::Foundation::Size. This function validates the Size value before returning
+// it to the caller.
+//
+// Possible return values are:
+// S_OK, valueExists == true - optional SIZE value was successfully retrieved and validated
+// S_OK, valueExists == false - optional SIZE value was not found
+// E_INVALIDARG, valueExists = false - optional SIZE value was malformed in the property set.
+// * Incorrect property type ( must be PropertyType_Size)
+// * Invalid property value (width/height must be > 0)
+// Additional errors may be returned from IMap or IPropertyValue
+//
+HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists)
+{
+ if (!propertyMap || !propertyName || !value || !valueExists)
+ {
+ return false;
+ }
+
+ // Assume that the value does not exist
+ *valueExists = false;
+ *value = { 0, 0 };
+
+ ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue;
+ ABI::Windows::Foundation::PropertyType propertyType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
+ Size sizeValue = { 0, 0 };
+ boolean hasKey = false;
+
+ HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), &hasKey);
+ if (SUCCEEDED(result) && !hasKey)
+ {
+ // Value does not exist, so return S_OK and set the exists parameter to false to indicate
+ // that a the optional property does not exist.
+ *valueExists = false;
+ return S_OK;
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = propertyValue->get_Type(&propertyType);
+ }
+
+ // Check if the expected Size property is of PropertyType_Size type.
+ if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size)
+ {
+ if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && (sizeValue.Width > 0 && sizeValue.Height > 0))
+ {
+ // A valid property value exists
+ *value = { static_cast<long>(sizeValue.Width), static_cast<long>(sizeValue.Height) };
+ *valueExists = true;
+ result = S_OK;
+ }
+ else
+ {
+ // An invalid Size property was detected. Width/Height values must > 0
+ result = E_INVALIDARG;
+ }
+ }
+ else
+ {
+ // An invalid property type was detected. Size property must be of PropertyType_Size
+ result = E_INVALIDARG;
+ }
+
+ return result;
+}
+}
diff --git a/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
new file mode 100644
index 0000000000..402941a788
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/InspectableNativeWindow.h
@@ -0,0 +1,91 @@
+//
+// 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.
+//
+
+// InspectableNativeWindow.h: Host specific implementation interface for
+// managing IInspectable native window types.
+
+#ifndef COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
+#define COMMON_WINRT_INSPECTABLENATIVEWINDOW_H_
+
+#include "common/platform.h"
+#include "common/NativeWindow.h"
+#include "angle_windowsstore.h"
+
+#include <windows.ui.xaml.h>
+#include <windows.ui.xaml.media.dxinterop.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+
+namespace rx
+{
+class InspectableNativeWindow
+{
+ public:
+ InspectableNativeWindow() :
+ mSupportsSwapChainResize(true),
+ mRequiresSwapChainScaling(false),
+ mClientRectChanged(false),
+ mClientRect({0,0,0,0}),
+ mNewClientRect({0,0,0,0}),
+ mScaleFactor(1.0)
+ {
+ mSizeChangedEventToken.value = 0;
+ }
+ virtual ~InspectableNativeWindow(){}
+
+ 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;
+ virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; }
+
+ bool getClientRect(RECT *rect)
+ {
+ if (mClientRectChanged && mSupportsSwapChainResize)
+ {
+ mClientRect = mNewClientRect;
+ mClientRectChanged = false;
+ }
+
+ *rect = mClientRect;
+
+ return true;
+ }
+
+ void setNewClientSize(const SIZE &newSize)
+ {
+ if (mSupportsSwapChainResize && !mRequiresSwapChainScaling)
+ {
+ mNewClientRect = { 0, 0, newSize.cx, newSize.cy };
+ mClientRectChanged = true;
+ }
+
+ if (mRequiresSwapChainScaling)
+ {
+ scaleSwapChain(newSize);
+ }
+ }
+
+protected:
+ bool mSupportsSwapChainResize;
+ bool mRequiresSwapChainScaling;
+ RECT mClientRect;
+ RECT mNewClientRect;
+ bool mClientRectChanged;
+ DOUBLE mScaleFactor;
+
+ EventRegistrationToken mSizeChangedEventToken;
+};
+
+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_
diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
new file mode 100644
index 0000000000..268dfbd8f0
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.cpp
@@ -0,0 +1,226 @@
+//
+// 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.
+//
+
+// SwapChainPanelNativeWindow.cpp: NativeWindow for managing ISwapChainPanel native window types.
+
+#include "common/winrt/SwapChainPanelNativeWindow.h"
+#include <algorithm>
+#include <math.h>
+using namespace ABI::Windows::Foundation::Collections;
+
+namespace rx
+{
+SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow()
+{
+ unregisterForSizeChangeEvents();
+}
+
+bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, EGLNativeDisplayType display, IPropertySet *propertySet)
+{
+ ComPtr<IPropertySet> props = propertySet;
+ ComPtr<IInspectable> win = window;
+ SIZE swapChainSize = {};
+ bool swapChainSizeSpecified = false;
+ HRESULT result = S_OK;
+
+ // IPropertySet is an optional parameter and can be null.
+ // If one is specified, cache as an IMap and read the properties
+ // used for initial host initialization.
+ if (propertySet)
+ {
+ result = props.As(&mPropertyMap);
+ if (SUCCEEDED(result))
+ {
+ // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
+ // was prevalidated to contain the EGLNativeWindowType before being passed to
+ // this host.
+ result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = win.As(&mSwapChainPanel);
+ }
+
+ 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
+ // of the host.
+ // Scaling of the swapchain output needs to be handled by the
+ // host for swapchain panels even though the scaling mode setting
+ // DXGI_SCALING_STRETCH is configured on the swapchain.
+ if (swapChainSizeSpecified)
+ {
+ mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
+
+ // Enable host swapchain scaling
+ mRequiresSwapChainScaling = true;
+ }
+ else
+ {
+ result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect);
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ mNewClientRect = mClientRect;
+ mClientRectChanged = false;
+ return registerForSizeChangeEvents();
+ }
+
+ return false;
+}
+
+bool SwapChainPanelNativeWindow::registerForSizeChangeEvents()
+{
+ ComPtr<ABI::Windows::UI::Xaml::ISizeChangedEventHandler> sizeChangedHandler;
+ ComPtr<ABI::Windows::UI::Xaml::IFrameworkElement> frameworkElement;
+ HRESULT result = Microsoft::WRL::MakeAndInitialize<SwapChainPanelSizeChangedHandler>(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this());
+
+ if (SUCCEEDED(result))
+ {
+ result = mSwapChainPanel.As(&frameworkElement);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = frameworkElement->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+void SwapChainPanelNativeWindow::unregisterForSizeChangeEvents()
+{
+ ComPtr<ABI::Windows::UI::Xaml::IFrameworkElement> frameworkElement;
+ if (SUCCEEDED(mSwapChainPanel.As(&frameworkElement)))
+ {
+ (void)frameworkElement->remove_SizeChanged(mSizeChangedEventToken);
+ }
+
+ mSizeChangedEventToken.value = 0;
+}
+
+HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
+{
+ if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
+ {
+ return E_INVALIDARG;
+ }
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
+ swapChainDesc.Width = width;
+ swapChainDesc.Height = height;
+ swapChainDesc.Format = format;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
+
+ *swapChain = nullptr;
+
+ ComPtr<IDXGISwapChain1> newSwapChain;
+ ComPtr<ISwapChainPanelNative> swapChainPanelNative;
+ RECT currentPanelSize = {};
+
+ HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
+
+ if (SUCCEEDED(result))
+ {
+ result = mSwapChainPanel.As(&swapChainPanelNative);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = swapChainPanelNative->SetSwapChain(newSwapChain.Get());
+ }
+
+ if (SUCCEEDED(result))
+ {
+ // The swapchain panel host requires an instance of the swapchain set on the SwapChainPanel
+ // to perform the runtime-scale behavior. This swapchain is cached here because there are
+ // no methods for retreiving the currently configured on from ISwapChainPanelNative.
+ mSwapChain = newSwapChain;
+ result = newSwapChain.CopyTo(swapChain);
+ }
+
+ // If the host is responsible for scaling the output of the swapchain, then
+ // scale it now before returning an instance to the caller. This is done by
+ // first reading the current size of the swapchain panel, then scaling
+ if (SUCCEEDED(result) && mRequiresSwapChainScaling)
+ {
+ result = GetSwapChainPanelSize(mSwapChainPanel, &currentPanelSize);
+ }
+
+ // Scale the swapchain to fit inside the contents of the panel.
+ if (SUCCEEDED(result) && mRequiresSwapChainScaling)
+ {
+ SIZE currentSize = { currentPanelSize.right, currentPanelSize.bottom };
+ result = scaleSwapChain(currentSize);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ // If automatic swapchain resize behaviors have been disabled, then
+ // unregister for the resize change events.
+ if (mSupportsSwapChainResize == false)
+ {
+ unregisterForSizeChangeEvents();
+ }
+ }
+
+ return result;
+}
+
+HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize)
+{
+ ABI::Windows::Foundation::Size renderScale = { (float)newSize.cx/(float)mClientRect.right, (float)newSize.cy/(float)mClientRect.bottom };
+ // Setup a scale matrix for the swap chain
+ DXGI_MATRIX_3X2_F scaleMatrix = {};
+ scaleMatrix._11 = renderScale.Width;
+ scaleMatrix._22 = renderScale.Height;
+
+ ComPtr<IDXGISwapChain2> swapChain2;
+ HRESULT result = mSwapChain.As(&swapChain2);
+ if (SUCCEEDED(result))
+ {
+ result = swapChain2->SetMatrixTransform(&scaleMatrix);
+ }
+
+ return result;
+}
+
+HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize)
+{
+ ComPtr<ABI::Windows::UI::Xaml::IUIElement> uiElement;
+ ABI::Windows::Foundation::Size renderSize = { 0, 0 };
+ HRESULT result = swapChainPanel.As(&uiElement);
+ if (SUCCEEDED(result))
+ {
+ result = uiElement->get_RenderSize(&renderSize);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ *windowSize = { 0, 0, lround(renderSize.Width), lround(renderSize.Height) };
+ }
+
+ return result;
+}
+}
diff --git a/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
new file mode 100644
index 0000000000..5bbf274e64
--- /dev/null
+++ b/src/3rdparty/angle/src/common/winrt/SwapChainPanelNativeWindow.h
@@ -0,0 +1,79 @@
+//
+// 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.
+//
+
+// SwapChainPanelNativeWindow.h: NativeWindow for managing ISwapChainPanel native window types.
+
+#ifndef COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
+#define COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
+
+#include "common/winrt/InspectableNativeWindow.h"
+
+namespace rx
+{
+class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this<SwapChainPanelNativeWindow>
+{
+ public:
+ ~SwapChainPanelNativeWindow();
+
+ 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);
+ HRESULT scaleSwapChain(const SIZE &newSize);
+
+ private:
+ ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> mSwapChainPanel;
+ ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
+ ComPtr<DXGISwapChain> mSwapChain;
+};
+
+[uuid(8ACBD974-8187-4508-AD80-AEC77F93CF36)]
+class SwapChainPanelSizeChangedHandler :
+ public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, ABI::Windows::UI::Xaml::ISizeChangedEventHandler>
+{
+ public:
+ SwapChainPanelSizeChangedHandler() { }
+ HRESULT RuntimeClassInitialize(std::shared_ptr<InspectableNativeWindow> host)
+ {
+ if (!host)
+ {
+ return E_INVALIDARG;
+ }
+
+ mHost = host;
+ return S_OK;
+ }
+
+ // ISizeChangedEventHandler
+ IFACEMETHOD(Invoke)(IInspectable *sender, ABI::Windows::UI::Xaml::ISizeChangedEventArgs *sizeChangedEventArgs)
+ {
+ std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
+ if (host)
+ {
+ // The size of the ISwapChainPanel control is returned in DIPs.
+ // We are keeping these in dips because the swapchain created for composition
+ // also uses dip units. This keeps dimensions, viewports, etc in the same unit.
+ // XAML Clients of the ISwapChainPanel are required to use dips to define their
+ // layout sizes as well.
+ ABI::Windows::Foundation::Size newSize;
+ HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize);
+ if (SUCCEEDED(result))
+ {
+ SIZE windowSize = { lround(newSize.Width), lround(newSize.Height) };
+ host->setNewClientSize(windowSize);
+ }
+ }
+
+ return S_OK;
+ }
+
+ private:
+ std::weak_ptr<InspectableNativeWindow> mHost;
+};
+
+HRESULT GetSwapChainPanelSize(const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel, RECT *windowSize);
+}
+#endif // COMMON_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
index 040b25c6a2..eec0d5e5f0 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
@@ -29,7 +29,8 @@ class DirectiveHandler
// Handle pragma of form: #pragma name[(value)]
virtual void handlePragma(const SourceLocation &loc,
const std::string &name,
- const std::string &value) = 0;
+ const std::string &value,
+ bool stdgl) = 0;
virtual void handleExtension(const SourceLocation &loc,
const std::string &name,
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp
index 6434d5cb5c..7803ee845a 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp
@@ -38,19 +38,19 @@ enum DirectiveType
DirectiveType getDirective(const pp::Token *token)
{
- static const std::string kDirectiveDefine("define");
- static const std::string kDirectiveUndef("undef");
- static const std::string kDirectiveIf("if");
- static const std::string kDirectiveIfdef("ifdef");
- static const std::string kDirectiveIfndef("ifndef");
- static const std::string kDirectiveElse("else");
- static const std::string kDirectiveElif("elif");
- static const std::string kDirectiveEndif("endif");
- static const std::string kDirectiveError("error");
- static const std::string kDirectivePragma("pragma");
- static const std::string kDirectiveExtension("extension");
- static const std::string kDirectiveVersion("version");
- static const std::string kDirectiveLine("line");
+ const char kDirectiveDefine[] = "define";
+ const char kDirectiveUndef[] = "undef";
+ const char kDirectiveIf[] = "if";
+ const char kDirectiveIfdef[] = "ifdef";
+ const char kDirectiveIfndef[] = "ifndef";
+ const char kDirectiveElse[] = "else";
+ const char kDirectiveElif[] = "elif";
+ const char kDirectiveEndif[] = "endif";
+ const char kDirectiveError[] = "error";
+ const char kDirectivePragma[] = "pragma";
+ const char kDirectiveExtension[] = "extension";
+ const char kDirectiveVersion[] = "version";
+ const char kDirectiveLine[] = "line";
if (token->type != pp::Token::IDENTIFIER)
return DIRECTIVE_NONE;
@@ -155,7 +155,7 @@ class DefinedParser : public Lexer
protected:
virtual void lex(Token *token)
{
- static const std::string kDefined("defined");
+ const char kDefined[] = "defined";
mLexer->lex(token);
if (token->type != Token::IDENTIFIER)
@@ -592,6 +592,11 @@ void DirectiveParser::parsePragma(Token *token)
int state = PRAGMA_NAME;
mTokenizer->lex(token);
+ bool stdgl = token->text == "STDGL";
+ if (stdgl)
+ {
+ mTokenizer->lex(token);
+ }
while ((token->type != '\n') && (token->type != Token::LAST))
{
switch(state++)
@@ -627,7 +632,7 @@ void DirectiveParser::parsePragma(Token *token)
}
else if (state > PRAGMA_NAME) // Do not notify for empty pragma.
{
- mDirectiveHandler->handlePragma(token->location, name, value);
+ mDirectiveHandler->handlePragma(token->location, name, value, stdgl);
}
}
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp
index d7e0c83465..69e2f39069 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp
@@ -194,8 +194,8 @@ bool MacroExpander::expandMacro(const Macro &macro,
if (macro.predefined)
{
- static const std::string kLine = "__LINE__";
- static const std::string kFile = "__FILE__";
+ const char kLine[] = "__LINE__";
+ const char kFile[] = "__FILE__";
assert(replacements->size() == 1);
Token& repl = replacements->front();
diff --git a/src/3rdparty/angle/src/compiler/translator/Compiler.cpp b/src/3rdparty/angle/src/compiler/translator/Compiler.cpp
index 368cd2ae4a..5c62a64d10 100644
--- a/src/3rdparty/angle/src/compiler/translator/Compiler.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/Compiler.cpp
@@ -29,24 +29,27 @@
bool IsWebGLBasedSpec(ShShaderSpec spec)
{
- return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
+ return (spec == SH_WEBGL_SPEC ||
+ spec == SH_CSS_SHADERS_SPEC ||
+ spec == SH_WEBGL2_SPEC);
}
size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
{
// WebGL defines a max token legnth of 256, while ES2 leaves max token
// size undefined. ES3 defines a max size of 1024 characters.
- if (IsWebGLBasedSpec(spec))
+ switch (spec)
{
+ case SH_WEBGL_SPEC:
+ case SH_CSS_SHADERS_SPEC:
return 256;
- }
- else
- {
+ default:
return 1024;
}
}
namespace {
+
class TScopedPoolAllocator
{
public:
@@ -82,6 +85,24 @@ class TScopedSymbolTableLevel
private:
TSymbolTable* mTable;
};
+
+int MapSpecToShaderVersion(ShShaderSpec spec)
+{
+ switch (spec)
+ {
+ case SH_GLES2_SPEC:
+ case SH_WEBGL_SPEC:
+ case SH_CSS_SHADERS_SPEC:
+ return 100;
+ case SH_GLES3_SPEC:
+ case SH_WEBGL2_SPEC:
+ return 300;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
} // namespace
TShHandleBase::TShHandleBase()
@@ -178,9 +199,21 @@ bool TCompiler::compile(const char* const shaderStrings[],
(parseContext.treeRoot != NULL);
shaderVersion = parseContext.getShaderVersion();
+ if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion)
+ {
+ infoSink.info.prefix(EPrefixError);
+ infoSink.info << "unsupported shader version";
+ success = false;
+ }
if (success)
{
+ mPragma = parseContext.pragma();
+ if (mPragma.stdgl.invariantAll)
+ {
+ symbolTable.setGlobalInvariant();
+ }
+
TIntermNode* root = parseContext.treeRoot;
success = intermediate.postProcess(root);
@@ -360,7 +393,8 @@ void TCompiler::setResourceString()
<< ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
<< ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
<< ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
- << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset;
+ << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
+ << ":NV_draw_buffers:" << compileResources.NV_draw_buffers;
builtInResourcesString = strstream.str();
}
@@ -377,7 +411,6 @@ void TCompiler::clearResults()
uniforms.clear();
expandedUniforms.clear();
varyings.clear();
- expandedVaryings.clear();
interfaceBlocks.clear();
builtInFunctionEmulator.Cleanup();
@@ -507,13 +540,12 @@ void TCompiler::collectVariables(TIntermNode* root)
&uniforms,
&varyings,
&interfaceBlocks,
- hashFunction);
+ hashFunction,
+ symbolTable);
root->traverse(&collect);
- // For backwards compatiblity with ShGetVariableInfo, expand struct
- // uniforms and varyings into separate variables for each field.
- sh::ExpandVariables(uniforms, &expandedUniforms);
- sh::ExpandVariables(varyings, &expandedVaryings);
+ // This is for enforcePackingRestriction().
+ sh::ExpandUniforms(uniforms, &expandedUniforms);
}
bool TCompiler::enforcePackingRestrictions()
@@ -581,3 +613,10 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
{
return builtInFunctionEmulator;
}
+
+void TCompiler::writePragma()
+{
+ TInfoSinkBase &sink = infoSink.obj;
+ if (mPragma.stdgl.invariantAll)
+ sink << "#pragma STDGL invariant(all)\n";
+}
diff --git a/src/3rdparty/angle/src/compiler/translator/Compiler.h b/src/3rdparty/angle/src/compiler/translator/Compiler.h
index ca0c157884..b6c9d13ed0 100644
--- a/src/3rdparty/angle/src/compiler/translator/Compiler.h
+++ b/src/3rdparty/angle/src/compiler/translator/Compiler.h
@@ -18,6 +18,7 @@
#include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/HashNames.h"
#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Pragma.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/VariableInfo.h"
#include "third_party/compiler/ArrayBoundsClamper.h"
@@ -71,9 +72,7 @@ class TCompiler : public TShHandleBase
const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; }
const std::vector<sh::Uniform> &getUniforms() const { return uniforms; }
- const std::vector<sh::ShaderVariable> &getExpandedUniforms() const { return expandedUniforms; }
const std::vector<sh::Varying> &getVaryings() const { return varyings; }
- const std::vector<sh::ShaderVariable> &getExpandedVaryings() const { return expandedVaryings; }
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
ShHashFunction64 getHashFunction() const { return hashFunction; }
@@ -81,7 +80,7 @@ class TCompiler : public TShHandleBase
TSymbolTable& getSymbolTable() { return symbolTable; }
ShShaderSpec getShaderSpec() const { return shaderSpec; }
ShShaderOutput getOutputType() const { return outputType; }
- std::string getBuiltInResourcesString() const { return builtInResourcesString; }
+ const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
// Get the resources set by InitBuiltInSymbolTable
const ShBuiltInResources& getResources() const;
@@ -131,6 +130,8 @@ class TCompiler : public TShHandleBase
bool limitExpressionComplexity(TIntermNode* root);
// Get built-in extensions with default behavior.
const TExtensionBehavior& getExtensionBehavior() const;
+ const TPragma& getPragma() const { return mPragma; }
+ void writePragma();
const ArrayBoundsClamper& getArrayBoundsClamper() const;
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
@@ -141,7 +142,6 @@ class TCompiler : public TShHandleBase
std::vector<sh::Uniform> uniforms;
std::vector<sh::ShaderVariable> expandedUniforms;
std::vector<sh::Varying> varyings;
- std::vector<sh::ShaderVariable> expandedVaryings;
std::vector<sh::InterfaceBlock> interfaceBlocks;
private:
@@ -174,6 +174,8 @@ class TCompiler : public TShHandleBase
// name hashing.
ShHashFunction64 hashFunction;
NameMap nameMap;
+
+ TPragma mPragma;
};
//
diff --git a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp
index 334eb0bfa8..f98d32b2b7 100644
--- a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp
@@ -14,6 +14,9 @@
namespace sh
{
+
+// Detect Loop Discontinuity
+
bool DetectLoopDiscontinuity::traverse(TIntermNode *node)
{
mLoopDepth = 0;
@@ -74,6 +77,55 @@ bool containsLoopDiscontinuity(TIntermNode *node)
return detectLoopDiscontinuity.traverse(node);
}
+// Detect Any Loop
+
+bool DetectAnyLoop::traverse(TIntermNode *node)
+{
+ mHasLoop = false;
+ node->traverse(this);
+ return mHasLoop;
+}
+
+bool DetectAnyLoop::visitLoop(Visit visit, TIntermLoop *loop)
+{
+ mHasLoop = true;
+ return false;
+}
+
+// The following definitions stop all traversal when we have found a loop
+bool DetectAnyLoop::visitBinary(Visit, TIntermBinary *)
+{
+ return !mHasLoop;
+}
+
+bool DetectAnyLoop::visitUnary(Visit, TIntermUnary *)
+{
+ return !mHasLoop;
+}
+
+bool DetectAnyLoop::visitSelection(Visit, TIntermSelection *)
+{
+ return !mHasLoop;
+}
+
+bool DetectAnyLoop::visitAggregate(Visit, TIntermAggregate *)
+{
+ return !mHasLoop;
+}
+
+bool DetectAnyLoop::visitBranch(Visit, TIntermBranch *)
+{
+ return !mHasLoop;
+}
+
+bool containsAnyLoop(TIntermNode *node)
+{
+ DetectAnyLoop detectAnyLoop;
+ return detectAnyLoop.traverse(node);
+}
+
+// Detect Gradient Operation
+
bool DetectGradientOperation::traverse(TIntermNode *node)
{
mGradientOperation = false;
diff --git a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h
index 35d66cbc2e..67e37be398 100644
--- a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h
+++ b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h
@@ -32,6 +32,25 @@ class DetectLoopDiscontinuity : public TIntermTraverser
bool containsLoopDiscontinuity(TIntermNode *node);
+// Checks for the existence of any loop
+class DetectAnyLoop : public TIntermTraverser
+{
+public:
+ bool traverse(TIntermNode *node);
+
+protected:
+ bool visitBinary(Visit, TIntermBinary *);
+ bool visitUnary(Visit, TIntermUnary *);
+ bool visitSelection(Visit, TIntermSelection *);
+ bool visitAggregate(Visit, TIntermAggregate *);
+ bool visitLoop(Visit, TIntermLoop *);
+ bool visitBranch(Visit, TIntermBranch *);
+
+ bool mHasLoop;
+};
+
+bool containsAnyLoop(TIntermNode *node);
+
// Checks for intrinsic functions which compute gradients
class DetectGradientOperation : public TIntermTraverser
{
diff --git a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp
index 59d2835f7b..f67a03aa93 100644
--- a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp
@@ -13,10 +13,10 @@
static TBehavior getBehavior(const std::string& str)
{
- static const std::string kRequire("require");
- static const std::string kEnable("enable");
- static const std::string kDisable("disable");
- static const std::string kWarn("warn");
+ const char kRequire[] = "require";
+ const char kEnable[] = "enable";
+ const char kDisable[] = "disable";
+ const char kWarn[] = "warn";
if (str == kRequire) return EBhRequire;
else if (str == kEnable) return EBhEnable;
@@ -46,50 +46,61 @@ void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
const std::string& name,
- const std::string& value)
+ const std::string& value,
+ bool stdgl)
{
- static const std::string kSTDGL("STDGL");
- static const std::string kOptimize("optimize");
- static const std::string kDebug("debug");
- static const std::string kOn("on");
- static const std::string kOff("off");
-
- bool invalidValue = false;
- if (name == kSTDGL)
+ if (stdgl)
{
+ const char kInvariant[] = "invariant";
+ const char kAll[] = "all";
+
+ if (name == kInvariant && value == kAll)
+ mPragma.stdgl.invariantAll = true;
// The STDGL pragma is used to reserve pragmas for use by future
- // revisions of GLSL. Ignore it.
+ // revisions of GLSL. Do not generate an error on unexpected
+ // name and value.
return;
}
- else if (name == kOptimize)
- {
- if (value == kOn) mPragma.optimize = true;
- else if (value == kOff) mPragma.optimize = false;
- else invalidValue = true;
- }
- else if (name == kDebug)
- {
- if (value == kOn) mPragma.debug = true;
- else if (value == kOff) mPragma.debug = false;
- else invalidValue = true;
- }
else
{
- mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
- return;
- }
+ const char kOptimize[] = "optimize";
+ const char kDebug[] = "debug";
+ const char kOn[] = "on";
+ const char kOff[] = "off";
- if (invalidValue)
- mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
- "invalid pragma value", value,
- "'on' or 'off' expected");
+ bool invalidValue = false;
+ if (name == kOptimize)
+ {
+ if (value == kOn) mPragma.optimize = true;
+ else if (value == kOff) mPragma.optimize = false;
+ else invalidValue = true;
+ }
+ else if (name == kDebug)
+ {
+ if (value == kOn) mPragma.debug = true;
+ else if (value == kOff) mPragma.debug = false;
+ else invalidValue = true;
+ }
+ else
+ {
+ mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
+ return;
+ }
+
+ if (invalidValue)
+ {
+ mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+ "invalid pragma value", value,
+ "'on' or 'off' expected");
+ }
+ }
}
void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
const std::string& name,
const std::string& behavior)
{
- static const std::string kExtAll("all");
+ const char kExtAll[] = "all";
TBehavior behaviorVal = getBehavior(behavior);
if (behaviorVal == EBhUndefined)
diff --git a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h
index 69418c277a..0433c3bf89 100644
--- a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h
+++ b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h
@@ -29,7 +29,8 @@ class TDirectiveHandler : public pp::DirectiveHandler
virtual void handlePragma(const pp::SourceLocation& loc,
const std::string& name,
- const std::string& value);
+ const std::string& value,
+ bool stdgl);
virtual void handleExtension(const pp::SourceLocation& loc,
const std::string& name,
diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp b/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp
index b155545ad2..aa0f31d170 100644
--- a/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp
@@ -133,6 +133,14 @@ bool CompareStructure(const TType &leftNodeType,
//
////////////////////////////////////////////////////////////////
+void TIntermTyped::setTypePreservePrecision(const TType &t)
+{
+ TPrecision precision = getPrecision();
+ mType = t;
+ ASSERT(mType.getBasicType() != EbtBool || precision == EbpUndefined);
+ mType.setPrecision(precision);
+}
+
#define REPLACE_IF_IS(node, type, original, replacement) \
if (node == original) { \
node = static_cast<type *>(replacement); \
@@ -237,6 +245,52 @@ void TIntermAggregate::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) con
}
}
+void TIntermAggregate::setPrecisionFromChildren()
+{
+ if (getBasicType() == EbtBool)
+ {
+ mType.setPrecision(EbpUndefined);
+ return;
+ }
+
+ TPrecision precision = EbpUndefined;
+ TIntermSequence::iterator childIter = mSequence.begin();
+ while (childIter != mSequence.end())
+ {
+ TIntermTyped *typed = (*childIter)->getAsTyped();
+ if (typed)
+ precision = GetHigherPrecision(typed->getPrecision(), precision);
+ ++childIter;
+ }
+ mType.setPrecision(precision);
+}
+
+void TIntermAggregate::setBuiltInFunctionPrecision()
+{
+ // All built-ins returning bool should be handled as ops, not functions.
+ ASSERT(getBasicType() != EbtBool);
+
+ TPrecision precision = EbpUndefined;
+ TIntermSequence::iterator childIter = mSequence.begin();
+ while (childIter != mSequence.end())
+ {
+ TIntermTyped *typed = (*childIter)->getAsTyped();
+ // ESSL spec section 8: texture functions get their precision from the sampler.
+ if (typed && IsSampler(typed->getBasicType()))
+ {
+ precision = typed->getPrecision();
+ break;
+ }
+ ++childIter;
+ }
+ // ESSL 3.0 spec section 8: textureSize always gets highp precision.
+ // All other functions that take a sampler are assumed to be texture functions.
+ if (mName.find("textureSize") == 0)
+ mType.setPrecision(EbpHigh);
+ else
+ mType.setPrecision(precision);
+}
+
bool TIntermSelection::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -336,6 +390,7 @@ bool TIntermUnary::promote(TInfoSink &)
return false;
break;
case EOpNegative:
+ case EOpPositive:
case EOpPostIncrement:
case EOpPostDecrement:
case EOpPreIncrement:
@@ -1068,6 +1123,27 @@ TIntermTyped *TIntermConstantUnion::fold(
}
break;
+ case EOpPositive:
+ switch (getType().getBasicType())
+ {
+ case EbtFloat:
+ tempConstArray[i].setFConst(unionArray[i].getFConst());
+ break;
+ case EbtInt:
+ tempConstArray[i].setIConst(unionArray[i].getIConst());
+ break;
+ case EbtUInt:
+ tempConstArray[i].setUConst(static_cast<unsigned int>(
+ static_cast<int>(unionArray[i].getUConst())));
+ break;
+ default:
+ infoSink.info.message(
+ EPrefixInternalError, getLine(),
+ "Unary operation not folded into constant");
+ return NULL;
+ }
+ break;
+
case EOpLogicalNot:
// this code is written for possible future use,
// will not get executed currently
diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode.h b/src/3rdparty/angle/src/compiler/translator/IntermNode.h
index ec440da010..32c70f4671 100644
--- a/src/3rdparty/angle/src/compiler/translator/IntermNode.h
+++ b/src/3rdparty/angle/src/compiler/translator/IntermNode.h
@@ -45,6 +45,7 @@ enum TOperator
//
EOpNegative,
+ EOpPositive,
EOpLogicalNot,
EOpVectorLogicalNot,
@@ -265,6 +266,7 @@ class TIntermTyped : public TIntermNode
virtual bool hasSideEffects() const = 0;
void setType(const TType &t) { mType = t; }
+ void setTypePreservePrecision(const TType &t);
const TType &getType() const { return mType; }
TType *getTypePointer() { return &mType; }
@@ -613,6 +615,9 @@ class TIntermAggregate : public TIntermOperator
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
+ void setPrecisionFromChildren();
+ void setBuiltInFunctionPrecision();
+
protected:
TIntermAggregate(const TIntermAggregate &); // disallow copy constructor
TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator
diff --git a/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp b/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp
index ef4f83307c..e558683c55 100644
--- a/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp
@@ -198,6 +198,7 @@ TIntermTyped *TIntermediate::addUnaryMath(
case EOpPostDecrement:
case EOpPreDecrement:
case EOpNegative:
+ case EOpPositive:
if (child->getType().getBasicType() == EbtStruct ||
child->getType().isArray())
{
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
index 6d07cccc04..ed590967b1 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp
@@ -395,6 +395,7 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
switch (node->getOp())
{
case EOpNegative: preString = "(-"; break;
+ case EOpPositive: preString = "(+"; break;
case EOpVectorLogicalNot: preString = "not("; break;
case EOpLogicalNot: preString = "(!"; break;
@@ -574,7 +575,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
// Function declaration.
ASSERT(visit == PreVisit);
writeVariableType(node->getType());
- out << " " << hashName(node->getName());
+ out << " " << hashFunctionName(node->getName());
out << "(";
writeFunctionParameters(*(node->getSequence()));
@@ -649,17 +650,18 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
mDeclaringVariables = false;
}
break;
- case EOpInvariantDeclaration: {
- // Invariant declaration.
- ASSERT(visit == PreVisit);
+ case EOpInvariantDeclaration:
+ // Invariant declaration.
+ ASSERT(visit == PreVisit);
+ {
const TIntermSequence *sequence = node->getSequence();
ASSERT(sequence && sequence->size() == 1);
const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
ASSERT(symbol);
- out << "invariant " << symbol->getSymbol() << ";";
- visitChildren = false;
- break;
+ out << "invariant " << hashVariableName(symbol->getSymbol());
}
+ visitChildren = false;
+ break;
case EOpConstructFloat:
writeTriplet(visit, "float(", NULL, ")");
break;
@@ -741,7 +743,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction);
break;
case EOpComma:
- writeTriplet(visit, NULL, ", ", NULL);
+ writeTriplet(visit, "(", ", ", ")");
break;
case EOpMod:
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
index a5ea71599d..30bbbff0f5 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp
@@ -135,6 +135,7 @@ OutputHLSL::OutputHLSL(TParseContext &context, TranslatorHLSL *parentTranslator)
mUniqueIndex = 0;
mContainsLoopDiscontinuity = false;
+ mContainsAnyLoop = false;
mOutputLod0Function = false;
mInsideDiscontinuousLoop = false;
mNestedLoopDepth = 0;
@@ -172,6 +173,7 @@ OutputHLSL::~OutputHLSL()
void OutputHLSL::output()
{
mContainsLoopDiscontinuity = mContext.shaderType == GL_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot);
+ mContainsAnyLoop = containsAnyLoop(mContext.treeRoot);
const std::vector<TIntermTyped*> &flaggedStructs = FlagStd140ValueStructs(mContext.treeRoot);
makeFlaggedStructMaps(flaggedStructs);
@@ -320,14 +322,22 @@ void OutputHLSL::header()
if (mUsesDiscardRewriting)
{
- out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n";
+ out << "#define ANGLE_USES_DISCARD_REWRITING\n";
}
if (mUsesNestedBreak)
{
- out << "#define ANGLE_USES_NESTED_BREAK" << "\n";
+ out << "#define ANGLE_USES_NESTED_BREAK\n";
}
+ out << "#ifdef ANGLE_ENABLE_LOOP_FLATTEN\n"
+ "#define LOOP [loop]\n"
+ "#define FLATTEN [flatten]\n"
+ "#else\n"
+ "#define LOOP\n"
+ "#define FLATTEN\n"
+ "#endif\n";
+
if (mContext.shaderType == GL_FRAGMENT_SHADER)
{
TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
@@ -1747,6 +1757,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
switch (node->getOp())
{
case EOpNegative: outputTriplet(visit, "(-", "", ")"); break;
+ case EOpPositive: outputTriplet(visit, "(+", "", ")"); break;
case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break;
@@ -1860,15 +1871,20 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
{
- if (!mInsideFunction)
+ for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
{
- out << "static ";
- }
+ if (isSingleStatement(*sit))
+ {
+ mUnfoldShortCircuit->traverse(*sit);
+ }
- out << TypeString(variable->getType()) + " ";
+ if (!mInsideFunction)
+ {
+ out << "static ";
+ }
+
+ out << TypeString(variable->getType()) + " ";
- for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
- {
TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
if (symbol)
@@ -1884,7 +1900,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
if (*sit != sequence->back())
{
- out << ", ";
+ out << ";\n";
}
}
}
@@ -1925,7 +1941,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpPrototype:
if (visit == PreVisit)
{
- out << TypeString(node->getType()) << " " << Decorate(node->getName()) << (mOutputLod0Function ? "Lod0(" : "(");
+ out << TypeString(node->getType()) << " " << Decorate(TFunction::unmangleName(node->getName())) << (mOutputLod0Function ? "Lod0(" : "(");
TIntermSequence *arguments = node->getSequence();
@@ -2287,6 +2303,15 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
{
mUnfoldShortCircuit->traverse(node->getCondition());
+ // D3D errors when there is a gradient operation in a loop in an unflattened if
+ // 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)
+ {
+ out << "FLATTEN ";
+ }
+
out << "if (";
node->getCondition()->traverse(this);
@@ -2367,14 +2392,14 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
if (node->getType() == ELoopDoWhile)
{
- out << "{do\n";
+ out << "{LOOP do\n";
outputLineDirective(node->getLine().first_line);
out << "{\n";
}
else
{
- out << "{for(";
+ out << "{LOOP for(";
if (node->getInit())
{
@@ -2503,6 +2528,12 @@ bool OutputHLSL::isSingleStatement(TIntermNode *node)
{
return false;
}
+ else if (aggregate->getOp() == EOpDeclaration)
+ {
+ // Declaring multiple comma-separated variables must be considered multiple statements
+ // because each individual declaration has side effects which are visible in the next.
+ return false;
+ }
else
{
for (TIntermSequence::iterator sit = aggregate->getSequence()->begin(); sit != aggregate->getSequence()->end(); sit++)
@@ -2675,7 +2706,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
// for(int index = initial; index < clampedLimit; index += increment)
- out << "for(";
+ out << "LOOP for(";
index->traverse(this);
out << " = ";
out << initial;
diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h
index bec02479bb..5525e6eaa6 100644
--- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h
@@ -144,6 +144,7 @@ class OutputHLSL : public TIntermTraverser
int mUniqueIndex; // For creating unique names
bool mContainsLoopDiscontinuity;
+ bool mContainsAnyLoop;
bool mOutputLod0Function;
bool mInsideDiscontinuousLoop;
int mNestedLoopDepth;
diff --git a/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp b/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp
index ff0a49667c..37969b5468 100644
--- a/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp
@@ -1004,12 +1004,12 @@ void TParseContext::handleExtensionDirective(const TSourceLoc& loc, const char*
directiveHandler.handleExtension(srcLoc, extName, behavior);
}
-void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value)
+void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl)
{
pp::SourceLocation srcLoc;
srcLoc.file = loc.first_file;
srcLoc.line = loc.first_line;
- directiveHandler.handlePragma(srcLoc, name, value);
+ directiveHandler.handlePragma(srcLoc, name, value, stdgl);
}
/////////////////////////////////////////////////////////////////////////////////
@@ -1364,11 +1364,18 @@ TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &inv
{
error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
recover();
-
return NULL;
}
else
{
+ const TString kGlFrontFacing("gl_FrontFacing");
+ if (*identifier == kGlFrontFacing)
+ {
+ error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
+ recover();
+ return NULL;
+ }
+ symbolTable.addInvariantVarying(*identifier);
const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
ASSERT(variable);
const TType &type = variable->getType();
diff --git a/src/3rdparty/angle/src/compiler/translator/ParseContext.h b/src/3rdparty/angle/src/compiler/translator/ParseContext.h
index 1f4cbdeba9..414c475cbb 100644
--- a/src/3rdparty/angle/src/compiler/translator/ParseContext.h
+++ b/src/3rdparty/angle/src/compiler/translator/ParseContext.h
@@ -116,7 +116,7 @@ struct TParseContext {
bool supportsExtension(const char* extension);
bool isExtensionEnabled(const char* extension) const;
void handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior);
- void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value);
+ void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl);
bool containsSampler(TType& type);
bool areAllChildConst(TIntermAggregate* aggrNode);
diff --git a/src/3rdparty/angle/src/compiler/translator/Pragma.h b/src/3rdparty/angle/src/compiler/translator/Pragma.h
index 2f744123b8..4a930a2962 100644
--- a/src/3rdparty/angle/src/compiler/translator/Pragma.h
+++ b/src/3rdparty/angle/src/compiler/translator/Pragma.h
@@ -7,13 +7,23 @@
#ifndef COMPILER_PRAGMA_H_
#define COMPILER_PRAGMA_H_
-struct TPragma {
+struct TPragma
+{
+ struct STDGL
+ {
+ STDGL() : invariantAll(false) { }
+
+ bool invariantAll;
+ };
+
+
// By default optimization is turned on and debug is turned off.
TPragma() : optimize(true), debug(false) { }
TPragma(bool o, bool d) : optimize(o), debug(d) { }
bool optimize;
bool debug;
+ STDGL stdgl;
};
#endif // COMPILER_PRAGMA_H_
diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp
index 20ce71605c..0d6a1d64cf 100644
--- a/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp
@@ -37,72 +37,6 @@ bool isInitialized = false;
// and the shading language compiler.
//
-static bool CheckVariableMaxLengths(const ShHandle handle,
- size_t expectedValue)
-{
- size_t activeUniformLimit = 0;
- ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
- size_t activeAttribLimit = 0;
- ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
- size_t varyingLimit = 0;
- ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit);
- return (expectedValue == activeUniformLimit &&
- expectedValue == activeAttribLimit &&
- expectedValue == varyingLimit);
-}
-
-bool CheckMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
-{
- size_t mappedNameMaxLength = 0;
- ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
- return (expectedValue == mappedNameMaxLength);
-}
-
-template <typename VarT>
-const sh::ShaderVariable *ReturnVariable(const std::vector<VarT> &infoList, int index)
-{
- if (index < 0 || static_cast<size_t>(index) >= infoList.size())
- {
- return NULL;
- }
-
- return &infoList[index];
-}
-
-const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShaderInfo varType, int index)
-{
- switch (varType)
- {
- case SH_ACTIVE_ATTRIBUTES:
- return ReturnVariable(compiler->getAttributes(), index);
- case SH_ACTIVE_UNIFORMS:
- return ReturnVariable(compiler->getExpandedUniforms(), index);
- case SH_VARYINGS:
- return ReturnVariable(compiler->getExpandedVaryings(), index);
- default:
- UNREACHABLE();
- return NULL;
- }
-}
-
-ShPrecisionType ConvertPrecision(sh::GLenum precision)
-{
- switch (precision)
- {
- case GL_HIGH_FLOAT:
- case GL_HIGH_INT:
- return SH_PRECISION_HIGHP;
- case GL_MEDIUM_FLOAT:
- case GL_MEDIUM_INT:
- return SH_PRECISION_MEDIUMP;
- case GL_LOW_FLOAT:
- case GL_LOW_INT:
- return SH_PRECISION_LOWP;
- default:
- return SH_PRECISION_UNDEFINED;
- }
-}
-
template <typename VarT>
const std::vector<VarT> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType);
@@ -150,32 +84,48 @@ const std::vector<VarT> *GetShaderVariables(const ShHandle handle, ShaderVariabl
return GetVariableList<VarT>(compiler, variableType);
}
+TCompiler *GetCompilerFromHandle(ShHandle handle)
+{
+ if (!handle)
+ return NULL;
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ return base->getAsCompiler();
}
+TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
+{
+ if (!handle)
+ return NULL;
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ return base->getAsTranslatorHLSL();
+}
+
+} // namespace anonymous
+
//
// Driver must call this first, once, before doing any other compiler operations.
// Subsequent calls to this function are no-op.
//
-int ShInitialize()
+bool ShInitialize()
{
if (!isInitialized)
{
isInitialized = InitProcess();
}
- return isInitialized ? 1 : 0;
+ return isInitialized;
}
//
// Cleanup symbol tables
//
-int ShFinalize()
+bool ShFinalize()
{
if (isInitialized)
{
DetachProcess();
isInitialized = false;
}
- return 1;
+ return true;
}
//
@@ -183,6 +133,9 @@ int ShFinalize()
//
void ShInitBuiltInResources(ShBuiltInResources* resources)
{
+ // Make comparable.
+ memset(resources, 0, sizeof(*resources));
+
// Constants.
resources->MaxVertexAttribs = 8;
resources->MaxVertexUniformVectors = 128;
@@ -201,6 +154,8 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->EXT_frag_depth = 0;
resources->EXT_shader_texture_lod = 0;
+ resources->NV_draw_buffers = 0;
+
// Disable highp precision in fragment shader by default.
resources->FragmentPrecisionHigh = 0;
@@ -251,23 +206,13 @@ void ShDestruct(ShHandle handle)
DeleteCompiler(base->getAsCompiler());
}
-void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outString)
+const std::string &ShGetBuiltInResourcesString(const ShHandle handle)
{
- if (!handle || !outString)
- {
- return;
- }
-
- TShHandleBase *base = static_cast<TShHandleBase*>(handle);
- TCompiler *compiler = base->getAsCompiler();
- if (!compiler)
- {
- return;
- }
-
- strncpy(outString, compiler->getBuiltInResourcesString().c_str(), outStringLen);
- outString[outStringLen - 1] = '\0';
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getBuiltInResourcesString();
}
+
//
// Do an actual compile on the given strings. The result is left
// in the given compile object.
@@ -275,219 +220,62 @@ void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, cha
// Return: The return value of ShCompile is really boolean, indicating
// success or failure.
//
-int ShCompile(
+bool ShCompile(
const ShHandle handle,
- const char* const shaderStrings[],
+ const char *const shaderStrings[],
size_t numStrings,
int compileOptions)
{
- if (handle == 0)
- return 0;
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (compiler == 0)
- return 0;
-
- bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
- return success ? 1 : 0;
+ return compiler->compile(shaderStrings, numStrings, compileOptions);
}
-void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
+int ShGetShaderVersion(const ShHandle handle)
{
- if (!handle || !params)
- return;
-
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (!compiler) return;
+ TCompiler* compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getShaderVersion();
+}
- switch(pname)
- {
- case SH_INFO_LOG_LENGTH:
- *params = compiler->getInfoSink().info.size() + 1;
- break;
- case SH_OBJECT_CODE_LENGTH:
- *params = compiler->getInfoSink().obj.size() + 1;
- break;
- case SH_ACTIVE_UNIFORMS:
- *params = compiler->getExpandedUniforms().size();
- break;
- case SH_ACTIVE_UNIFORM_MAX_LENGTH:
- *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- break;
- case SH_ACTIVE_ATTRIBUTES:
- *params = compiler->getAttributes().size();
- break;
- case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
- *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- break;
- case SH_VARYINGS:
- *params = compiler->getExpandedVaryings().size();
- break;
- case SH_VARYING_MAX_LENGTH:
- *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- break;
- case SH_MAPPED_NAME_MAX_LENGTH:
- // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
- // handle array and struct dereferences.
- *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- break;
- case SH_NAME_MAX_LENGTH:
- *params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- break;
- case SH_HASHED_NAME_MAX_LENGTH:
- if (compiler->getHashFunction() == NULL) {
- *params = 0;
- } else {
- // 64 bits hashing output requires 16 bytes for hex
- // representation.
- const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
- (void)HashedNamePrefix;
- *params = 16 + sizeof(HashedNamePrefix);
- }
- break;
- case SH_HASHED_NAMES_COUNT:
- *params = compiler->getNameMap().size();
- break;
- case SH_SHADER_VERSION:
- *params = compiler->getShaderVersion();
- break;
- case SH_RESOURCES_STRING_LENGTH:
- *params = compiler->getBuiltInResourcesString().length() + 1;
- break;
- case SH_OUTPUT_TYPE:
- *params = compiler->getOutputType();
- break;
- default: UNREACHABLE();
- }
+ShShaderOutput ShGetShaderOutputType(const ShHandle handle)
+{
+ TCompiler* compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getOutputType();
}
//
// Return any compiler log of messages for the application.
//
-void ShGetInfoLog(const ShHandle handle, char* infoLog)
+const std::string &ShGetInfoLog(const ShHandle handle)
{
- if (!handle || !infoLog)
- return;
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (!compiler) return;
-
- TInfoSink& infoSink = compiler->getInfoSink();
- strcpy(infoLog, infoSink.info.c_str());
+ TInfoSink &infoSink = compiler->getInfoSink();
+ return infoSink.info.str();
}
//
// Return any object code.
//
-void ShGetObjectCode(const ShHandle handle, char* objCode)
+const std::string &ShGetObjectCode(const ShHandle handle)
{
- if (!handle || !objCode)
- return;
-
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (!compiler) return;
-
- TInfoSink& infoSink = compiler->getInfoSink();
- strcpy(objCode, infoSink.obj.c_str());
-}
-
-void ShGetVariableInfo(const ShHandle handle,
- ShShaderInfo varType,
- int index,
- size_t* length,
- int* size,
- sh::GLenum* type,
- ShPrecisionType* precision,
- int* staticUse,
- char* name,
- char* mappedName)
-{
- if (!handle || !size || !type || !precision || !staticUse || !name)
- return;
- ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
- (varType == SH_ACTIVE_UNIFORMS) ||
- (varType == SH_VARYINGS));
-
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (compiler == 0)
- return;
-
- const sh::ShaderVariable *varInfo = GetVariable(compiler, varType, index);
- if (!varInfo)
- {
- return;
- }
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
- if (length) *length = varInfo->name.size();
- *size = varInfo->elementCount();
- *type = varInfo->type;
- *precision = ConvertPrecision(varInfo->precision);
- *staticUse = varInfo->staticUse ? 1 : 0;
-
- // This size must match that queried by
- // SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
- // in ShGetInfo, below.
- size_t variableLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- ASSERT(CheckVariableMaxLengths(handle, variableLength));
- strncpy(name, varInfo->name.c_str(), variableLength);
- name[variableLength - 1] = 0;
- if (mappedName)
- {
- // This size must match that queried by
- // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
- size_t maxMappedNameLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
- ASSERT(CheckMappedNameMaxLength(handle, maxMappedNameLength));
- strncpy(mappedName, varInfo->mappedName.c_str(), maxMappedNameLength);
- mappedName[maxMappedNameLength - 1] = 0;
- }
+ TInfoSink &infoSink = compiler->getInfoSink();
+ return infoSink.obj.str();
}
-void ShGetNameHashingEntry(const ShHandle handle,
- int index,
- char* name,
- char* hashedName)
+const std::map<std::string, std::string> *ShGetNameHashingMap(
+ const ShHandle handle)
{
- if (!handle || !name || !hashedName || index < 0)
- return;
-
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (!compiler) return;
-
- const NameMap& nameMap = compiler->getNameMap();
- if (index >= static_cast<int>(nameMap.size()))
- return;
-
- NameMap::const_iterator it = nameMap.begin();
- for (int i = 0; i < index; ++i)
- ++it;
-
- size_t len = it->first.length() + 1;
- size_t max_len = 0;
- ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
- if (len > max_len) {
- ASSERT(false);
- len = max_len;
- }
- strncpy(name, it->first.c_str(), len);
- // To be on the safe side in case the source is longer than expected.
- name[len - 1] = '\0';
-
- len = it->second.length() + 1;
- max_len = 0;
- ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
- if (len > max_len) {
- ASSERT(false);
- len = max_len;
- }
- strncpy(hashedName, it->second.c_str(), len);
- // To be on the safe side in case the source is longer than expected.
- hashedName[len - 1] = '\0';
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return &(compiler->getNameMap());
}
const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
@@ -515,11 +303,11 @@ const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handl
return GetShaderVariables<sh::InterfaceBlock>(handle, SHADERVAR_INTERFACEBLOCK);
}
-int ShCheckVariablesWithinPackingLimits(
- int maxVectors, ShVariableInfo* varInfoArray, size_t varInfoArraySize)
+bool ShCheckVariablesWithinPackingLimits(
+ int maxVectors, ShVariableInfo *varInfoArray, size_t varInfoArraySize)
{
if (varInfoArraySize == 0)
- return 1;
+ return true;
ASSERT(varInfoArray);
std::vector<sh::ShaderVariable> variables;
for (size_t ii = 0; ii < varInfoArraySize; ++ii)
@@ -528,24 +316,17 @@ int ShCheckVariablesWithinPackingLimits(
variables.push_back(var);
}
VariablePacker packer;
- return packer.CheckVariablesWithinPackingLimits(maxVectors, variables) ? 1 : 0;
+ return packer.CheckVariablesWithinPackingLimits(maxVectors, variables);
}
bool ShGetInterfaceBlockRegister(const ShHandle handle,
- const char *interfaceBlockName,
+ const std::string &interfaceBlockName,
unsigned int *indexOut)
{
- if (!handle || !interfaceBlockName || !indexOut)
- {
- return false;
- }
+ ASSERT(indexOut);
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TranslatorHLSL* translator = base->getAsTranslatorHLSL();
- if (!translator)
- {
- return false;
- }
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
if (!translator->hasInterfaceBlock(interfaceBlockName))
{
@@ -557,20 +338,12 @@ bool ShGetInterfaceBlockRegister(const ShHandle handle,
}
bool ShGetUniformRegister(const ShHandle handle,
- const char *uniformName,
+ const std::string &uniformName,
unsigned int *indexOut)
{
- if (!handle || !uniformName || !indexOut)
- {
- return false;
- }
-
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TranslatorHLSL* translator = base->getAsTranslatorHLSL();
- if (!translator)
- {
- return false;
- }
+ ASSERT(indexOut);
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
if (!translator->hasUniform(uniformName))
{
diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
index 822c558c9b..3098a7f0c9 100644
--- a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp
@@ -9,6 +9,8 @@
#include <GLSLANG/ShaderLang.h>
+#include "compiler/translator/compilerdebug.h"
+
namespace sh
{
@@ -53,6 +55,126 @@ ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
return *this;
}
+bool ShaderVariable::operator==(const ShaderVariable &other) const
+{
+ if (type != other.type ||
+ precision != other.precision ||
+ name != other.name ||
+ mappedName != other.mappedName ||
+ arraySize != other.arraySize ||
+ staticUse != other.staticUse ||
+ fields.size() != other.fields.size() ||
+ structName != other.structName)
+ {
+ return false;
+ }
+ for (size_t ii = 0; ii < fields.size(); ++ii)
+ {
+ if (fields[ii] != other.fields[ii])
+ return false;
+ }
+ return true;
+}
+
+bool ShaderVariable::findInfoByMappedName(
+ const std::string &mappedFullName,
+ const ShaderVariable **leafVar, std::string *originalFullName) const
+{
+ ASSERT(leafVar && originalFullName);
+ // There are three cases:
+ // 1) the top variable is of struct type;
+ // 2) the top variable is an array;
+ // 3) otherwise.
+ size_t pos = mappedFullName.find_first_of(".[");
+ std::string topName;
+
+ if (pos == std::string::npos)
+ {
+ // Case 3.
+ if (mappedFullName != this->mappedName)
+ return false;
+ *originalFullName = this->name;
+ *leafVar = this;
+ return true;
+ }
+ else
+ {
+ std::string topName = mappedFullName.substr(0, pos);
+ if (topName != this->mappedName)
+ return false;
+ std::string originalName = this->name;
+ std::string remaining;
+ if (mappedFullName[pos] == '[')
+ {
+ // Case 2.
+ size_t closePos = mappedFullName.find_first_of(']');
+ if (closePos < pos || closePos == std::string::npos)
+ return false;
+ // Append '[index]'.
+ originalName += mappedFullName.substr(pos, closePos - pos + 1);
+ if (closePos + 1 == mappedFullName.size())
+ {
+ *originalFullName = originalName;
+ *leafVar = this;
+ return true;
+ }
+ else
+ {
+ // In the form of 'a[0].b', so after ']', '.' is expected.
+ if (mappedFullName[closePos + 1] != '.')
+ return false;
+ remaining = mappedFullName.substr(closePos + 2); // Skip "]."
+ }
+ }
+ else
+ {
+ // Case 1.
+ remaining = mappedFullName.substr(pos + 1); // Skip "."
+ }
+ for (size_t ii = 0; ii < this->fields.size(); ++ii)
+ {
+ const ShaderVariable *fieldVar = NULL;
+ std::string originalFieldName;
+ bool found = fields[ii].findInfoByMappedName(
+ remaining, &fieldVar, &originalFieldName);
+ if (found)
+ {
+ *originalFullName = originalName + "." + originalFieldName;
+ *leafVar = fieldVar;
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+bool ShaderVariable::isSameVariableAtLinkTime(
+ const ShaderVariable &other, bool matchPrecision) const
+{
+ if (type != other.type)
+ return false;
+ if (matchPrecision && precision != other.precision)
+ return false;
+ if (name != other.name)
+ return false;
+ ASSERT(mappedName == other.mappedName);
+ if (arraySize != other.arraySize)
+ return false;
+ if (fields.size() != other.fields.size())
+ return false;
+ for (size_t ii = 0; ii < fields.size(); ++ii)
+ {
+ if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii],
+ matchPrecision))
+ {
+ return false;
+ }
+ }
+ if (structName != other.structName)
+ return false;
+ return true;
+}
+
Uniform::Uniform()
{}
@@ -69,6 +191,16 @@ Uniform &Uniform::operator=(const Uniform &other)
return *this;
}
+bool Uniform::operator==(const Uniform &other) const
+{
+ return ShaderVariable::operator==(other);
+}
+
+bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
+{
+ return ShaderVariable::isSameVariableAtLinkTime(other, true);
+}
+
Attribute::Attribute()
: location(-1)
{}
@@ -88,6 +220,12 @@ Attribute &Attribute::operator=(const Attribute &other)
return *this;
}
+bool Attribute::operator==(const Attribute &other) const
+{
+ return (ShaderVariable::operator==(other) &&
+ location == other.location);
+}
+
InterfaceBlockField::InterfaceBlockField()
: isRowMajorLayout(false)
{}
@@ -107,6 +245,19 @@ InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &o
return *this;
}
+bool InterfaceBlockField::operator==(const InterfaceBlockField &other) const
+{
+ return (ShaderVariable::operator==(other) &&
+ isRowMajorLayout == other.isRowMajorLayout);
+}
+
+bool InterfaceBlockField::isSameInterfaceBlockFieldAtLinkTime(
+ const InterfaceBlockField &other) const
+{
+ return (ShaderVariable::isSameVariableAtLinkTime(other, true) &&
+ isRowMajorLayout == other.isRowMajorLayout);
+}
+
Varying::Varying()
: interpolation(INTERPOLATION_SMOOTH),
isInvariant(false)
@@ -129,6 +280,20 @@ Varying &Varying::operator=(const Varying &other)
return *this;
}
+bool Varying::operator==(const Varying &other) const
+{
+ return (ShaderVariable::operator==(other) &&
+ interpolation == other.interpolation &&
+ isInvariant == other.isInvariant);
+}
+
+bool Varying::isSameVaryingAtLinkTime(const Varying &other) const
+{
+ return (ShaderVariable::isSameVariableAtLinkTime(other, false) &&
+ interpolation == other.interpolation &&
+ isInvariant == other.isInvariant);
+}
+
InterfaceBlock::InterfaceBlock()
: arraySize(0),
layout(BLOCKLAYOUT_PACKED),
diff --git a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h
index 6b0e0c0a03..9cd74218dc 100644
--- a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h
+++ b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h
@@ -31,6 +31,7 @@
//
#include <assert.h>
+#include <set>
#include "common/angleutils.h"
#include "compiler/translator/InfoSink.h"
@@ -299,19 +300,21 @@ class TSymbolTableLevel
tLevel level;
};
-enum ESymbolLevel
-{
- COMMON_BUILTINS = 0,
- ESSL1_BUILTINS = 1,
- ESSL3_BUILTINS = 2,
- LAST_BUILTIN_LEVEL = ESSL3_BUILTINS,
- GLOBAL_LEVEL = 3
-};
+// Define ESymbolLevel as int rather than an enum since level can go
+// above GLOBAL_LEVEL and cause atBuiltInLevel() to fail if the
+// compiler optimizes the >= of the last element to ==.
+typedef int ESymbolLevel;
+const int COMMON_BUILTINS = 0;
+const int ESSL1_BUILTINS = 1;
+const int ESSL3_BUILTINS = 2;
+const int LAST_BUILTIN_LEVEL = ESSL3_BUILTINS;
+const int GLOBAL_LEVEL = 3;
class TSymbolTable
{
public:
TSymbolTable()
+ : mGlobalInvariant(false)
{
// The symbol table cannot be used until push() is called, but
// the lack of an initial call to push() can be used to detect
@@ -408,6 +411,25 @@ class TSymbolTable
// for the specified TBasicType
TPrecision getDefaultPrecision(TBasicType type) const;
+ // This records invariant varyings declared through
+ // "invariant varying_name;".
+ void addInvariantVarying(const TString &originalName)
+ {
+ mInvariantVaryings.insert(originalName);
+ }
+ // If this returns false, the varying could still be invariant
+ // if it is set as invariant during the varying variable
+ // declaration - this piece of information is stored in the
+ // variable's type, not here.
+ bool isVaryingInvariant(const TString &originalName) const
+ {
+ return (mGlobalInvariant ||
+ mInvariantVaryings.count(originalName) > 0);
+ }
+
+ void setGlobalInvariant() { mGlobalInvariant = true; }
+ bool getGlobalInvariant() const { return mGlobalInvariant; }
+
static int nextUniqueId()
{
return ++uniqueIdCounter;
@@ -423,6 +445,9 @@ class TSymbolTable
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
std::vector< PrecisionStackLevel *> precisionStack;
+ std::set<TString> mInvariantVaryings;
+ bool mGlobalInvariant;
+
static int uniqueIdCounter;
};
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp
index 5b99fea948..dcbf3cea1d 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp
@@ -16,6 +16,8 @@ TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
void TranslatorESSL::translate(TIntermNode* root) {
TInfoSinkBase& sink = getInfoSink().obj;
+ writePragma();
+
// Write built-in extension behaviors.
writeExtensionBehavior();
@@ -37,8 +39,13 @@ void TranslatorESSL::writeExtensionBehavior() {
for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
iter != extensionBehavior.end(); ++iter) {
if (iter->second != EBhUndefined) {
- sink << "#extension " << iter->first << " : "
- << getBehaviorString(iter->second) << "\n";
+ if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") {
+ sink << "#extension GL_NV_draw_buffers : "
+ << getBehaviorString(iter->second) << "\n";
+ } else {
+ sink << "#extension " << iter->first << " : "
+ << getBehaviorString(iter->second) << "\n";
+ }
}
}
}
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
index 4b2aecab33..6acbf7c5a8 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
@@ -9,18 +9,6 @@
#include "compiler/translator/OutputGLSL.h"
#include "compiler/translator/VersionGLSL.h"
-static void writeVersion(sh::GLenum type, TIntermNode* root,
- TInfoSinkBase& sink) {
- TVersionGLSL versionGLSL(type);
- root->traverse(&versionGLSL);
- int version = versionGLSL.getVersion();
- // We need to write version directive only if it is greater than 110.
- // If there is no version directive in the shader, 110 is implied.
- if (version > 110) {
- sink << "#version " << version << "\n";
- }
-}
-
TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec)
: TCompiler(type, spec, SH_GLSL_OUTPUT) {
}
@@ -29,7 +17,9 @@ void TranslatorGLSL::translate(TIntermNode* root) {
TInfoSinkBase& sink = getInfoSink().obj;
// Write GLSL version.
- writeVersion(getShaderType(), root, sink);
+ writeVersion(root);
+
+ writePragma();
// Write extension behaviour as needed
writeExtensionBehavior();
@@ -46,6 +36,20 @@ void TranslatorGLSL::translate(TIntermNode* root) {
root->traverse(&outputGLSL);
}
+void TranslatorGLSL::writeVersion(TIntermNode *root)
+{
+ TVersionGLSL versionGLSL(getShaderType(), getPragma());
+ root->traverse(&versionGLSL);
+ int version = versionGLSL.getVersion();
+ // We need to write version directive only if it is greater than 110.
+ // If there is no version directive in the shader, 110 is implied.
+ if (version > 110)
+ {
+ TInfoSinkBase& sink = getInfoSink().obj;
+ sink << "#version " << version << "\n";
+ }
+}
+
void TranslatorGLSL::writeExtensionBehavior() {
TInfoSinkBase& sink = getInfoSink().obj;
const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h
index 3c6c2e426a..766d8d910e 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h
@@ -9,14 +9,16 @@
#include "compiler/translator/Compiler.h"
-class TranslatorGLSL : public TCompiler {
-public:
+class TranslatorGLSL : public TCompiler
+{
+ public:
TranslatorGLSL(sh::GLenum type, ShShaderSpec spec);
-protected:
- virtual void translate(TIntermNode* root);
+ protected:
+ virtual void translate(TIntermNode *root);
-private:
+ private:
+ void writeVersion(TIntermNode *root);
void writeExtensionBehavior();
};
diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp
index c1a7b7524f..896e1cd7a0 100644
--- a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp
@@ -94,6 +94,7 @@ const char *GetOperatorString(TOperator op)
case EOpLogicalXor: return "^^";
case EOpLogicalAnd: return "&&";
case EOpNegative: return "-";
+ case EOpPositive: return "+";
case EOpVectorLogicalNot: return "not";
case EOpLogicalNot: return "!";
case EOpPostIncrement: return "++";
diff --git a/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp b/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp
index f26c1566ac..d8e13788b7 100644
--- a/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp
@@ -5,6 +5,7 @@
//
#include "angle_gl.h"
+#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/VariableInfo.h"
#include "compiler/translator/util.h"
#include "common/utilities.h"
@@ -131,7 +132,8 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
std::vector<sh::Uniform> *uniforms,
std::vector<sh::Varying> *varyings,
std::vector<sh::InterfaceBlock> *interfaceBlocks,
- ShHashFunction64 hashFunction)
+ ShHashFunction64 hashFunction,
+ const TSymbolTable &symbolTable)
: mAttribs(attribs),
mOutputVariables(outputVariables),
mUniforms(uniforms),
@@ -140,7 +142,10 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
mPointCoordAdded(false),
mFrontFacingAdded(false),
mFragCoordAdded(false),
- mHashFunction(hashFunction)
+ mPositionAdded(false),
+ mPointSizeAdded(false),
+ mHashFunction(hashFunction),
+ mSymbolTable(symbolTable)
{
}
@@ -200,12 +205,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
if (!mFragCoordAdded)
{
Varying info;
- info.name = "gl_FragCoord";
- info.mappedName = "gl_FragCoord";
+ const char kName[] = "gl_FragCoord";
+ info.name = kName;
+ info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
info.arraySize = 0;
- info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter.
+ info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
+ info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mFragCoordAdded = true;
}
@@ -214,12 +221,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
if (!mFrontFacingAdded)
{
Varying info;
- info.name = "gl_FrontFacing";
- info.mappedName = "gl_FrontFacing";
+ const char kName[] = "gl_FrontFacing";
+ info.name = kName;
+ info.mappedName = kName;
info.type = GL_BOOL;
info.arraySize = 0;
info.precision = GL_NONE;
info.staticUse = true;
+ info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mFrontFacingAdded = true;
}
@@ -228,16 +237,50 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
if (!mPointCoordAdded)
{
Varying info;
- info.name = "gl_PointCoord";
- info.mappedName = "gl_PointCoord";
+ const char kName[] = "gl_PointCoord";
+ info.name = kName;
+ info.mappedName = kName;
info.type = GL_FLOAT_VEC2;
info.arraySize = 0;
- info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter.
+ info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
+ info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mPointCoordAdded = true;
}
return;
+ case EvqPosition:
+ if (!mPositionAdded)
+ {
+ Varying info;
+ const char kName[] = "gl_Position";
+ info.name = kName;
+ info.mappedName = kName;
+ info.type = GL_FLOAT_VEC4;
+ info.arraySize = 0;
+ info.precision = GL_HIGH_FLOAT; // Defined by spec.
+ info.staticUse = true;
+ info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
+ mVaryings->push_back(info);
+ mPositionAdded = true;
+ }
+ return;
+ case EvqPointSize:
+ if (!mPointSizeAdded)
+ {
+ Varying info;
+ const char kName[] = "gl_PointSize";
+ info.name = kName;
+ info.mappedName = kName;
+ info.type = GL_FLOAT;
+ info.arraySize = 0;
+ info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
+ info.staticUse = true;
+ info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
+ mVaryings->push_back(info);
+ mPointSizeAdded = true;
+ }
+ return;
default:
break;
}
@@ -251,8 +294,10 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
class NameHashingTraverser : public GetVariableTraverser
{
public:
- NameHashingTraverser(ShHashFunction64 hashFunction)
- : mHashFunction(hashFunction)
+ NameHashingTraverser(ShHashFunction64 hashFunction,
+ const TSymbolTable &symbolTable)
+ : GetVariableTraverser(symbolTable),
+ mHashFunction(hashFunction)
{}
private:
@@ -312,7 +357,7 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable,
const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
const TType &fieldType = *field.type();
- GetVariableTraverser traverser;
+ GetVariableTraverser traverser(mSymbolTable);
traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
@@ -325,7 +370,7 @@ template <typename VarT>
void CollectVariables::visitVariable(const TIntermSymbol *variable,
std::vector<VarT> *infoList) const
{
- NameHashingTraverser traverser(mHashFunction);
+ NameHashingTraverser traverser(mHashFunction, mSymbolTable);
traverser.traverse(variable->getType(), variable->getSymbol(), infoList);
}
@@ -421,9 +466,8 @@ bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
return true;
}
-template <typename VarT>
-void ExpandVariables(const std::vector<VarT> &compact,
- std::vector<ShaderVariable> *expanded)
+void ExpandUniforms(const std::vector<Uniform> &compact,
+ std::vector<ShaderVariable> *expanded)
{
for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++)
{
@@ -432,7 +476,4 @@ void ExpandVariables(const std::vector<VarT> &compact,
}
}
-template void ExpandVariables(const std::vector<Uniform> &, std::vector<ShaderVariable> *);
-template void ExpandVariables(const std::vector<Varying> &, std::vector<ShaderVariable> *);
-
}
diff --git a/src/3rdparty/angle/src/compiler/translator/VariableInfo.h b/src/3rdparty/angle/src/compiler/translator/VariableInfo.h
index 5ac4c46baa..92d376d879 100644
--- a/src/3rdparty/angle/src/compiler/translator/VariableInfo.h
+++ b/src/3rdparty/angle/src/compiler/translator/VariableInfo.h
@@ -11,6 +11,8 @@
#include "compiler/translator/IntermNode.h"
+class TSymbolTable;
+
namespace sh
{
@@ -23,7 +25,8 @@ class CollectVariables : public TIntermTraverser
std::vector<Uniform> *uniforms,
std::vector<Varying> *varyings,
std::vector<InterfaceBlock> *interfaceBlocks,
- ShHashFunction64 hashFunction);
+ ShHashFunction64 hashFunction,
+ const TSymbolTable &symbolTable);
virtual void visitSymbol(TIntermSymbol *symbol);
virtual bool visitAggregate(Visit, TIntermAggregate *node);
@@ -48,13 +51,17 @@ class CollectVariables : public TIntermTraverser
bool mFrontFacingAdded;
bool mFragCoordAdded;
+ bool mPositionAdded;
+ bool mPointSizeAdded;
+
ShHashFunction64 mHashFunction;
+
+ const TSymbolTable &mSymbolTable;
};
-// Expand struct variables to flattened lists of split variables
-template <typename VarT>
-void ExpandVariables(const std::vector<VarT> &compact,
- std::vector<ShaderVariable> *expanded);
+// Expand struct uniforms to flattened lists of split variables
+void ExpandUniforms(const std::vector<Uniform> &compact,
+ std::vector<ShaderVariable> *expanded);
}
diff --git a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp
index 8edbd009b0..05b111a7a7 100644
--- a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp
@@ -26,18 +26,12 @@ 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."
//
-// TODO(alokp): The following two cases of invariant decalaration get lost
-// during parsing - they do not get carried over to the intermediate tree.
-// Handle these cases:
-// 1. When a pragma is used to force all output variables to be invariant:
-// - #pragma STDGL invariant(all)
-// 2. When a previously decalared or built-in variable is marked invariant:
-// - invariant gl_Position;
-// - varying vec3 color; invariant color;
-//
-TVersionGLSL::TVersionGLSL(sh::GLenum type)
- : mVersion(GLSL_VERSION_110)
+TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma)
{
+ 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 30f5a138a0..72368e39d6 100644
--- a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h
+++ b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h
@@ -9,6 +9,8 @@
#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Pragma.h"
+
// Traverses the intermediate tree to return the minimum GLSL version
// required to legally access all built-in features used in the shader.
// GLSL 1.1 which is mandated by OpenGL 2.0 provides:
@@ -27,7 +29,7 @@
class TVersionGLSL : public TIntermTraverser
{
public:
- TVersionGLSL(sh::GLenum type);
+ TVersionGLSL(sh::GLenum type, const TPragma &pragma);
// Returns 120 if the following is used the shader:
// - "invariant",
diff --git a/src/3rdparty/angle/src/compiler/translator/glslang.y b/src/3rdparty/angle/src/compiler/translator/glslang.y
index 5c945ad5ad..e271de978c 100644
--- a/src/3rdparty/angle/src/compiler/translator/glslang.y
+++ b/src/3rdparty/angle/src/compiler/translator/glslang.y
@@ -354,6 +354,15 @@ function_call
// 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();
@@ -362,20 +371,29 @@ function_call
YYERROR;
}
} else {
- $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
+ TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
+ aggregate->setType(fnCandidate->getReturnType());
+ aggregate->setPrecisionFromChildren();
+ $$ = aggregate;
}
} else {
// This is a real function call
- $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
- $$->setType(fnCandidate->getReturnType());
+ 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)
- $$->getAsAggregate()->setUserDefined();
- $$->getAsAggregate()->setName(fnCandidate->getMangledName());
+ 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) {
@@ -388,7 +406,6 @@ function_call
}
}
}
- $$->setType(fnCandidate->getReturnType());
} else {
// error message was put out by PaFindFunction()
// Put on a dummy node for error recovery
@@ -500,6 +517,7 @@ unary_expression
const char* errorOp = "";
switch($1.op) {
case EOpNegative: errorOp = "-"; break;
+ case EOpPositive: errorOp = "+"; break;
case EOpLogicalNot: errorOp = "!"; break;
default: break;
}
@@ -514,7 +532,7 @@ unary_expression
// Grammar Note: No traditional style type casts.
unary_operator
- : PLUS { $$.op = EOpNull; }
+ : PLUS { $$.op = EOpPositive; }
| DASH { $$.op = EOpNegative; }
| BANG { $$.op = EOpLogicalNot; }
;
@@ -762,7 +780,7 @@ declaration
TIntermAggregate *prototype = new TIntermAggregate;
prototype->setType(function.getReturnType());
- prototype->setName(function.getName());
+ prototype->setName(function.getMangledName());
for (size_t i = 0; i < function.getParamCount(); i++)
{
diff --git a/src/3rdparty/angle/src/compiler/translator/intermOut.cpp b/src/3rdparty/angle/src/compiler/translator/intermOut.cpp
index 56340c6f9e..00780f0454 100644
--- a/src/3rdparty/angle/src/compiler/translator/intermOut.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/intermOut.cpp
@@ -62,7 +62,9 @@ TString TType::getCompleteString() const
TStringStream stream;
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
- stream << getQualifierString() << " " << getPrecisionString() << " ";
+ stream << getQualifierString() << " ";
+ if (precision != EbpUndefined)
+ stream << getPrecisionString() << " ";
if (array)
stream << "array[" << getArraySize() << "] of ";
if (isMatrix())
@@ -221,6 +223,7 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
switch (node->getOp())
{
case EOpNegative: out << "Negate value"; break;
+ case EOpPositive: out << "Positive sign"; break;
case EOpVectorLogicalNot:
case EOpLogicalNot: out << "Negate conditional"; break;
@@ -292,6 +295,7 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpFunction: out << "Function Definition: " << node->getName(); break;
case EOpFunctionCall: out << "Function Call: " << node->getName(); break;
case EOpParameters: out << "Function Parameters: "; break;
+ case EOpPrototype: out << "Function Prototype: " << node->getName(); break;
case EOpConstructFloat: out << "Construct float"; break;
case EOpConstructVec2: out << "Construct vec2"; break;
diff --git a/src/3rdparty/angle/src/compiler/translator/util.cpp b/src/3rdparty/angle/src/compiler/translator/util.cpp
index f74c7d1173..8cc06a658a 100644
--- a/src/3rdparty/angle/src/compiler/translator/util.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/util.cpp
@@ -9,6 +9,7 @@
#include <limits>
#include "compiler/preprocessor/numeric_lex.h"
+#include "compiler/translator/SymbolTable.h"
#include "common/utilities.h"
bool atof_clamp(const char *str, float *value)
@@ -281,8 +282,47 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
}
}
+GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
+ : mSymbolTable(symbolTable)
+{
+}
+
+template void GetVariableTraverser::setTypeSpecificInfo(
+ const TType &type, const TString& name, InterfaceBlockField *variable);
+template void GetVariableTraverser::setTypeSpecificInfo(
+ const TType &type, const TString& name, ShaderVariable *variable);
+template void GetVariableTraverser::setTypeSpecificInfo(
+ const TType &type, const TString& name, Uniform *variable);
+
+template<>
+void GetVariableTraverser::setTypeSpecificInfo(
+ const TType &type, const TString& name, Varying *variable)
+{
+ ASSERT(variable);
+ switch (type.getQualifier())
+ {
+ case EvqInvariantVaryingIn:
+ case EvqInvariantVaryingOut:
+ variable->isInvariant = true;
+ break;
+ case EvqVaryingIn:
+ case EvqVaryingOut:
+ if (mSymbolTable.isVaryingInvariant(name))
+ {
+ variable->isInvariant = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ variable->interpolation = GetInterpolationType(type.getQualifier());
+}
+
template <typename VarT>
-void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output)
+void GetVariableTraverser::traverse(const TType &type,
+ const TString &name,
+ std::vector<VarT> *output)
{
const TStructure *structure = type.getStruct();
@@ -309,15 +349,16 @@ void GetVariableTraverser::traverse(const TType &type, const TString &name, std:
traverse(*field->type(), field->name(), &variable.fields);
}
}
-
+ setTypeSpecificInfo(type, name, &variable);
visitVariable(&variable);
ASSERT(output);
output->push_back(variable);
}
+template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
+template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<ShaderVariable> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
-template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
}
diff --git a/src/3rdparty/angle/src/compiler/translator/util.h b/src/3rdparty/angle/src/compiler/translator/util.h
index 241e2cc1c2..fb5308759e 100644
--- a/src/3rdparty/angle/src/compiler/translator/util.h
+++ b/src/3rdparty/angle/src/compiler/translator/util.h
@@ -24,6 +24,8 @@ extern bool atof_clamp(const char *str, float *value);
// Return false if overflow happens.
extern bool atoi_clamp(const char *str, int *value);
+class TSymbolTable;
+
namespace sh
{
@@ -38,7 +40,7 @@ TString ArrayString(const TType &type);
class GetVariableTraverser
{
public:
- GetVariableTraverser() {}
+ GetVariableTraverser(const TSymbolTable &symbolTable);
template <typename VarT>
void traverse(const TType &type, const TString &name, std::vector<VarT> *output);
@@ -48,6 +50,14 @@ class GetVariableTraverser
virtual void visitVariable(ShaderVariable *newVar) {}
private:
+ // Helper function called by traverse() to fill specific fields
+ // for attributes/varyings/uniforms.
+ template <typename VarT>
+ void setTypeSpecificInfo(
+ const TType &type, const TString &name, VarT *variable) {}
+
+ const TSymbolTable &mSymbolTable;
+
DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser);
};
diff --git a/src/3rdparty/angle/src/libEGL/AttributeMap.cpp b/src/3rdparty/angle/src/libEGL/AttributeMap.cpp
new file mode 100644
index 0000000000..28dd3d842e
--- /dev/null
+++ b/src/3rdparty/angle/src/libEGL/AttributeMap.cpp
@@ -0,0 +1,40 @@
+//
+// 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 "libEGL/AttributeMap.h"
+
+namespace egl
+{
+
+AttributeMap::AttributeMap()
+{
+}
+
+AttributeMap::AttributeMap(const EGLint *attributes)
+{
+ for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2)
+ {
+ insert(curAttrib[0], curAttrib[1]);
+ }
+}
+
+void AttributeMap::insert(EGLint key, EGLint value)
+{
+ mAttributes[key] = value;
+}
+
+bool AttributeMap::contains(EGLint key) const
+{
+ return (mAttributes.find(key) != mAttributes.end());
+}
+
+EGLint AttributeMap::get(EGLint key, EGLint defaultValue) const
+{
+ std::map<EGLint, EGLint>::const_iterator iter = mAttributes.find(key);
+ return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libEGL/AttributeMap.h b/src/3rdparty/angle/src/libEGL/AttributeMap.h
new file mode 100644
index 0000000000..f2f082fe21
--- /dev/null
+++ b/src/3rdparty/angle/src/libEGL/AttributeMap.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.
+//
+
+#ifndef LIBEGL_ATTRIBUTEMAP_H_
+#define LIBEGL_ATTRIBUTEMAP_H_
+
+#include <EGL/egl.h>
+
+#include <map>
+
+namespace egl
+{
+
+class AttributeMap
+{
+ public:
+ AttributeMap();
+ explicit AttributeMap(const EGLint *attributes);
+
+ virtual void insert(EGLint key, EGLint value);
+ virtual bool contains(EGLint key) const;
+ virtual EGLint get(EGLint key, EGLint defaultValue) const;
+
+ private:
+ std::map<EGLint, EGLint> mAttributes;
+};
+
+}
+
+#endif // LIBEGL_ATTRIBUTEMAP_H_
diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
index 5a50e4baf5..eea93b1d87 100644
--- a/src/3rdparty/angle/src/libEGL/Display.cpp
+++ b/src/3rdparty/angle/src/libEGL/Display.cpp
@@ -35,32 +35,36 @@ static DisplayMap *GetDisplayMap()
return &displays;
}
-egl::Display *Display::getDisplay(EGLNativeDisplayType displayId, EGLint displayType)
+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())
{
- return iter->second;
+ display = iter->second;
+ }
+ else
+ {
+ display = new egl::Display(displayId);
+ displays->insert(std::make_pair(displayId, display));
}
-
- // FIXME: Check if displayId is a valid display device context
- egl::Display *display = new egl::Display(displayId, displayType);
- 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, EGLint displayType)
+Display::Display(EGLNativeDisplayType displayId)
: mDisplayId(displayId),
- mRequestedDisplayType(displayType),
+ mAttributeMap(),
mRenderer(NULL)
{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (mDisplayId)
- mDisplayId->AddRef();
-#endif
}
Display::~Display()
@@ -73,28 +77,29 @@ Display::~Display()
{
displays->erase(iter);
}
+}
-#if defined(ANGLE_PLATFORM_WINRT)
- if (mDisplayId)
- mDisplayId->Release();
-#endif
+void Display::setAttributes(const AttributeMap &attribMap)
+{
+ mAttributeMap = attribMap;
}
-bool Display::initialize()
+Error Display::initialize()
{
if (isInitialized())
{
- return true;
+ return Error(EGL_SUCCESS);
}
- mRenderer = glCreateRenderer(this, mDisplayId, mRequestedDisplayType);
+ mRenderer = glCreateRenderer(this, mDisplayId, mAttributeMap);
if (!mRenderer)
{
terminate();
- return error(EGL_NOT_INITIALIZED, false);
+ 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;
@@ -125,13 +130,13 @@ bool Display::initialize()
if (!isInitialized())
{
terminate();
- return false;
+ return Error(EGL_NOT_INITIALIZED);
}
initDisplayExtensionString();
initVendorString();
- return true;
+ return Error(EGL_SUCCESS);
}
void Display::terminate()
@@ -148,6 +153,8 @@ void Display::terminate()
glDestroyRenderer(mRenderer);
mRenderer = NULL;
+
+ mConfigSet.mSet.clear();
}
bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
@@ -202,7 +209,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
-EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList)
+Error Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList, EGLSurface *outSurface)
{
const Config *configuration = mConfigSet.get(config);
EGLint postSubBufferSupported = EGL_FALSE;
@@ -223,9 +230,9 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
case EGL_BACK_BUFFER:
break;
case EGL_SINGLE_BUFFER:
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported
+ return Error(EGL_BAD_MATCH); // Rendering directly to front buffer not supported
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
@@ -241,11 +248,11 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
fixedSize = attribList[1];
break;
case EGL_VG_COLORSPACE:
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
case EGL_VG_ALPHA_FORMAT:
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
attribList += 2;
@@ -254,7 +261,7 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
if (width < 0 || height < 0)
{
- return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+ return Error(EGL_BAD_PARAMETER);
}
if (!fixedSize)
@@ -265,29 +272,33 @@ EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig co
if (hasExistingWindowSurface(window))
{
- return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ALLOC);
}
if (mRenderer->testDeviceLost(false))
{
- if (!restoreLostDevice())
- return EGL_NO_SURFACE;
+ Error error = restoreLostDevice();
+ if (error.isError())
+ {
+ return error;
+ }
}
Surface *surface = new Surface(this, configuration, window, fixedSize, width, height, postSubBufferSupported);
-
- if (!surface->initialize())
+ Error error = surface->initialize();
+ if (error.isError())
{
- delete surface;
- return EGL_NO_SURFACE;
+ SafeDelete(surface);
+ return error;
}
mSurfaceSet.insert(surface);
- return success(surface);
+ *outSurface = surface;
+ return Error(EGL_SUCCESS);
}
-EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList)
+Error Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList, EGLSurface *outSurface)
{
EGLint width = 0, height = 0;
EGLenum textureFormat = EGL_NO_TEXTURE;
@@ -319,7 +330,7 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
textureFormat = attribList[1];
break;
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_TEXTURE_TARGET:
@@ -330,19 +341,19 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
textureTarget = attribList[1];
break;
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
break;
case EGL_MIPMAP_TEXTURE:
if (attribList[1] != EGL_FALSE)
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
break;
case EGL_VG_COLORSPACE:
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
case EGL_VG_ALPHA_FORMAT:
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
attribList += 2;
@@ -351,88 +362,100 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
if (width < 0 || height < 0)
{
- return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+ return Error(EGL_BAD_PARAMETER);
}
if (width == 0 || height == 0)
{
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getRendererExtensions().textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height)))
{
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ 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, EGL_NO_SURFACE);
+ return Error(EGL_BAD_MATCH);
}
if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
{
- return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+ 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, EGL_NO_SURFACE);
+ return Error(EGL_BAD_ATTRIBUTE);
}
if (mRenderer->testDeviceLost(false))
{
- if (!restoreLostDevice())
- return EGL_NO_SURFACE;
+ Error error = restoreLostDevice();
+ if (error.isError())
+ {
+ return error;
+ }
}
Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget);
-
- if (!surface->initialize())
+ Error error = surface->initialize();
+ if (error.isError())
{
- delete surface;
- return EGL_NO_SURFACE;
+ SafeDelete(surface);
+ return error;
}
mSurfaceSet.insert(surface);
- return success(surface);
+ *outSurface = surface;
+ return Error(EGL_SUCCESS);
}
-EGLContext Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
+Error Display::createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets,
+ bool robustAccess, EGLContext *outContext)
{
if (!mRenderer)
{
- return EGL_NO_CONTEXT;
+ *outContext = EGL_NO_CONTEXT;
+ return Error(EGL_SUCCESS);
}
else if (mRenderer->testDeviceLost(false)) // Lost device
{
- if (!restoreLostDevice())
+ Error error = restoreLostDevice();
+ if (error.isError())
{
- return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT);
+ return error;
}
}
+ //TODO(jmadill): shader model is not cross-platform
if (clientVersion > 2 && mRenderer->getMajorShaderModel() < 4)
{
- return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
+ return Error(EGL_BAD_CONFIG);
}
gl::Context *context = glCreateContext(clientVersion, shareContext, mRenderer, notifyResets, robustAccess);
mContextSet.insert(context);
- return success(context);
+ *outContext = context;
+ return Error(EGL_SUCCESS);
}
-bool Display::restoreLostDevice()
+Error Display::restoreLostDevice()
{
for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++)
{
if ((*ctx)->isResetNotificationEnabled())
- return false; // If reset notifications have been requested, application must delete all contexts first
+ {
+ // 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++)
{
@@ -441,16 +464,20 @@ bool Display::restoreLostDevice()
if (!mRenderer->resetDevice())
{
- return error(EGL_BAD_ALLOC, false);
+ return Error(EGL_BAD_ALLOC);
}
// Restore any surfaces that may have been lost
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
- (*surface)->resetSwapChain();
+ Error error = (*surface)->resetSwapChain();
+ if (error.isError())
+ {
+ return error;
+ }
}
- return true;
+ return Error(EGL_SUCCESS);
}
@@ -472,7 +499,6 @@ void Display::notifyDeviceLost()
{
(*context)->markContextLost();
}
- egl::error(EGL_CONTEXT_LOST);
}
void Display::recreateSwapChains()
@@ -604,10 +630,11 @@ void Display::initVendorString()
LUID adapterLuid = {0};
+ //TODO(jmadill): LUID is not cross-platform
if (mRenderer && mRenderer->getLUID(&adapterLuid))
{
char adapterLuidString[64];
- snprintf(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
+ sprintf_s(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
mVendorString += adapterLuidString;
}
diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
index 73ba7673ff..b3ffcc84c5 100644
--- a/src/3rdparty/angle/src/libEGL/Display.h
+++ b/src/3rdparty/angle/src/libEGL/Display.h
@@ -14,7 +14,9 @@
#include <set>
#include <vector>
+#include "libEGL/Error.h"
#include "libEGL/Config.h"
+#include "libEGL/AttributeMap.h"
namespace gl
{
@@ -30,10 +32,10 @@ class Display
public:
~Display();
- bool initialize();
+ Error initialize();
void terminate();
- static egl::Display *getDisplay(EGLNativeDisplayType displayId, EGLint displayType);
+ static egl::Display *getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap);
static const char *getExtensionString(egl::Display *display);
@@ -43,9 +45,10 @@ class Display
bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
- EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);
- EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
- EGLContext createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
+ 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);
@@ -64,18 +67,19 @@ class Display
const char *getExtensionString() const;
const char *getVendorString() const;
-
EGLNativeDisplayType getDisplayId() const { return mDisplayId; }
private:
DISALLOW_COPY_AND_ASSIGN(Display);
- Display(EGLNativeDisplayType displayId, EGLint displayType);
+ Display(EGLNativeDisplayType displayId);
+
+ void setAttributes(const AttributeMap &attribMap);
- bool restoreLostDevice();
+ Error restoreLostDevice();
EGLNativeDisplayType mDisplayId;
- EGLint mRequestedDisplayType;
+ AttributeMap mAttributeMap;
typedef std::set<Surface*> SurfaceSet;
SurfaceSet mSurfaceSet;
diff --git a/src/3rdparty/angle/src/libEGL/Error.cpp b/src/3rdparty/angle/src/libEGL/Error.cpp
new file mode 100644
index 0000000000..df5f163d32
--- /dev/null
+++ b/src/3rdparty/angle/src/libEGL/Error.cpp
@@ -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.
+//
+
+// 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
new file mode 100644
index 0000000000..71805d2fb7
--- /dev/null
+++ b/src/3rdparty/angle/src/libEGL/Error.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.
+
+// 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
index fa7996152a..b664a8530e 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
+++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
@@ -22,23 +22,19 @@
#include "libEGL/main.h"
#include "libEGL/Display.h"
-#if defined(ANGLE_PLATFORM_WINRT)
-# include "wrl.h"
-# include "windows.graphics.display.h"
-# include "windows.ui.core.h"
-using namespace ABI::Windows::Graphics::Display;
-using namespace ABI::Windows::Foundation;
-using namespace ABI::Windows::UI::Core;
-using namespace Microsoft::WRL;
-#endif
+#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), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
+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)
{
- mRenderer = mDisplay->getRenderer();
+ //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;
@@ -51,27 +47,19 @@ Surface::Surface(Display *display, const Config *config, EGLNativeWindowType win
mSwapInterval = -1;
mWidth = width;
mHeight = height;
+ mFixedWidth = mWidth;
+ mFixedHeight = mHeight;
setSwapInterval(1);
mFixedSize = fixedSize;
- mSwapFlags = rx::SWAP_NORMAL;
-#if defined(ANGLE_PLATFORM_WINRT)
- if (mWindow)
- mWindow->AddRef();
- mScaleFactor = 1.0;
- mSizeToken.value = 0;
- mDpiToken.value = 0;
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- mOrientationToken.value = 0;
-# endif
-#endif
subclassWindow();
}
Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
- : mDisplay(display), mWindow(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)
{
- mRenderer = mDisplay->getRenderer();
+ //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;
@@ -85,90 +73,33 @@ 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;
- mSwapFlags = rx::SWAP_NORMAL;
-#if defined(ANGLE_PLATFORM_WINRT)
- mScaleFactor = 1.0;
- mSizeToken.value = 0;
- mDpiToken.value = 0;
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- mOrientationToken.value = 0;
-# endif
-#endif
+ mFixedWidth = mWidth;
+ mFixedHeight = mHeight;
}
Surface::~Surface()
{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (mSizeToken.value) {
- ComPtr<ICoreWindow> coreWindow;
- HRESULT hr = mWindow->QueryInterface(coreWindow.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
-
- hr = coreWindow->remove_SizeChanged(mSizeToken);
- ASSERT(SUCCEEDED(hr));
- }
- if (mDpiToken.value) {
- ComPtr<IDisplayInformation> displayInformation;
- HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
-
- hr = displayInformation->remove_DpiChanged(mDpiToken);
- ASSERT(SUCCEEDED(hr));
- }
-# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
- if (mOrientationToken.value) {
- ComPtr<IDisplayInformation> displayInformation;
- HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
-
- hr = displayInformation->remove_OrientationChanged(mOrientationToken);
- ASSERT(SUCCEEDED(hr));
- }
-# endif
-#endif
unsubclassWindow();
release();
}
-bool Surface::initialize()
-{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (!mFixedSize) {
- HRESULT hr;
- ComPtr<IDisplayInformation> displayInformation;
- hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
- onDpiChanged(displayInformation.Get(), 0);
- hr = displayInformation->add_DpiChanged(Callback<ITypedEventHandler<DisplayInformation *, IInspectable *>>(this, &Surface::onDpiChanged).Get(),
- &mDpiToken);
- ASSERT(SUCCEEDED(hr));
-
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- onOrientationChanged(displayInformation.Get(), 0);
- hr = displayInformation->add_OrientationChanged(Callback<ITypedEventHandler<DisplayInformation *, IInspectable *>>(this, &Surface::onOrientationChanged).Get(),
- &mOrientationToken);
- ASSERT(SUCCEEDED(hr));
-# endif
-
- ComPtr<ICoreWindow> coreWindow;
- hr = mWindow->QueryInterface(coreWindow.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
-
- Rect rect;
- hr = coreWindow->get_Bounds(&rect);
- ASSERT(SUCCEEDED(hr));
- mWidth = rect.Width * mScaleFactor;
- mHeight = rect.Height * mScaleFactor;
- hr = coreWindow->add_SizeChanged(Callback<ITypedEventHandler<CoreWindow *, WindowSizeChangedEventArgs *>>(this, &Surface::onSizeChanged).Get(),
- &mSizeToken);
- ASSERT(SUCCEEDED(hr));
+Error Surface::initialize()
+{
+ if (mNativeWindow.getNativeWindow())
+ {
+ if (!mNativeWindow.initialize())
+ {
+ return Error(EGL_BAD_SURFACE);
+ }
}
-#endif
- if (!resetSwapChain())
- return false;
+ Error error = resetSwapChain();
+ if (error.isError())
+ {
+ return error;
+ }
- return true;
+ return Error(EGL_SUCCESS);
}
void Surface::release()
@@ -181,85 +112,80 @@ void Surface::release()
mTexture->releaseTexImage();
mTexture = NULL;
}
-
-#if defined(ANGLE_PLATFORM_WINRT)
- if (mWindow)
- mWindow->Release();
-#endif
}
-bool Surface::resetSwapChain()
+Error Surface::resetSwapChain()
{
ASSERT(!mSwapChain);
int width;
int height;
-#if !defined(ANGLE_PLATFORM_WINRT)
if (!mFixedSize)
{
RECT windowRect;
- if (!GetClientRect(getWindowHandle(), &windowRect))
+ if (!mNativeWindow.getClientRect(&windowRect))
{
ASSERT(false);
- ERR("Could not retrieve the window dimensions");
- return error(EGL_BAD_SURFACE, false);
+ return Error(EGL_BAD_SURFACE, "Could not retrieve the window dimensions");
}
width = windowRect.right - windowRect.left;
height = windowRect.bottom - windowRect.top;
}
else
-#endif
{
// non-window surface - size is determined at creation
width = mWidth;
height = mHeight;
}
- mSwapChain = mRenderer->createSwapChain(mWindow, mShareHandle,
+ mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle,
mConfig->mRenderTargetFormat,
mConfig->mDepthStencilFormat);
if (!mSwapChain)
{
- return error(EGL_BAD_ALLOC, false);
+ return Error(EGL_BAD_ALLOC);
}
- if (!resetSwapChain(width, height))
+ Error error = resetSwapChain(width, height);
+ if (error.isError())
{
- delete mSwapChain;
- mSwapChain = NULL;
- return false;
+ SafeDelete(mSwapChain);
+ return error;
}
- return true;
+ return Error(EGL_SUCCESS);
}
-bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
+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)
{
mDisplay->notifyDeviceLost();
- return false;
+ return Error(status);
}
else if (status != EGL_SUCCESS)
{
- return error(status, false);
+ return Error(status);
}
mWidth = backbufferWidth;
mHeight = backbufferHeight;
- return true;
+ return Error(EGL_SUCCESS);
}
-bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
+Error Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
{
ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
ASSERT(mSwapChain);
@@ -269,69 +195,71 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
if (status == EGL_CONTEXT_LOST)
{
mRenderer->notifyDeviceLost();
- return false;
+ return Error(status);
}
else if (status != EGL_SUCCESS)
{
- return error(status, false);
+ return Error(status);
}
mWidth = backbufferWidth;
mHeight = backbufferHeight;
mSwapIntervalDirty = false;
- return true;
+ return Error(EGL_SUCCESS);
}
-bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+Error Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mSwapChain)
{
- return true;
+ 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)
{
- return true;
+ return Error(EGL_SUCCESS);
}
- EGLint status = mSwapChain->swapRect(x, y, width, height, mSwapFlags);
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+
+ EGLint status = mSwapChain->swapRect(x, y, width, height);
if (status == EGL_CONTEXT_LOST)
{
mRenderer->notifyDeviceLost();
- return false;
+ return Error(status);
}
else if (status != EGL_SUCCESS)
{
- return error(status, false);
+ return Error(status);
}
checkForOutOfDateSwapChain();
- return true;
+ return Error(EGL_SUCCESS);
}
EGLNativeWindowType Surface::getWindowHandle()
{
- return mWindow;
+ return mNativeWindow.getNativeWindow();
}
-
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
-#if !defined(ANGLE_PLATFORM_WINRT)
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
if (message == WM_SIZE)
@@ -349,45 +277,50 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
void Surface::subclassWindow()
{
-#if !defined(ANGLE_PLATFORM_WINRT)
- if (!mWindow)
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ HWND window = mNativeWindow.getNativeWindow();
+ if (!window)
{
return;
}
DWORD processId;
- DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
+ DWORD threadId = GetWindowThreadProcessId(window, &processId);
if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
{
return;
}
SetLastError(0);
- LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
+ LONG_PTR oldWndProc = SetWindowLongPtr(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
{
mWindowSubclassed = false;
return;
}
- SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
- SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
+ SetProp(window, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
+ SetProp(window, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
mWindowSubclassed = true;
-#else
- mWindowSubclassed = false;
#endif
}
void Surface::unsubclassWindow()
{
-#if !defined(ANGLE_PLATFORM_WINRT)
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(mWindow, kParentWndProc));
+ 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
@@ -396,29 +329,28 @@ void Surface::unsubclassWindow()
// EGL context, or to unsubclass before destroying the EGL context.
if(parentWndFunc)
{
- LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc);
+ LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc);
UNUSED_ASSERTION_VARIABLE(prevWndFunc);
ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
}
- RemoveProp(mWindow, kSurfaceProperty);
- RemoveProp(mWindow, kParentWndProc);
- mWindowSubclassed = false;
+ RemoveProp(window, kSurfaceProperty);
+ RemoveProp(window, kParentWndProc);
#endif
+ mWindowSubclassed = false;
}
bool Surface::checkForOutOfDateSwapChain()
{
+ RECT client;
int clientWidth = getWidth();
int clientHeight = getHeight();
bool sizeDirty = false;
-#if !defined(ANGLE_PLATFORM_WINRT)
- if (!mFixedSize && !IsIconic(getWindowHandle()))
+ if (!mFixedSize && !mNativeWindow.isIconic())
{
- RECT client;
// 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 (!GetClientRect(getWindowHandle(), &client))
+ if (!mNativeWindow.getClientRect(&client))
{
ASSERT(false);
return false;
@@ -429,7 +361,13 @@ bool Surface::checkForOutOfDateSwapChain()
clientHeight = client.bottom - client.top;
sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
}
-#endif
+
+ if (mFixedSize && (mWidth != mFixedWidth || mHeight != mFixedHeight))
+ {
+ clientWidth = mFixedWidth;
+ clientHeight = mFixedHeight;
+ sizeDirty = true;
+ }
bool wasDirty = (mSwapIntervalDirty || sizeDirty);
@@ -455,17 +393,17 @@ bool Surface::checkForOutOfDateSwapChain()
return false;
}
-bool Surface::swap()
+Error Surface::swap()
{
- return swapRect(0, 0, mWidth, mHeight);
+ return swapRect(0, 0, abs(mWidth), abs(mHeight));
}
-bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
+Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height)
{
if (!mPostSubBufferSupported)
{
// Spec is not clear about how this should be handled.
- return true;
+ return Error(EGL_SUCCESS);
}
return swapRect(x, y, width, height);
@@ -550,77 +488,18 @@ EGLint Surface::isFixedSize() const
return mFixedSize;
}
-EGLenum Surface::getFormat() const
+void Surface::setFixedWidth(EGLint width)
{
- return mConfig->mRenderTargetFormat;
+ mFixedWidth = width;
}
-#if defined(ANGLE_PLATFORM_WINRT)
-
-HRESULT Surface::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args)
+void Surface::setFixedHeight(EGLint height)
{
- HRESULT hr;
- Size size;
- hr = args->get_Size(&size);
- ASSERT(SUCCEEDED(hr));
-
- resizeSwapChain(std::floor(size.Width * mScaleFactor + 0.5),
- std::floor(size.Height * mScaleFactor + 0.5));
-
- if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
- {
- glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
- }
-
- return S_OK;
-}
-
-HRESULT Surface::onDpiChanged(IDisplayInformation *displayInformation, IInspectable *)
-{
- HRESULT hr;
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- ComPtr<IDisplayInformation2> displayInformation2;
- hr = displayInformation->QueryInterface(displayInformation2.GetAddressOf());
- ASSERT(SUCCEEDED(hr));
-
- hr = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor);
- ASSERT(SUCCEEDED(hr));
-# else
- ResolutionScale resolutionScale;
- hr = displayInformation->get_ResolutionScale(&resolutionScale);
- ASSERT(SUCCEEDED(hr));
-
- mScaleFactor = double(resolutionScale) / 100.0;
-# endif
- return S_OK;
-}
-
-# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
-HRESULT Surface::onOrientationChanged(IDisplayInformation *displayInformation, IInspectable *)
-{
- HRESULT hr;
- DisplayOrientations orientation;
- hr = displayInformation->get_CurrentOrientation(&orientation);
- ASSERT(SUCCEEDED(hr));
- switch (orientation) {
- default:
- case DisplayOrientations_Portrait:
- mSwapFlags = rx::SWAP_NORMAL;
- break;
- case DisplayOrientations_Landscape:
- mSwapFlags = rx::SWAP_ROTATE_90;
- break;
- case DisplayOrientations_LandscapeFlipped:
- mSwapFlags = rx::SWAP_ROTATE_270;
- break;
- case DisplayOrientations_PortraitFlipped:
- mSwapFlags = rx::SWAP_ROTATE_180;
- break;
- }
- return S_OK;
+ mFixedHeight = height;
}
-# endif
-
-#endif
+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 ebffce8fed..46382d06e1 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.h
+++ b/src/3rdparty/angle/src/libEGL/Surface.h
@@ -11,23 +11,12 @@
#ifndef LIBEGL_SURFACE_H_
#define LIBEGL_SURFACE_H_
+#include "libEGL/Error.h"
+
#include <EGL/egl.h>
#include "common/angleutils.h"
-
-#if defined(ANGLE_PLATFORM_WINRT)
-#include <EventToken.h>
-namespace ABI { namespace Windows {
- namespace UI { namespace Core {
- struct ICoreWindow;
- struct IWindowSizeChangedEventArgs;
- } }
- namespace Graphics { namespace Display {
- struct IDisplayInformation;
- } }
-} }
-struct IInspectable;
-#endif
+#include "common/NativeWindow.h"
namespace gl
{
@@ -35,8 +24,8 @@ class Texture2D;
}
namespace rx
{
-class Renderer;
class SwapChain;
+class RendererD3D; //TODO(jmadill): remove this
}
namespace egl
@@ -52,13 +41,13 @@ class Surface
virtual ~Surface();
- bool initialize();
+ Error initialize();
void release();
- bool resetSwapChain();
+ Error resetSwapChain();
EGLNativeWindowType getWindowHandle();
- bool swap();
- bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
+ Error swap();
+ Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
virtual EGLint isPostSubBufferSupported() const;
@@ -81,35 +70,31 @@ class Surface
virtual gl::Texture2D *getBoundTexture() const;
EGLint isFixedSize() const;
+ void setFixedWidth(EGLint width);
+ void setFixedHeight(EGLint height);
-private:
+ private:
DISALLOW_COPY_AND_ASSIGN(Surface);
-#if defined(ANGLE_PLATFORM_WINRT)
- HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *);
- HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *);
-# endif
-#endif
-
Display *const mDisplay;
- rx::Renderer *mRenderer;
+ rx::RendererD3D *mRenderer;
HANDLE mShareHandle;
rx::SwapChain *mSwapChain;
void subclassWindow();
void unsubclassWindow();
- bool resizeSwapChain(int backbufferWidth, int backbufferHeight);
- bool resetSwapChain(int backbufferWidth, int backbufferHeight);
- bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
+ Error resizeSwapChain(int backbufferWidth, int backbufferHeight);
+ Error resetSwapChain(int backbufferWidth, int backbufferHeight);
+ Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
- const EGLNativeWindowType mWindow; // Window that the surface is created for.
+ 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
@@ -126,18 +111,9 @@ private:
EGLint mSwapInterval;
EGLint mPostSubBufferSupported;
EGLint mFixedSize;
- EGLint mSwapFlags;
bool mSwapIntervalDirty;
gl::Texture2D *mTexture;
-#if defined(ANGLE_PLATFORM_WINRT)
- double mScaleFactor;
- EventRegistrationToken mSizeToken;
- EventRegistrationToken mDpiToken;
-# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
- EventRegistrationToken mOrientationToken;
-# endif
-#endif
};
}
diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
index c2e0fd6d3d..68399d63a4 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
@@ -13,7 +13,6 @@
#include "common/debug.h"
#include "common/version.h"
-#include "common/platform.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/main.h"
@@ -26,16 +25,20 @@
#include "libEGL/Display.h"
#include "libEGL/Surface.h"
+#include "common/NativeWindow.h"
+
bool validateDisplay(egl::Display *display)
{
if (display == EGL_NO_DISPLAY)
{
- return egl::error(EGL_BAD_DISPLAY, false);
+ recordError(egl::Error(EGL_BAD_DISPLAY));
+ return false;
}
if (!display->isInitialized())
{
- return egl::error(EGL_NOT_INITIALIZED, false);
+ recordError(egl::Error(EGL_NOT_INITIALIZED));
+ return false;
}
return true;
@@ -50,7 +53,8 @@ bool validateConfig(egl::Display *display, EGLConfig config)
if (!display->isValidConfig(config))
{
- return egl::error(EGL_BAD_CONFIG, false);
+ recordError(egl::Error(EGL_BAD_CONFIG));
+ return false;
}
return true;
@@ -65,7 +69,8 @@ bool validateContext(egl::Display *display, gl::Context *context)
if (!display->isValidContext(context))
{
- return egl::error(EGL_BAD_CONTEXT, false);
+ recordError(egl::Error(EGL_BAD_CONTEXT));
+ return false;
}
return true;
@@ -80,7 +85,8 @@ bool validateSurface(egl::Display *display, egl::Surface *surface)
if (!display->isValidSurface(surface))
{
- return egl::error(EGL_BAD_SURFACE, false);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return false;
}
return true;
@@ -93,12 +99,7 @@ EGLint __stdcall eglGetError(void)
EVENT("()");
EGLint error = egl::getCurrentError();
-
- if (error != EGL_SUCCESS)
- {
- egl::setCurrentError(EGL_SUCCESS);
- }
-
+ recordError(egl::Error(EGL_SUCCESS));
return error;
}
@@ -106,7 +107,7 @@ EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
{
EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
- return egl::Display::getDisplay(display_id, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
+ return egl::Display::getDisplay(display_id, egl::AttributeMap());
}
EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
@@ -120,19 +121,26 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
break;
default:
- return egl::error(EGL_BAD_CONFIG, EGL_NO_DISPLAY);
+ recordError(egl::Error(EGL_BAD_CONFIG));
+ return EGL_NO_DISPLAY;
}
EGLNativeDisplayType displayId = static_cast<EGLNativeDisplayType>(native_display);
-#if !defined(ANGLE_PLATFORM_WINRT)
+
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
// Validate the display device context
if (WindowFromDC(displayId) == NULL)
{
- return egl::success(EGL_NO_DISPLAY);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_NO_DISPLAY;
}
#endif
- EGLint requestedDisplayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
+ 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)
@@ -140,7 +148,69 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
switch (curAttrib[0])
{
case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
- requestedDisplayType = curAttrib[1];
+ 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:
@@ -149,33 +219,20 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis
}
}
- switch (requestedDisplayType)
+ if (!majorVersionSpecified && minorVersionSpecified)
{
- case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
- break;
-
- case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
- case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
- case EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE:
- if (!egl::Display::supportsPlatformD3D())
- {
- return egl::success(EGL_NO_DISPLAY);
- }
- break;
-
- case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
- case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
- if (!egl::Display::supportsPlatformOpenGL())
- {
- return egl::success(EGL_NO_DISPLAY);
- }
- break;
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_DISPLAY;
+ }
- default:
- return egl::success(EGL_NO_DISPLAY);
+ if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE && requestedWARP)
+ {
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_DISPLAY;
}
- return egl::Display::getDisplay(displayId, requestedDisplayType);
+ recordError(egl::Error(EGL_SUCCESS));
+ return egl::Display::getDisplay(displayId, egl::AttributeMap(attrib_list));
}
EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
@@ -185,20 +242,24 @@ EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
if (dpy == EGL_NO_DISPLAY)
{
- return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_DISPLAY));
+ return EGL_FALSE;
}
egl::Display *display = static_cast<egl::Display*>(dpy);
- if (!display->initialize())
+ egl::Error error = display->initialize();
+ if (error.isError())
{
- return egl::error(EGL_NOT_INITIALIZED, EGL_FALSE);
+ recordError(error);
+ return EGL_FALSE;
}
if (major) *major = 1;
if (minor) *minor = 4;
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
@@ -207,14 +268,16 @@ EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
if (dpy == EGL_NO_DISPLAY)
{
- return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_DISPLAY));
+ return EGL_FALSE;
}
egl::Display *display = static_cast<egl::Display*>(dpy);
display->terminate();
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
@@ -227,19 +290,28 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
return NULL;
}
+ const char *result;
switch (name)
{
case EGL_CLIENT_APIS:
- return egl::success("OpenGL_ES");
+ result = "OpenGL_ES";
+ break;
case EGL_EXTENSIONS:
- return egl::success(egl::Display::getExtensionString(display));
+ result = egl::Display::getExtensionString(display);
+ break;
case EGL_VENDOR:
- return egl::success(display->getVendorString());
+ result = display->getVendorString();
+ break;
case EGL_VERSION:
- return egl::success("1.4 (ANGLE " ANGLE_VERSION_STRING ")");
+ result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")";
+ break;
default:
- return egl::error(EGL_BAD_PARAMETER, (const char*)NULL);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return NULL;
}
+
+ recordError(egl::Error(EGL_SUCCESS));
+ return result;
}
EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
@@ -257,17 +329,20 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co
if (!num_config)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
const EGLint attribList[] = {EGL_NONE};
if (!display->getConfigs(configs, attribList, config_size, num_config))
{
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
@@ -285,7 +360,8 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
if (!num_config)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
const EGLint attribList[] = {EGL_NONE};
@@ -297,7 +373,8 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
display->getConfigs(configs, attrib_list, config_size, num_config);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
@@ -314,10 +391,12 @@ EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint
if (!display->getConfigAttrib(config, attribute, value))
{
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
@@ -332,16 +411,21 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
return EGL_NO_SURFACE;
}
-#if !defined(ANGLE_PLATFORM_WINRT)
- HWND window = (HWND)win;
+ if (!rx::IsValidEGLNativeWindowType(win))
+ {
+ recordError(egl::Error(EGL_BAD_NATIVE_WINDOW));
+ return EGL_NO_SURFACE;
+ }
- if (!IsWindow(window))
+ EGLSurface surface = EGL_NO_SURFACE;
+ egl::Error error = display->createWindowSurface(win, config, attrib_list, &surface);
+ if (error.isError())
{
- return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ recordError(error);
+ return EGL_NO_SURFACE;
}
-#endif
- return display->createWindowSurface(win, config, attrib_list);
+ return surface;
}
EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
@@ -356,7 +440,15 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c
return EGL_NO_SURFACE;
}
- return display->createOffscreenSurface(config, NULL, attrib_list);
+ 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;
}
EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
@@ -373,7 +465,8 @@ EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EG
UNIMPLEMENTED(); // FIXME
- return egl::success(EGL_NO_SURFACE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_NO_SURFACE;
}
EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
@@ -390,12 +483,14 @@ EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
if (surface == EGL_NO_SURFACE)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
display->destroySurface((egl::Surface*)surface);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
@@ -413,7 +508,8 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
if (surface == EGL_NO_SURFACE)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
switch (attribute)
@@ -473,10 +569,12 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
*value = eglSurface->isFixedSize();
break;
default:
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
@@ -498,7 +596,8 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
if (surface == EGL_NO_SURFACE)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
rx::SwapChain *swapchain = eglSurface->getSwapChain();
@@ -522,7 +621,8 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
if (renderer->getMajorShaderModel() < 4)
{
- return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_CONTEXT));
+ return EGL_FALSE;
}
*value = static_cast<rx::Renderer11*>(renderer)->getDevice();
@@ -530,10 +630,12 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
break;
#endif
default:
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglBindAPI(EGLenum api)
@@ -544,16 +646,19 @@ EGLBoolean __stdcall eglBindAPI(EGLenum api)
{
case EGL_OPENGL_API:
case EGL_OPENVG_API:
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE; // Not supported by this implementation
case EGL_OPENGL_ES_API:
break;
default:
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
egl::setCurrentAPI(api);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLenum __stdcall eglQueryAPI(void)
@@ -562,7 +667,8 @@ EGLenum __stdcall eglQueryAPI(void)
EGLenum API = egl::getCurrentAPI();
- return egl::success(API);
+ recordError(egl::Error(EGL_SUCCESS));
+ return API;
}
EGLBoolean __stdcall eglWaitClient(void)
@@ -571,7 +677,8 @@ EGLBoolean __stdcall eglWaitClient(void)
UNIMPLEMENTED(); // FIXME
- return egl::success(0);
+ recordError(egl::Error(EGL_SUCCESS));
+ return 0;
}
EGLBoolean __stdcall eglReleaseThread(void)
@@ -580,7 +687,8 @@ EGLBoolean __stdcall eglReleaseThread(void)
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
@@ -598,10 +706,19 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu
if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+ 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 display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list);
+ return surface;
}
EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
@@ -617,9 +734,30 @@ 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
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
@@ -636,30 +774,36 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint
if (buffer != EGL_BACK_BUFFER)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
if (eglSurface->getBoundTexture())
{
- return egl::error(EGL_BAD_ACCESS, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_ACCESS));
+ return EGL_FALSE;
}
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
{
- return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
}
if (!glBindTexImage(eglSurface))
{
- return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
@@ -676,17 +820,20 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
if (buffer != EGL_BACK_BUFFER)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
{
- return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
}
gl::Texture2D *texture = eglSurface->getBoundTexture();
@@ -696,7 +843,8 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
texture->releaseTexImage();
}
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
@@ -714,12 +862,14 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
if (draw_surface == NULL)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
draw_surface->setSwapInterval(interval);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
@@ -744,27 +894,38 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
if (attribute[1] == EGL_TRUE)
{
- return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented
+ recordError(egl::Error(EGL_BAD_CONFIG)); // Unimplemented
+ return EGL_NO_CONTEXT;
// robust_access = true;
}
else if (attribute[1] != EGL_FALSE)
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+ {
+ 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)
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+ {
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_CONTEXT;
+ }
break;
default:
- return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+ recordError(egl::Error(EGL_BAD_ATTRIBUTE));
+ return EGL_NO_CONTEXT;
}
}
}
if (client_version != 2 && client_version != 3)
{
- return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
+ recordError(egl::Error(EGL_BAD_CONFIG));
+ return EGL_NO_CONTEXT;
}
egl::Display *display = static_cast<egl::Display*>(dpy);
@@ -775,18 +936,21 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
if (sharedGLContext->isResetNotificationEnabled() != reset_notification)
{
- return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_NO_CONTEXT;
}
if (sharedGLContext->getClientVersion() != client_version)
{
- return egl::error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
+ recordError(egl::Error(EGL_BAD_CONTEXT));
+ return EGL_NO_CONTEXT;
}
// Can not share contexts between displays
if (sharedGLContext->getRenderer() != display->getRenderer())
{
- return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_NO_CONTEXT;
}
}
@@ -795,7 +959,16 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
return EGL_NO_CONTEXT;
}
- return display->createContext(config, client_version, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
+ 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;
}
EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
@@ -812,12 +985,14 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
if (ctx == EGL_NO_CONTEXT)
{
- return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_CONTEXT));
+ return EGL_FALSE;
}
display->destroyContext(context);
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
@@ -832,7 +1007,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
bool noSurface = (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE);
if (noContext != noSurface)
{
- return egl::error(EGL_BAD_MATCH, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
}
if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
@@ -850,7 +1026,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
if (renderer->isDeviceLost())
{
- return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
+ recordError(egl::Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
}
}
@@ -871,7 +1048,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
- return egl::success(EGL_TRUE);
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLContext __stdcall eglGetCurrentContext(void)
@@ -880,7 +1058,8 @@ EGLContext __stdcall eglGetCurrentContext(void)
EGLContext context = glGetCurrentContext();
- return egl::success(context);
+ recordError(egl::Error(EGL_SUCCESS));
+ return context;
}
EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
@@ -889,17 +1068,18 @@ EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
if (readdraw == EGL_READ)
{
- EGLSurface read = egl::getCurrentReadSurface();
- return egl::success(read);
+ recordError(egl::Error(EGL_SUCCESS));
+ return egl::getCurrentReadSurface();
}
else if (readdraw == EGL_DRAW)
{
- EGLSurface draw = egl::getCurrentDrawSurface();
- return egl::success(draw);
+ recordError(egl::Error(EGL_SUCCESS));
+ return egl::getCurrentDrawSurface();
}
else
{
- return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_NO_SURFACE;
}
}
@@ -909,7 +1089,8 @@ EGLDisplay __stdcall eglGetCurrentDisplay(void)
EGLDisplay dpy = egl::getCurrentDisplay();
- return egl::success(dpy);
+ recordError(egl::Error(EGL_SUCCESS));
+ return dpy;
}
EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
@@ -927,7 +1108,8 @@ EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attr
UNIMPLEMENTED(); // FIXME
- return egl::success(0);
+ recordError(egl::Error(EGL_SUCCESS));
+ return 0;
}
EGLBoolean __stdcall eglWaitGL(void)
@@ -936,7 +1118,8 @@ EGLBoolean __stdcall eglWaitGL(void)
UNIMPLEMENTED(); // FIXME
- return egl::success(0);
+ recordError(egl::Error(EGL_SUCCESS));
+ return 0;
}
EGLBoolean __stdcall eglWaitNative(EGLint engine)
@@ -945,7 +1128,8 @@ EGLBoolean __stdcall eglWaitNative(EGLint engine)
UNIMPLEMENTED(); // FIXME
- return egl::success(0);
+ recordError(egl::Error(EGL_SUCCESS));
+ return 0;
}
EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
@@ -962,20 +1146,25 @@ EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
if (display->getRenderer()->isDeviceLost())
{
- return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
+ recordError(egl::Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
}
if (surface == EGL_NO_SURFACE)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
- if (eglSurface->swap())
+ egl::Error error = eglSurface->swap();
+ if (error.isError())
{
- return egl::success(EGL_TRUE);
+ recordError(error);
+ return EGL_FALSE;
}
- return EGL_FALSE;
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
@@ -992,12 +1181,14 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ
if (display->getRenderer()->isDeviceLost())
{
- return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
+ recordError(egl::Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
}
UNIMPLEMENTED(); // FIXME
- return egl::success(0);
+ recordError(egl::Error(EGL_SUCCESS));
+ return 0;
}
EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
@@ -1006,7 +1197,8 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
if (x < 0 || y < 0 || width < 0 || height < 0)
{
- return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
}
egl::Display *display = static_cast<egl::Display*>(dpy);
@@ -1019,20 +1211,25 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
if (display->getRenderer()->isDeviceLost())
{
- return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
+ recordError(egl::Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
}
if (surface == EGL_NO_SURFACE)
{
- return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
+ recordError(egl::Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
}
- if (eglSurface->postSubBuffer(x, y, width, height))
+ egl::Error error = eglSurface->postSubBuffer(x, y, width, height);
+ if (error.isError())
{
- return egl::success(EGL_TRUE);
+ recordError(error);
+ return EGL_FALSE;
}
- return EGL_FALSE;
+ recordError(egl::Error(EGL_SUCCESS));
+ return EGL_TRUE;
}
__eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname)
diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
index e74737eaba..e88cad775f 100644
--- a/src/3rdparty/angle/src/libEGL/main.cpp
+++ b/src/3rdparty/angle/src/libEGL/main.cpp
@@ -11,9 +11,6 @@
#include "common/debug.h"
#include "common/tls.h"
-#if defined(ANGLE_PLATFORM_WINRT)
-__declspec(thread)
-#endif
static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
namespace egl
@@ -21,12 +18,6 @@ namespace egl
Current *AllocateCurrent()
{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (currentTLS == TLS_OUT_OF_INDEXES)
- {
- currentTLS = CreateTLSIndex();
- }
-#endif
ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
if (currentTLS == TLS_OUT_OF_INDEXES)
{
@@ -51,12 +42,6 @@ Current *AllocateCurrent()
void DeallocateCurrent()
{
-#if defined(ANGLE_PLATFORM_WINRT)
- if (currentTLS == TLS_OUT_OF_INDEXES)
- {
- return;
- }
-#endif
Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
SafeDelete(current);
SetTLSValue(currentTLS, NULL);
@@ -72,7 +57,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
{
case DLL_PROCESS_ATTACH:
{
-#if defined(ANGLE_ENABLE_TRACE)
+#if defined(ANGLE_ENABLE_DEBUG_TRACE)
FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
if (debug)
@@ -87,15 +72,15 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
}
#endif
-#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain
- return DisableThreadLibraryCalls(instance);
-#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:
@@ -105,15 +90,17 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
break;
case DLL_THREAD_DETACH:
{
-#if !defined(ANGLE_PLATFORM_WINRT)
egl::DeallocateCurrent();
-#endif
}
break;
case DLL_PROCESS_DETACH:
{
egl::DeallocateCurrent();
DestroyTLSIndex(currentTLS);
+
+#ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
+ gl::UninitializeDebugAnnotations();
+#endif
}
break;
default:
@@ -143,11 +130,11 @@ Current *GetCurrentData()
#endif
}
-void setCurrentError(EGLint error)
+void recordError(const Error &error)
{
Current *current = GetCurrentData();
- current->error = error;
+ current->error = error.getCode();
}
EGLint getCurrentError()
@@ -213,9 +200,4 @@ EGLSurface getCurrentReadSurface()
return current->readSurface;
}
-void error(EGLint errorCode)
-{
- egl::setCurrentError(errorCode);
-}
-
}
diff --git a/src/3rdparty/angle/src/libEGL/main.h b/src/3rdparty/angle/src/libEGL/main.h
index 07f5b9e675..e5361a4a5e 100644
--- a/src/3rdparty/angle/src/libEGL/main.h
+++ b/src/3rdparty/angle/src/libEGL/main.h
@@ -9,6 +9,8 @@
#ifndef LIBEGL_MAIN_H_
#define LIBEGL_MAIN_H_
+#include "libEGL/Error.h"
+
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -23,7 +25,7 @@ struct Current
EGLSurface readSurface;
};
-void setCurrentError(EGLint error);
+void recordError(const Error &error);
EGLint getCurrentError();
void setCurrentAPI(EGLenum API);
@@ -38,24 +40,6 @@ EGLSurface getCurrentDrawSurface();
void setCurrentReadSurface(EGLSurface surface);
EGLSurface getCurrentReadSurface();
-void error(EGLint errorCode);
-
-template<class T>
-const T &error(EGLint errorCode, const T &returnValue)
-{
- error(errorCode);
-
- return returnValue;
-}
-
-template<class T>
-const T &success(const T &returnValue)
-{
- egl::setCurrentError(EGL_SUCCESS);
-
- return returnValue;
-}
-
}
#endif // LIBEGL_MAIN_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h b/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
index 4d7dde04e1..4f7f5f2c85 100644
--- a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
+++ b/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
@@ -15,6 +15,7 @@
#include <cstddef>
#include <string>
#include <vector>
+#include <stdint.h>
namespace gl
{
@@ -26,7 +27,7 @@ class BinaryInputStream
{
mError = false;
mOffset = 0;
- mData = static_cast<const char*>(data);
+ mData = static_cast<const uint8_t*>(data);
mLength = length;
}
@@ -85,7 +86,7 @@ class BinaryInputStream
return;
}
- v->assign(mData + mOffset, length);
+ v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
mOffset += length;
}
@@ -115,11 +116,16 @@ class BinaryInputStream
return mOffset == mLength;
}
+ const uint8_t *data()
+ {
+ return mData;
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(BinaryInputStream);
bool mError;
size_t mOffset;
- const char *mData;
+ const uint8_t *mData;
size_t mLength;
template <typename T>
diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libGLESv2/Buffer.h
index 35a6767502..daa862ca0d 100644
--- a/src/3rdparty/angle/src/libGLESv2/Buffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Buffer.h
@@ -19,7 +19,6 @@
namespace rx
{
-class Renderer;
class BufferImpl;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp
index 5342de1331..b87689cd3f 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp
@@ -9,10 +9,8 @@
#include "libGLESv2/Context.h"
-#include "libGLESv2/main.h"
#include "common/utilities.h"
#include "common/platform.h"
-#include "libGLESv2/formatutils.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Fence.h"
#include "libGLESv2/Framebuffer.h"
@@ -21,14 +19,15 @@
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/Query.h"
-#include "libGLESv2/Texture.h"
#include "libGLESv2/ResourceManager.h"
-#include "libGLESv2/renderer/d3d/IndexDataManager.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/VertexArray.h"
#include "libGLESv2/Sampler.h"
-#include "libGLESv2/validationES.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"
@@ -38,7 +37,7 @@
namespace gl
{
-Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
+Context::Context(int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
: mRenderer(renderer)
{
ASSERT(robustAccess == false); // Unimplemented
@@ -66,22 +65,24 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
- mZeroTextures[GL_TEXTURE_2D].set(new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0));
- bindTexture(GL_TEXTURE_2D, 0);
+ Texture2D *zeroTexture2D = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 0);
+ mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D);
- mZeroTextures[GL_TEXTURE_CUBE_MAP].set(new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0));
- bindTexture(GL_TEXTURE_CUBE_MAP, 0);
+ TextureCubeMap *zeroTextureCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0);
+ mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube);
if (mClientVersion >= 3)
{
// TODO: These could also be enabled via extension
- mZeroTextures[GL_TEXTURE_3D].set(new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0));
- bindTexture(GL_TEXTURE_3D, 0);
+ Texture3D *zeroTexture3D = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 0);
+ mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D);
- mZeroTextures[GL_TEXTURE_2D_ARRAY].set(new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0));
- bindTexture(GL_TEXTURE_2D_ARRAY, 0);
+ Texture2DArray *zeroTexture2DArray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0);
+ mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray);
}
+ mState.initializeZeroTextures(mZeroTextures);
+
bindVertexArray(0);
bindArrayBuffer(0);
bindElementArrayBuffer(0);
@@ -91,13 +92,13 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
bindRenderbuffer(0);
bindGenericUniformBuffer(0);
- for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
+ for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++)
{
bindIndexedUniformBuffer(0, i, 0, -1);
}
bindGenericTransformFeedbackBuffer(0);
- for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
+ for (unsigned int i = 0; i < mCaps.maxTransformFeedbackSeparateAttributes; i++)
{
bindIndexedTransformFeedbackBuffer(0, i, 0, -1);
}
@@ -119,8 +120,6 @@ Context::Context(int clientVersion, const gl::Context *shareContext, rx::Rendere
mResetStatus = GL_NO_ERROR;
mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
mRobustAccess = robustAccess;
-
- mState.setContext(this);
}
Context::~Context()
@@ -175,7 +174,10 @@ Context::~Context()
}
mZeroTextures.clear();
- mResourceManager->release();
+ if (mResourceManager)
+ {
+ mResourceManager->release();
+ }
}
void Context::makeCurrent(egl::Surface *surface)
@@ -194,14 +196,11 @@ void Context::makeCurrent(egl::Surface *surface)
// Wrap the existing swapchain resources into GL objects and assign them to the '0' names
rx::SwapChain *swapchain = surface->getSwapChain();
- Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
- DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
- Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
+ rx::RenderbufferImpl *colorbufferZero = mRenderer->createRenderbuffer(swapchain, false);
+ rx::RenderbufferImpl *depthStencilbufferZero = mRenderer->createRenderbuffer(swapchain, true);
+ Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
setFramebufferZero(framebufferZero);
-
- // Store the current client version in the renderer
- mRenderer->setCurrentClientVersion(mClientVersion);
}
// NOTE: this function should not assume that this context is current!
@@ -229,7 +228,7 @@ GLuint Context::createProgram()
GLuint Context::createShader(GLenum type)
{
- return mResourceManager->createShader(type);
+ return mResourceManager->createShader(getData(), type);
}
GLuint Context::createTexture()
@@ -242,15 +241,10 @@ GLuint Context::createRenderbuffer()
return mResourceManager->createRenderbuffer();
}
-GLsync Context::createFenceSync(GLenum condition)
+GLsync Context::createFenceSync()
{
GLuint handle = mResourceManager->createFenceSync();
- gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle);
- ASSERT(fenceSync);
-
- fenceSync->set(condition);
-
return reinterpret_cast<GLsync>(handle);
}
@@ -294,7 +288,7 @@ GLuint Context::createFenceNV()
{
GLuint handle = mFenceNVHandleAllocator.allocate();
- mFenceNVMap[handle] = new FenceNV(mRenderer);
+ mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV());
return handle;
}
@@ -355,12 +349,12 @@ void Context::deleteFenceSync(GLsync fenceSync)
// wait commands finish. However, since the name becomes invalid, we cannot query the fence,
// and since our API is currently designed for being called from a single thread, we can delete
// the fence immediately.
- mResourceManager->deleteFenceSync(uintptr_t(fenceSync));
+ mResourceManager->deleteFenceSync(reinterpret_cast<uintptr_t>(fenceSync));
}
void Context::deleteVertexArray(GLuint vertexArray)
{
- auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
+ VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray);
if (vertexArrayObject != mVertexArrayMap.end())
{
@@ -461,12 +455,12 @@ Renderbuffer *Context::getRenderbuffer(GLuint handle)
FenceSync *Context::getFenceSync(GLsync handle) const
{
- return mResourceManager->getFenceSync(uintptr_t(handle));
+ return mResourceManager->getFenceSync(reinterpret_cast<uintptr_t>(handle));
}
VertexArray *Context::getVertexArray(GLuint handle) const
{
- auto vertexArray = mVertexArrayMap.find(handle);
+ VertexArrayMap::const_iterator vertexArray = mVertexArrayMap.find(handle);
if (vertexArray == mVertexArrayMap.end())
{
@@ -515,18 +509,30 @@ void Context::bindElementArrayBuffer(unsigned int buffer)
mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer));
}
-void Context::bindTexture(GLenum target, GLuint texture)
+void Context::bindTexture(GLenum target, GLuint handle)
{
- mResourceManager->checkTextureAllocation(texture, target);
+ Texture *texture = NULL;
+
+ if (handle == 0)
+ {
+ texture = mZeroTextures[target].get();
+ }
+ else
+ {
+ mResourceManager->checkTextureAllocation(handle, target);
+ texture = getTexture(handle);
+ }
- mState.setSamplerTexture(target, getTexture(texture));
+ ASSERT(texture);
+
+ mState.setSamplerTexture(target, texture);
}
void Context::bindReadFramebuffer(GLuint framebuffer)
{
if (!getFramebuffer(framebuffer))
{
- mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
+ mFramebufferMap[framebuffer] = new Framebuffer(framebuffer);
}
mState.setReadFramebufferBinding(getFramebuffer(framebuffer));
@@ -536,7 +542,7 @@ void Context::bindDrawFramebuffer(GLuint framebuffer)
{
if (!getFramebuffer(framebuffer))
{
- mFramebufferMap[framebuffer] = new Framebuffer(mRenderer, framebuffer);
+ mFramebufferMap[framebuffer] = new Framebuffer(framebuffer);
}
mState.setDrawFramebufferBinding(getFramebuffer(framebuffer));
@@ -640,33 +646,44 @@ void Context::useProgram(GLuint program)
}
}
-void Context::linkProgram(GLuint program)
+Error Context::linkProgram(GLuint program)
{
Program *programObject = mResourceManager->getProgram(program);
- bool linked = programObject->link(getCaps());
+ 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 (linked && program == mState.getCurrentProgramId())
+ if (programObject->isLinked() && program == mState.getCurrentProgramId())
{
mState.setCurrentProgramBinary(programObject->getProgramBinary());
}
+
+ return Error(GL_NO_ERROR);
}
-void Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
+Error Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
{
Program *programObject = mResourceManager->getProgram(program);
- bool loaded = programObject->setProgramBinary(binaryFormat, binary, length);
+ 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 (loaded && program == mState.getCurrentProgramId())
+ if (programObject->isLinked() && program == mState.getCurrentProgramId())
{
mState.setCurrentProgramBinary(programObject->getProgramBinary());
}
+ return Error(GL_NO_ERROR);
}
void Context::bindTransformFeedback(GLuint transformFeedback)
@@ -724,33 +741,6 @@ void Context::setFramebufferZero(Framebuffer *buffer)
mFramebufferMap[0] = buffer;
}
-void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
-{
- ASSERT(getTextureCaps().get(internalformat).renderable);
-
- RenderbufferStorage *renderbuffer = NULL;
-
- const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
- if (formatInfo.depthBits > 0 && formatInfo.stencilBits > 0)
- {
- renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
- }
- else if (formatInfo.depthBits > 0)
- {
- renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
- }
- else if (formatInfo.stencilBits > 0)
- {
- renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
- }
- else
- {
- renderbuffer = new gl::Colorbuffer(mRenderer, width, height, internalformat, samples);
- }
-
- mState.getCurrentRenderbuffer()->setStorage(renderbuffer);
-}
-
Framebuffer *Context::getFramebuffer(unsigned int handle) const
{
FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
@@ -837,14 +827,7 @@ Texture2DArray *Context::getTexture2DArray() const
Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const
{
- if (mState.getSamplerTextureId(sampler, type) == 0)
- {
- return mZeroTextures.at(type).get();
- }
- else
- {
- return mState.getSamplerTexture(sampler, type);
- }
+ return mState.getSamplerTexture(sampler, type);
}
void Context::getBooleanv(GLenum pname, GLboolean *params)
@@ -962,7 +945,7 @@ void Context::getIntegerv(GLenum pname, GLint *params)
*params = static_cast<GLint>(mExtensionStrings.size());
break;
default:
- mState.getIntegerv(pname, params);
+ mState.getIntegerv(getData(), pname, params);
break;
}
}
@@ -1309,309 +1292,6 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned
return false;
}
-// Applies the render target surface, depth stencil surface, viewport rectangle and
-// scissor rectangle to the renderer
-Error Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
-{
- Framebuffer *framebufferObject = mState.getDrawFramebuffer();
- ASSERT(framebufferObject && framebufferObject->completeness() == GL_FRAMEBUFFER_COMPLETE);
-
- gl::Error error = mRenderer->applyRenderTarget(framebufferObject);
- if (error.isError())
- {
- return error;
- }
-
- float nearZ, farZ;
- mState.getDepthRange(&nearZ, &farZ);
- mRenderer->setViewport(mState.getViewport(), nearZ, farZ, drawMode, mState.getRasterizerState().frontFace,
- ignoreViewport);
-
- mRenderer->setScissorRectangle(mState.getScissor(), mState.isScissorTestEnabled());
-
- return gl::Error(GL_NO_ERROR);
-}
-
-// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
-Error Context::applyState(GLenum drawMode)
-{
- Framebuffer *framebufferObject = mState.getDrawFramebuffer();
- int samples = framebufferObject->getSamples();
-
- RasterizerState rasterizer = mState.getRasterizerState();
- rasterizer.pointDrawMode = (drawMode == GL_POINTS);
- rasterizer.multiSample = (samples != 0);
-
- Error error = mRenderer->setRasterizerState(rasterizer);
- if (error.isError())
- {
- return error;
- }
-
- unsigned int mask = 0;
- if (mState.isSampleCoverageEnabled())
- {
- GLclampf coverageValue;
- bool coverageInvert = false;
- mState.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 = mRenderer->setBlendState(framebufferObject, mState.getBlendState(), mState.getBlendColor(), mask);
- if (error.isError())
- {
- return error;
- }
-
- error = mRenderer->setDepthStencilState(mState.getDepthStencilState(), mState.getStencilRef(), mState.getStencilBackRef(),
- rasterizer.frontFace == GL_CCW);
- if (error.isError())
- {
- return error;
- }
-
- return Error(GL_NO_ERROR);
-}
-
-// Applies the shaders and shader constants to the Direct3D 9 device
-Error Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
-{
- const VertexAttribute *vertexAttributes = mState.getVertexArray()->getVertexAttributes();
-
- VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
- VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.getVertexAttribCurrentValues());
-
- const Framebuffer *fbo = mState.getDrawFramebuffer();
-
- Error error = mRenderer->applyShaders(programBinary, inputLayout, fbo, mState.getRasterizerState().rasterizerDiscard, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- return programBinary->applyUniforms();
-}
-
-Error Context::generateSwizzles(ProgramBinary *programBinary, SamplerType type)
-{
- 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, getCaps());
- if (textureUnit != -1)
- {
- Texture* texture = getSamplerTexture(textureUnit, textureType);
- if (texture->getSamplerState().swizzleRequired())
- {
- Error error = mRenderer->generateSwizzle(texture);
- if (error.isError())
- {
- return error;
- }
- }
- }
- }
-
- return Error(GL_NO_ERROR);
-}
-
-Error Context::generateSwizzles(ProgramBinary *programBinary)
-{
- Error error = generateSwizzles(programBinary, SAMPLER_VERTEX);
- if (error.isError())
- {
- return error;
- }
-
- error = generateSwizzles(programBinary, SAMPLER_PIXEL);
- if (error.isError())
- {
- return error;
- }
-
- return Error(GL_NO_ERROR);
-}
-
-// 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).
-Error Context::applyTextures(ProgramBinary *programBinary, SamplerType shaderType,
- const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount)
-{
- 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, getCaps());
- if (textureUnit != -1)
- {
- SamplerState sampler;
- Texture* texture = getSamplerTexture(textureUnit, textureType);
- texture->getSamplerStateWithNativeOffset(&sampler);
-
- Sampler *samplerObject = mState.getSampler(textureUnit);
- if (samplerObject)
- {
- samplerObject->getState(&sampler);
- }
-
- // TODO: std::binary_search may become unavailable using older versions of GCC
- if (texture->isSamplerComplete(sampler, mTextureCaps, mExtensions, mClientVersion) &&
- !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
- {
- Error error = mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
- if (error.isError())
- {
- return error;
- }
-
- error = mRenderer->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.
- Texture *incompleteTexture = getIncompleteTexture(textureType);
- gl::Error error = mRenderer->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
- Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL);
- if (error.isError())
- {
- return error;
- }
- }
- }
-
- // Set all the remaining textures to NULL
- size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? mCaps.maxTextureImageUnits
- : mCaps.maxVertexTextureImageUnits;
- for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
- {
- Error error = mRenderer->setTexture(shaderType, samplerIndex, NULL);
- if (error.isError())
- {
- return error;
- }
- }
-
- return Error(GL_NO_ERROR);
-}
-
-Error Context::applyTextures(ProgramBinary *programBinary)
-{
- FramebufferTextureSerialArray framebufferSerials;
- size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&framebufferSerials);
-
- Error error = applyTextures(programBinary, SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(programBinary, SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount);
- if (error.isError())
- {
- return error;
- }
-
- return Error(GL_NO_ERROR);
-}
-
-Error Context::applyUniformBuffers()
-{
- Program *programObject = getProgram(mState.getCurrentProgramId());
- ProgramBinary *programBinary = programObject->getProgramBinary();
-
- std::vector<Buffer*> boundBuffers;
-
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
- {
- GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
-
- if (mState.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
- {
- Buffer *uniformBuffer = mState.getIndexedUniformBuffer(blockBinding);
- ASSERT(uniformBuffer);
- boundBuffers.push_back(uniformBuffer);
- }
- }
-
- return programBinary->applyUniformBuffers(boundBuffers, getCaps());
-}
-
-bool Context::applyTransformFeedbackBuffers()
-{
- TransformFeedback *curTransformFeedback = mState.getCurrentTransformFeedback();
- if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
- {
- Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
- GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
- for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
- {
- transformFeedbackBuffers[i] = mState.getIndexedTransformFeedbackBuffer(i);
- transformFeedbackOffsets[i] = mState.getIndexedTransformFeedbackBufferOffset(i);
- }
- mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets);
- return true;
- }
- else
- {
- return false;
- }
-}
-
-void Context::markTransformFeedbackUsage()
-{
- for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
- {
- Buffer *buffer = mState.getIndexedTransformFeedbackBuffer(i);
- if (buffer)
- {
- buffer->markTransformFeedbackUsage();
- }
- }
-}
-
Error Context::clear(GLbitfield mask)
{
if (mState.isRasterizerDiscardEnabled())
@@ -1619,290 +1299,71 @@ Error Context::clear(GLbitfield mask)
return Error(GL_NO_ERROR);
}
- ClearParameters clearParams = mState.getClearParameters(mask);
-
- applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
-
- return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clear(getData(), mask);
}
-Error Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
+Error Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
- // glClearBufferfv can be called to clear the color buffer or depth buffer
- ClearParameters clearParams = mState.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 = ColorF(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_FLOAT;
- }
-
- if (buffer == GL_DEPTH)
- {
- clearParams.clearDepth = true;
- clearParams.depthClearValue = values[0];
- }
-
- applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
-
- return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clearBufferfv(getData(), buffer, drawbuffer, values);
}
-Error Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
+Error Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
- // glClearBufferuv can only be called to clear a color buffer
- ClearParameters clearParams = mState.getClearParameters(0);
- for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
- {
- clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
- }
- clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_UNSIGNED_INT;
-
- applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
-
- return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clearBufferuiv(getData(), buffer, drawbuffer, values);
}
-Error Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
+Error Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
- // glClearBufferfv can be called to clear the color buffer or stencil buffer
- ClearParameters clearParams = mState.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 = ColorI(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_INT;
- }
-
- if (buffer == GL_STENCIL)
- {
- clearParams.clearStencil = true;
- clearParams.stencilClearValue = values[1];
- }
-
- applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
-
- return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ return mRenderer->clearBufferiv(getData(), buffer, drawbuffer, values);
}
-Error Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
+Error Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
{
if (mState.isRasterizerDiscardEnabled())
{
return Error(GL_NO_ERROR);
}
- // glClearBufferfi can only be called to clear a depth stencil buffer
- ClearParameters clearParams = mState.getClearParameters(0);
- clearParams.clearDepth = true;
- clearParams.depthClearValue = depth;
- clearParams.clearStencil = true;
- clearParams.stencilClearValue = stencil;
-
- applyRenderTarget(GL_TRIANGLES, true); // Clips the clear to the scissor rectangle but not the viewport
-
- return mRenderer->clear(clearParams, mState.getDrawFramebuffer());
+ 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)
{
- Framebuffer *framebuffer = mState.getReadFramebuffer();
-
- GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
- const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
- GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, width, mState.getPackAlignment());
-
- return mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.getPackState(),
- reinterpret_cast<uint8_t*>(pixels));
+ return mRenderer->readPixels(getData(), x, y, width, height, format, type, bufSize, pixels);
}
Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
- ASSERT(mState.getCurrentProgramId() != 0);
-
- ProgramBinary *programBinary = mState.getCurrentProgramBinary();
- programBinary->updateSamplerMapping();
-
- Error error = generateSwizzles(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- if (!mRenderer->applyPrimitiveType(mode, count))
- {
- return Error(GL_NO_ERROR);
- }
-
- error = applyRenderTarget(mode, false);
- if (error.isError())
- {
- return error;
- }
-
- error = applyState(mode);
- if (error.isError())
- {
- return error;
- }
-
- error = mRenderer->applyVertexBuffer(programBinary, mState.getVertexArray()->getVertexAttributes(), mState.getVertexAttribCurrentValues(), first, count, instances);
- if (error.isError())
- {
- return error;
- }
-
- bool transformFeedbackActive = applyTransformFeedbackBuffers();
-
- error = applyShaders(programBinary, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- error = applyUniformBuffers();
- if (error.isError())
- {
- return error;
- }
-
- if (!skipDraw(mode))
- {
- error = mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- if (transformFeedbackActive)
- {
- markTransformFeedbackUsage();
- }
- }
-
- return gl::Error(GL_NO_ERROR);
+ return mRenderer->drawArrays(getData(), mode, first, count, instances);
}
Error Context::drawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei instances,
const rx::RangeUI &indexRange)
{
- ASSERT(mState.getCurrentProgramId() != 0);
-
- ProgramBinary *programBinary = mState.getCurrentProgramBinary();
- programBinary->updateSamplerMapping();
-
- Error error = generateSwizzles(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- if (!mRenderer->applyPrimitiveType(mode, count))
- {
- return Error(GL_NO_ERROR);
- }
-
- error = applyRenderTarget(mode, false);
- if (error.isError())
- {
- return error;
- }
-
- error = applyState(mode);
- if (error.isError())
- {
- return error;
- }
-
- VertexArray *vao = mState.getVertexArray();
- rx::TranslatedIndexData indexInfo;
- indexInfo.indexRange = indexRange;
- error = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
- if (error.isError())
- {
- return error;
- }
-
- GLsizei vertexCount = indexInfo.indexRange.length() + 1;
- error = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(),
- mState.getVertexAttribCurrentValues(),
- indexInfo.indexRange.start, vertexCount, instances);
- if (error.isError())
- {
- return error;
- }
-
- bool transformFeedbackActive = applyTransformFeedbackBuffers();
- // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
- // layer.
- ASSERT(!transformFeedbackActive);
-
- error = applyShaders(programBinary, transformFeedbackActive);
- if (error.isError())
- {
- return error;
- }
-
- error = applyTextures(programBinary);
- if (error.isError())
- {
- return error;
- }
-
- error = applyUniformBuffers();
- if (error.isError())
- {
- return error;
- }
-
- if (!skipDraw(mode))
- {
- error = mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
- if (error.isError())
- {
- return error;
- }
- }
-
- return Error(GL_NO_ERROR);
+ return mRenderer->drawElements(getData(), mode, count, type, indices, instances, indexRange);
}
// Implements glFlush when block is false, glFinish when block is true
-void Context::sync(bool block)
+Error Context::sync(bool block)
{
- mRenderer->sync(block);
+ return mRenderer->sync(block);
}
void Context::recordError(const Error &error)
@@ -1931,6 +1392,7 @@ GLenum Context::getError()
GLenum Context::getResetStatus()
{
+ //TODO(jmadill): needs MANGLE reworking
if (mResetStatus == GL_NO_ERROR && !mContextLost)
{
// mResetStatus will be set by the markContextLost callback
@@ -1981,7 +1443,7 @@ const Extensions &Context::getExtensions() const
void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
{
Framebuffer *framebuffer = mState.getReadFramebuffer();
- ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE);
+ ASSERT(framebuffer && framebuffer->completeness(getData()) == GL_FRAMEBUFFER_COMPLETE);
FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
ASSERT(attachment);
@@ -2000,7 +1462,7 @@ void Context::detachTexture(GLuint texture)
// allocation map management either here or in the resource manager at detach time.
// Zero textures are held by the Context, and we don't attempt to request them from
// the State.
- mState.detachTexture(texture);
+ mState.detachTexture(mZeroTextures, texture);
}
void Context::detachBuffer(GLuint buffer)
@@ -2072,95 +1534,6 @@ void Context::detachSampler(GLuint sampler)
mState.detachSampler(sampler);
}
-Texture *Context::getIncompleteTexture(GLenum type)
-{
- if (mIncompleteTextures.find(type) == mIncompleteTextures.end())
- {
- const GLubyte color[] = { 0, 0, 0, 255 };
- const PixelUnpackState incompleteUnpackState(1);
-
- Texture* t = NULL;
- switch (type)
- {
- default:
- UNREACHABLE();
- // default falls through to TEXTURE_2D
-
- case GL_TEXTURE_2D:
- {
- Texture2D *incomplete2d = new Texture2D(mRenderer->createTexture(GL_TEXTURE_2D), 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:
- {
- TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), Texture::INCOMPLETE_TEXTURE_ID);
-
- incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
- incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
-
- t = incompleteCube;
- }
- break;
-
- case GL_TEXTURE_3D:
- {
- Texture3D *incomplete3d = new Texture3D(mRenderer->createTexture(GL_TEXTURE_3D), 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:
- {
- Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 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();
-}
-
-bool Context::skipDraw(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 (!mState.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 (IsTriangleMode(drawMode))
- {
- if (mState.getRasterizerState().cullFace && mState.getRasterizerState().cullMode == GL_FRONT_AND_BACK)
- {
- return true;
- }
- }
-
- return false;
-}
-
void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
{
mState.getVertexArray()->setVertexAttribDivisor(index, divisor);
@@ -2293,63 +1666,12 @@ size_t Context::getExtensionStringCount() const
return mExtensionStrings.size();
}
-size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray)
+Error Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
{
- size_t serialCount = 0;
-
- Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
- for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
- {
- FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
- if (attachment && attachment->isTexture())
- {
- Texture *texture = attachment->getTexture();
- (*outSerialArray)[serialCount++] = texture->getTextureSerial();
- }
- }
-
- FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
- if (depthStencilAttachment && depthStencilAttachment->isTexture())
- {
- Texture *depthStencilTexture = depthStencilAttachment->getTexture();
- (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial();
- }
-
- std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
-
- return serialCount;
-}
-
-void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- Framebuffer *readFramebuffer = mState.getReadFramebuffer();
- Framebuffer *drawFramebuffer = mState.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;
- }
-
- Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
- Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
- if (blitRenderTarget || blitDepth || blitStencil)
- {
- const Rectangle *scissor = mState.isScissorTestEnabled() ? &mState.getScissor() : NULL;
- mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
- blitRenderTarget, blitDepth, blitStencil, filter);
- }
+ return mRenderer->blitFramebuffer(getData(), srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1, mask, filter);
}
void Context::releaseShaderCompiler()
@@ -2416,6 +1738,11 @@ void Context::initCaps(GLuint clientVersion)
mExtensions.maxSamples = maxSamples;
}
+Data Context::getData() const
+{
+ return Data(mClientVersion, mState, mCaps, mTextureCaps, mExtensions, mResourceManager);
+}
+
}
extern "C"
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.h b/src/3rdparty/angle/src/libGLESv2/Context.h
index 1b888aec83..1e890de3ef 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.h
+++ b/src/3rdparty/angle/src/libGLESv2/Context.h
@@ -13,12 +13,12 @@
#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/angletypes.h"
-#include "libGLESv2/Constants.h"
#include "libGLESv2/VertexAttribute.h"
-#include "libGLESv2/State.h"
+#include "libGLESv2/angletypes.h"
#include "angle_gl.h"
@@ -50,11 +50,6 @@ class Texture3D;
class Texture2DArray;
class Framebuffer;
class Renderbuffer;
-class RenderbufferStorage;
-class Colorbuffer;
-class Depthbuffer;
-class Stencilbuffer;
-class DepthStencilbuffer;
class FenceNV;
class FenceSync;
class Query;
@@ -68,7 +63,7 @@ class TransformFeedback;
class Context
{
public:
- Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
+ Context(int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
virtual ~Context();
@@ -86,7 +81,7 @@ class Context
GLuint createRenderbuffer();
GLuint createSampler();
GLuint createTransformFeedback();
- GLsync createFenceSync(GLenum condition);
+ GLsync createFenceSync();
void deleteBuffer(GLuint buffer);
void deleteShader(GLuint shader);
@@ -115,7 +110,7 @@ class Context
void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer);
- void bindTexture(GLenum target, GLuint texture);
+ void bindTexture(GLenum target, GLuint handle);
void bindReadFramebuffer(GLuint framebuffer);
void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
@@ -130,8 +125,8 @@ class Context
void bindPixelPackBuffer(GLuint buffer);
void bindPixelUnpackBuffer(GLuint buffer);
void useProgram(GLuint program);
- void linkProgram(GLuint program);
- void setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length);
+ 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);
@@ -139,8 +134,6 @@ class Context
void setFramebufferZero(Framebuffer *framebuffer);
- void setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
-
void setVertexAttribDivisor(GLuint index, GLuint divisor);
void samplerParameteri(GLuint sampler, GLenum pname, GLint param);
@@ -183,17 +176,17 @@ class Context
bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
Error clear(GLbitfield mask);
- Error clearBufferfv(GLenum buffer, int drawbuffer, const float *values);
- Error clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values);
- Error clearBufferiv(GLenum buffer, int drawbuffer, const int *values);
- Error clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil);
+ 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);
- void sync(bool block); // flush/finish
+ Error sync(bool block); // flush/finish
void recordError(const Error &error);
@@ -215,32 +208,21 @@ class Context
void getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type);
- void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter);
+ 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; }
const State &getState() const { return mState; }
+ Data getData() const;
+
void releaseShaderCompiler();
private:
DISALLOW_COPY_AND_ASSIGN(Context);
- // TODO: std::array may become unavailable using older versions of GCC
- typedef std::array<unsigned int, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS> FramebufferTextureSerialArray;
-
- Error applyRenderTarget(GLenum drawMode, bool ignoreViewport);
- Error applyState(GLenum drawMode);
- Error applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive);
- Error applyTextures(ProgramBinary *programBinary, SamplerType shaderType, const FramebufferTextureSerialArray &framebufferSerials,
- size_t framebufferSerialCount);
- Error applyTextures(ProgramBinary *programBinary);
- Error applyUniformBuffers();
- bool applyTransformFeedbackBuffers();
- void markTransformFeedbackUsage();
-
void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer);
@@ -249,18 +231,9 @@ class Context
void detachTransformFeedback(GLuint transformFeedback);
void detachSampler(GLuint sampler);
- Error generateSwizzles(ProgramBinary *programBinary, SamplerType type);
- Error generateSwizzles(ProgramBinary *programBinary);
-
- Texture *getIncompleteTexture(GLenum type);
-
- bool skipDraw(GLenum drawMode);
-
void initRendererString();
void initExtensionStrings();
- size_t getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray);
-
void initCaps(GLuint clientVersion);
// Caps to use for validation
@@ -273,7 +246,6 @@ class Context
int mClientVersion;
- typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
TextureMap mZeroTextures;
TextureMap mIncompleteTextures;
diff --git a/src/3rdparty/angle/src/libGLESv2/Data.cpp b/src/3rdparty/angle/src/libGLESv2/Data.cpp
new file mode 100644
index 0000000000..3ddf591d77
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/Data.cpp
@@ -0,0 +1,51 @@
+//
+// 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.
+//
+
+// Data.cpp: Container class for all GL relevant state, caps and objects
+
+#include "libGLESv2/Data.h"
+#include "libGLESv2/ResourceManager.h"
+
+namespace gl
+{
+
+Data::Data(GLint clientVersionIn, const State &stateIn, const Caps &capsIn,
+ const TextureCapsMap &textureCapsIn, const Extensions &extensionsIn,
+ const ResourceManager *resourceManagerIn)
+ : clientVersion(clientVersionIn),
+ state(&stateIn),
+ caps(&capsIn),
+ textureCaps(&textureCapsIn),
+ extensions(&extensionsIn),
+ resourceManager(resourceManagerIn)
+{}
+
+Data::~Data()
+{
+}
+
+Data::Data(const Data &other)
+ : clientVersion(other.clientVersion),
+ state(other.state),
+ caps(other.caps),
+ textureCaps(other.textureCaps),
+ extensions(other.extensions),
+ resourceManager(other.resourceManager)
+{
+}
+
+Data &Data::operator=(const Data &other)
+{
+ clientVersion = other.clientVersion;
+ state = other.state;
+ caps = other.caps;
+ textureCaps = other.textureCaps;
+ extensions = other.extensions;
+ resourceManager = other.resourceManager;
+ return *this;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/Data.h b/src/3rdparty/angle/src/libGLESv2/Data.h
new file mode 100644
index 0000000000..9234403e13
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/Data.h
@@ -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.
+//
+
+// Data.h: Container class for all GL relevant state, caps and objects
+
+#ifndef LIBGLESV2_DATA_H_
+#define LIBGLESV2_DATA_H_
+
+#include "libGLESv2/State.h"
+
+namespace gl
+{
+
+struct Data
+{
+ public:
+ Data(GLint clientVersion, const State &state, const Caps &caps,
+ const TextureCapsMap &textureCaps, const Extensions &extensions,
+ const ResourceManager *resourceManager);
+ ~Data();
+
+ Data(const Data &other);
+ Data &operator=(const Data &other);
+
+ GLint clientVersion;
+ const State *state;
+ const Caps *caps;
+ const TextureCapsMap *textureCaps;
+ const Extensions *extensions;
+ const ResourceManager *resourceManager;
+};
+
+}
+
+#endif // LIBGLESV2_DATA_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.cpp b/src/3rdparty/angle/src/libGLESv2/Fence.cpp
index ee9a07a5c4..966a327de5 100644
--- a/src/3rdparty/angle/src/libGLESv2/Fence.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Fence.cpp
@@ -4,191 +4,113 @@
// found in the LICENSE file.
//
-// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension.
-
-// Important note on accurate timers in Windows:
-//
-// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call
-// as timeGetTime on laptops and "jumping" during certain hardware events.
-//
-// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc"
-// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc
-//
-// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer
-// from buggy implementations.
+// 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 "common/utilities.h"
#include "angle_gl.h"
namespace gl
{
-FenceNV::FenceNV(rx::Renderer *renderer)
+FenceNV::FenceNV(rx::FenceNVImpl *impl)
+ : mFence(impl),
+ mIsSet(false),
+ mStatus(GL_FALSE),
+ mCondition(GL_NONE)
{
- mFence = renderer->createFence();
}
FenceNV::~FenceNV()
{
- delete mFence;
+ SafeDelete(mFence);
}
GLboolean FenceNV::isFence() const
{
// GL_NV_fence spec:
// A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
- return (mFence->isSet() ? GL_TRUE : GL_FALSE);
+ return (mIsSet ? GL_TRUE : GL_FALSE);
}
-void FenceNV::setFence(GLenum condition)
+Error FenceNV::setFence(GLenum condition)
{
- mFence->set();
+ Error error = mFence->set();
+ if (error.isError())
+ {
+ return error;
+ }
mCondition = condition;
mStatus = GL_FALSE;
-}
-
-GLboolean FenceNV::testFence()
-{
- // Flush the command buffer by default
- bool result = mFence->test(true);
+ mIsSet = true;
- mStatus = (result ? GL_TRUE : GL_FALSE);
- return mStatus;
+ return Error(GL_NO_ERROR);
}
-void FenceNV::finishFence()
+Error FenceNV::testFence(GLboolean *outResult)
{
- ASSERT(mFence->isSet());
-
- while (!mFence->test(true))
+ // Flush the command buffer by default
+ Error error = mFence->test(true, &mStatus);
+ if (error.isError())
{
- Sleep(0);
+ return error;
}
-}
-
-GLint FenceNV::getFencei(GLenum pname)
-{
- ASSERT(mFence->isSet());
- switch (pname)
- {
- case GL_FENCE_STATUS_NV:
- {
- // GL_NV_fence spec:
- // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
- // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
- if (mStatus == GL_TRUE)
- {
- return GL_TRUE;
- }
-
- mStatus = (mFence->test(false) ? GL_TRUE : GL_FALSE);
- return mStatus;
- }
-
- case GL_FENCE_CONDITION_NV:
- return mCondition;
-
- default: UNREACHABLE(); return 0;
- }
+ *outResult = mStatus;
+ return Error(GL_NO_ERROR);
}
-FenceSync::FenceSync(rx::Renderer *renderer, GLuint id)
- : RefCountObject(id)
+Error FenceNV::finishFence()
{
- mFence = renderer->createFence();
-
- LARGE_INTEGER counterFreqency = { 0 };
- BOOL success = QueryPerformanceFrequency(&counterFreqency);
- UNUSED_ASSERTION_VARIABLE(success);
- ASSERT(success);
+ ASSERT(mIsSet);
- mCounterFrequency = counterFreqency.QuadPart;
+ return mFence->finishFence(&mStatus);
}
-FenceSync::~FenceSync()
+FenceSync::FenceSync(rx::FenceSyncImpl *impl, GLuint id)
+ : RefCountObject(id),
+ mFence(impl),
+ mCondition(GL_NONE)
{
- delete mFence;
}
-void FenceSync::set(GLenum condition)
+FenceSync::~FenceSync()
{
- mCondition = condition;
- mFence->set();
+ SafeDelete(mFence);
}
-GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout)
+Error FenceSync::set(GLenum condition)
{
- ASSERT(mFence->isSet());
-
- bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0);
-
- if (mFence->test(flushCommandBuffer))
+ Error error = mFence->set();
+ if (error.isError())
{
- return GL_ALREADY_SIGNALED;
+ return error;
}
- if (mFence->hasError())
- {
- return GL_WAIT_FAILED;
- }
-
- if (timeout == 0)
- {
- return GL_TIMEOUT_EXPIRED;
- }
-
- LARGE_INTEGER currentCounter = { 0 };
- BOOL success = QueryPerformanceCounter(&currentCounter);
- UNUSED_ASSERTION_VARIABLE(success);
- ASSERT(success);
-
- LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll);
- LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds;
-
- while (currentCounter.QuadPart < endCounter && !mFence->test(flushCommandBuffer))
- {
- Sleep(0);
- BOOL success = QueryPerformanceCounter(&currentCounter);
- UNUSED_ASSERTION_VARIABLE(success);
- ASSERT(success);
- }
-
- if (mFence->hasError())
- {
- return GL_WAIT_FAILED;
- }
-
- if (currentCounter.QuadPart >= endCounter)
- {
- return GL_TIMEOUT_EXPIRED;
- }
-
- return GL_CONDITION_SATISFIED;
+ mCondition = condition;
+ return Error(GL_NO_ERROR);
}
-void FenceSync::serverWait()
+Error FenceSync::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult)
{
- // Because our API is currently designed to be called from a single thread, we don't need to do
- // extra work for a server-side fence. GPU commands issued after the fence is created will always
- // be processed after the fence is signaled.
+ ASSERT(mCondition != GL_NONE);
+ return mFence->clientWait(flags, timeout, outResult);
}
-GLenum FenceSync::getStatus() const
+Error FenceSync::serverWait(GLbitfield flags, GLuint64 timeout)
{
- if (mFence->test(false))
- {
- // The spec does not specify any way to report errors during the status test (e.g. device lost)
- // so we report the fence is unblocked in case of error or signaled.
- return GL_SIGNALED;
- }
+ return mFence->serverWait(flags, timeout);
+}
- return GL_UNSIGNALED;
+Error FenceSync::getStatus(GLint *outResult) const
+{
+ return mFence->getStatus(outResult);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.h b/src/3rdparty/angle/src/libGLESv2/Fence.h
index 291edb3de1..fd565e96a6 100644
--- a/src/3rdparty/angle/src/libGLESv2/Fence.h
+++ b/src/3rdparty/angle/src/libGLESv2/Fence.h
@@ -4,18 +4,21 @@
// found in the LICENSE file.
//
-// Fence.h: Defines the gl::Fence class, which supports the GL_NV_fence extension.
+// 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_
+#include "libGLESv2/Error.h"
+
#include "common/angleutils.h"
#include "common/RefCountObject.h"
namespace rx
{
-class Renderer;
-class FenceImpl;
+class FenceNVImpl;
+class FenceSyncImpl;
}
namespace gl
@@ -24,14 +27,13 @@ namespace gl
class FenceNV
{
public:
- explicit FenceNV(rx::Renderer *renderer);
+ explicit FenceNV(rx::FenceNVImpl *impl);
virtual ~FenceNV();
GLboolean isFence() const;
- void setFence(GLenum condition);
- GLboolean testFence();
- void finishFence();
- GLint getFencei(GLenum pname);
+ Error setFence(GLenum condition);
+ Error testFence(GLboolean *outResult);
+ Error finishFence();
GLboolean getStatus() const { return mStatus; }
GLuint getCondition() const { return mCondition; }
@@ -39,7 +41,9 @@ class FenceNV
private:
DISALLOW_COPY_AND_ASSIGN(FenceNV);
- rx::FenceImpl *mFence;
+ rx::FenceNVImpl *mFence;
+
+ bool mIsSet;
GLboolean mStatus;
GLenum mCondition;
@@ -48,21 +52,20 @@ class FenceNV
class FenceSync : public RefCountObject
{
public:
- explicit FenceSync(rx::Renderer *renderer, GLuint id);
+ explicit FenceSync(rx::FenceSyncImpl *impl, GLuint id);
virtual ~FenceSync();
- void set(GLenum condition);
- GLenum clientWait(GLbitfield flags, GLuint64 timeout);
- void serverWait();
- GLenum getStatus() const;
+ Error set(GLenum condition);
+ Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult);
+ Error serverWait(GLbitfield flags, GLuint64 timeout);
+ Error getStatus(GLint *outResult) const;
GLuint getCondition() const { return mCondition; }
private:
DISALLOW_COPY_AND_ASSIGN(FenceSync);
- rx::FenceImpl *mFence;
- LONGLONG mCounterFrequency;
+ rx::FenceSyncImpl *mFence;
GLenum mCondition;
};
diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
index 5b21433f90..3d57262e3c 100644
--- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
@@ -16,13 +16,18 @@
#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
{
-RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
+// TODO: Move these functions, and the D3D-specific header inclusions above,
+// to FramebufferD3D.
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT)
{
if (attachment->isTexture())
{
@@ -31,14 +36,16 @@ RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
const gl::ImageIndex *index = attachment->getTextureImageIndex();
ASSERT(index);
- return textureD3D->getRenderTarget(*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);
}
-
- gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
- ASSERT(renderbuffer);
-
- // TODO: cast to RenderbufferD3D
- return renderbuffer->getStorage()->getRenderTarget();
}
// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
@@ -56,9 +63,8 @@ unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
ASSERT(renderbuffer);
-
- // TODO: cast to RenderbufferD3D
- return renderbuffer->getStorage()->getSerial();
+ RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
+ return renderbufferD3D->getRenderTargetSerial();
}
}
@@ -66,9 +72,8 @@ unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment)
namespace gl
{
-Framebuffer::Framebuffer(rx::Renderer *renderer, GLuint id)
- : mRenderer(renderer),
- mId(id),
+Framebuffer::Framebuffer(GLuint id)
+ : mId(id),
mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
mDepthbuffer(NULL),
mStencilbuffer(NULL)
@@ -91,124 +96,6 @@ Framebuffer::~Framebuffer()
SafeDelete(mStencilbuffer);
}
-FramebufferAttachment *Framebuffer::createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const
-{
- if (handle == 0)
- {
- return NULL;
- }
-
- gl::Context *context = gl::getContext();
-
- switch (type)
- {
- case GL_NONE:
- return NULL;
-
- case GL_RENDERBUFFER:
- return new RenderbufferAttachment(binding, context->getRenderbuffer(handle));
-
- case GL_TEXTURE_2D:
- {
- Texture *texture = context->getTexture(handle);
- if (texture && texture->getTarget() == GL_TEXTURE_2D)
- {
- return new TextureAttachment(binding, texture, ImageIndex::Make2D(level));
- }
- else
- {
- return NULL;
- }
- }
-
- 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:
- {
- Texture *texture = context->getTexture(handle);
- if (texture && texture->getTarget() == GL_TEXTURE_CUBE_MAP)
- {
- return new TextureAttachment(binding, texture, ImageIndex::MakeCube(type, level));
- }
- else
- {
- return NULL;
- }
- }
-
- case GL_TEXTURE_3D:
- {
- Texture *texture = context->getTexture(handle);
- if (texture && texture->getTarget() == GL_TEXTURE_3D)
- {
- return new TextureAttachment(binding, texture, ImageIndex::Make3D(level, layer));
- }
- else
- {
- return NULL;
- }
- }
-
- case GL_TEXTURE_2D_ARRAY:
- {
- Texture *texture = context->getTexture(handle);
- if (texture && texture->getTarget() == GL_TEXTURE_2D_ARRAY)
- {
- return new TextureAttachment(binding, texture, ImageIndex::Make2DArray(level, layer));
- }
- else
- {
- return NULL;
- }
- }
-
- default:
- UNREACHABLE();
- return NULL;
- }
-}
-
-void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer)
-{
- ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
- SafeDelete(mColorbuffers[colorAttachment]);
- GLenum binding = colorAttachment + GL_COLOR_ATTACHMENT0;
- mColorbuffers[colorAttachment] = createAttachment(binding, type, colorbuffer, level, layer);
-}
-
-void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
-{
- SafeDelete(mDepthbuffer);
- mDepthbuffer = createAttachment(GL_DEPTH_ATTACHMENT, type, depthbuffer, level, layer);
-}
-
-void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
-{
- SafeDelete(mStencilbuffer);
- mStencilbuffer = createAttachment(GL_STENCIL_ATTACHMENT, type, stencilbuffer, level, layer);
-}
-
-void Framebuffer::setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer)
-{
- FramebufferAttachment *attachment = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
-
- SafeDelete(mDepthbuffer);
- SafeDelete(mStencilbuffer);
-
- // ensure this is a legitimate depth+stencil format
- if (attachment && attachment->getDepthSize() > 0 && attachment->getStencilSize() > 0)
- {
- mDepthbuffer = attachment;
-
- // Make a new attachment object to ensure we do not double-delete
- // See angle issue 686
- mStencilbuffer = createAttachment(GL_DEPTH_STENCIL_ATTACHMENT, type, depthStencilBuffer, level, layer);
- }
-}
-
void Framebuffer::detachTexture(GLuint textureId)
{
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
@@ -382,14 +269,13 @@ bool Framebuffer::usingExtendedDrawBuffers() const
return false;
}
-GLenum Framebuffer::completeness() const
+GLenum Framebuffer::completeness(const gl::Data &data) const
{
int width = 0;
int height = 0;
unsigned int colorbufferSize = 0;
int samples = -1;
bool missingAttachment = true;
- GLuint clientVersion = mRenderer->getCurrentClientVersion();
for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
@@ -403,8 +289,7 @@ GLenum Framebuffer::completeness() const
}
GLenum internalformat = colorbuffer->getInternalFormat();
- // TODO(geofflang): use context's texture caps
- const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+ const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (colorbuffer->isTexture())
{
@@ -443,7 +328,7 @@ GLenum Framebuffer::completeness() const
// 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 (clientVersion < 3)
+ if (data.clientVersion < 3)
{
if (formatInfo.pixelBytes != colorbufferSize)
{
@@ -483,14 +368,12 @@ GLenum Framebuffer::completeness() const
}
GLenum internalformat = mDepthbuffer->getInternalFormat();
- // TODO(geofflang): use context's texture caps
- const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+ const TextureCaps &formatCaps = data.textureCaps->get(internalformat);
const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat);
if (mDepthbuffer->isTexture())
{
// depth texture attachments require OES/ANGLE_depth_texture
- // TODO(geofflang): use context's extensions
- if (!mRenderer->getRendererExtensions().depthTextures)
+ if (!data.extensions->depthTextures)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -538,15 +421,13 @@ GLenum Framebuffer::completeness() const
}
GLenum internalformat = mStencilbuffer->getInternalFormat();
- // TODO(geofflang): use context's texture caps
- const TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(internalformat);
+ 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
- // TODO(geofflang): use context's extensions
- if (!mRenderer->getRendererExtensions().depthTextures)
+ if (!data.extensions->depthTextures)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -602,42 +483,44 @@ GLenum Framebuffer::completeness() const
return GL_FRAMEBUFFER_COMPLETE;
}
-void Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
+Error Framebuffer::invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments)
{
GLuint maxDimension = caps.maxRenderbufferSize;
- invalidateSub(caps, numAttachments, attachments, 0, 0, maxDimension, maxDimension);
+ return invalidateSub(numAttachments, attachments, 0, 0, maxDimension, maxDimension);
}
-void Framebuffer::invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
- GLint x, GLint y, GLsizei width, GLsizei height)
+Error Framebuffer::invalidateSub(GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)
{
- ASSERT(completeness() == GL_FRAMEBUFFER_COMPLETE);
for (GLsizei attachIndex = 0; attachIndex < numAttachments; ++attachIndex)
{
GLenum attachmentTarget = attachments[attachIndex];
- gl::FramebufferAttachment *attachment =
- (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer() :
- getAttachment(attachmentTarget);
+ FramebufferAttachment *attachment = (attachmentTarget == GL_DEPTH_STENCIL_ATTACHMENT) ? getDepthOrStencilbuffer()
+ : getAttachment(attachmentTarget);
if (attachment)
{
- rx::RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
- if (renderTarget)
+ rx::RenderTarget *renderTarget = NULL;
+ Error error = rx::GetAttachmentRenderTarget(attachment, &renderTarget);
+ if (error.isError())
{
- renderTarget->invalidate(x, y, width, height);
+ return error;
}
+
+ renderTarget->invalidate(x, y, width, height);
}
}
+
+ return Error(GL_NO_ERROR);
}
-DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
- : Framebuffer(renderer, 0)
+DefaultFramebuffer::DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil)
+ : Framebuffer(0)
{
- Renderbuffer *colorRenderbuffer = new Renderbuffer(0, colorbuffer);
+ Renderbuffer *colorRenderbuffer = new Renderbuffer(colorbuffer, 0);
mColorbuffers[0] = new RenderbufferAttachment(GL_BACK, colorRenderbuffer);
- Renderbuffer *depthStencilBuffer = new Renderbuffer(0, depthStencil);
+ Renderbuffer *depthStencilBuffer = new Renderbuffer(depthStencil, 0);
// Make a new attachment objects to ensure we do not double-delete
// See angle issue 686
@@ -648,9 +531,9 @@ DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colo
mReadBufferState = GL_BACK;
}
-int Framebuffer::getSamples() const
+int Framebuffer::getSamples(const gl::Data &data) const
{
- if (completeness() == GL_FRAMEBUFFER_COMPLETE)
+ 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
@@ -675,7 +558,7 @@ bool Framebuffer::hasValidDepthStencil() const
mDepthbuffer->id() == mStencilbuffer->id());
}
-ColorbufferInfo Framebuffer::getColorbuffersForRender() const
+ColorbufferInfo Framebuffer::getColorbuffersForRender(const rx::Workarounds &workarounds) const
{
ColorbufferInfo colorbuffersForRender;
@@ -689,18 +572,78 @@ ColorbufferInfo Framebuffer::getColorbuffersForRender() const
ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
colorbuffersForRender.push_back(colorbuffer);
}
-#if (ANGLE_MRT_PERF_WORKAROUND == ANGLE_WORKAROUND_DISABLED)
- else
+ else if (!workarounds.mrtPerfWorkaround)
{
colorbuffersForRender.push_back(NULL);
}
-#endif
}
return colorbuffersForRender;
}
-GLenum DefaultFramebuffer::completeness() const
+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.
diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
index cc12d22953..d0fe8935ea 100644
--- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
@@ -10,41 +10,44 @@
#ifndef LIBGLESV2_FRAMEBUFFER_H_
#define LIBGLESV2_FRAMEBUFFER_H_
-#include <vector>
+#include "libGLESv2/Error.h"
#include "common/angleutils.h"
#include "common/RefCountObject.h"
-#include "constants.h"
+#include "Constants.h"
+
+#include <vector>
namespace rx
{
-class Renderer;
+class RenderbufferImpl;
+struct Workarounds;
}
namespace gl
{
class FramebufferAttachment;
-class Colorbuffer;
-class Depthbuffer;
-class Stencilbuffer;
-class DepthStencilbuffer;
+class Texture;
+class Renderbuffer;
+struct ImageIndex;
struct Caps;
+struct Extensions;
+class TextureCapsMap;
+struct Data;
typedef std::vector<FramebufferAttachment *> ColorbufferInfo;
class Framebuffer
{
public:
- Framebuffer(rx::Renderer *renderer, GLuint id);
-
+ Framebuffer(GLuint id);
virtual ~Framebuffer();
GLuint id() const { return mId; }
- void setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer, GLint level, GLint layer);
- void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer);
- void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer);
- void setDepthStencilBuffer(GLenum type, GLuint depthStencilBuffer, GLint level, GLint layer);
+ 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);
@@ -66,24 +69,21 @@ class Framebuffer
bool isEnabledColorAttachment(unsigned int colorAttachment) const;
bool hasEnabledColorAttachment() const;
bool hasStencil() const;
- int getSamples() const;
+ int getSamples(const gl::Data &data) const;
bool usingExtendedDrawBuffers() const;
- virtual GLenum completeness() const;
+ virtual GLenum completeness(const gl::Data &data) const;
bool hasValidDepthStencil() const;
- void invalidate(const Caps &caps, GLsizei numAttachments, const GLenum *attachments);
- void invalidateSub(const Caps &caps, GLsizei numAttachments, const GLenum *attachments,
- GLint x, GLint y, GLsizei width, GLsizei height);
+ 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;
+ ColorbufferInfo getColorbuffersForRender(const rx::Workarounds &workarounds) const;
protected:
- rx::Renderer *mRenderer;
-
GLuint mId;
FramebufferAttachment *mColorbuffers[IMPLEMENTATION_MAX_DRAW_BUFFERS];
@@ -96,15 +96,15 @@ class Framebuffer
private:
DISALLOW_COPY_AND_ASSIGN(Framebuffer);
- FramebufferAttachment *createAttachment(GLenum binding, GLenum type, GLuint handle, GLint level, GLint layer) const;
+ void setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj);
};
class DefaultFramebuffer : public Framebuffer
{
public:
- DefaultFramebuffer(rx::Renderer *Renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
+ DefaultFramebuffer(rx::RenderbufferImpl *colorbuffer, rx::RenderbufferImpl *depthStencil);
- virtual GLenum completeness() const;
+ GLenum completeness(const gl::Data &data) const override;
virtual FramebufferAttachment *getAttachment(GLenum attachment) const;
private:
@@ -118,7 +118,7 @@ namespace rx
class RenderTarget;
// TODO: place this in FramebufferD3D.h
-RenderTarget *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment);
+gl::Error GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment, RenderTarget **outRT);
unsigned int GetAttachmentSerial(gl::FramebufferAttachment *attachment);
}
diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp
index 540ede1cd2..894884a6d8 100644
--- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.cpp
@@ -187,7 +187,7 @@ GLenum RenderbufferAttachment::getActualFormat() const
GLsizei RenderbufferAttachment::getSamples() const
{
- return mRenderbuffer->getStorage()->getSamples();
+ return mRenderbuffer->getSamples();
}
GLuint RenderbufferAttachment::id() const
diff --git a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h
index c18ef7364d..8d2dafa7ee 100644
--- a/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h
+++ b/src/3rdparty/angle/src/libGLESv2/FramebufferAttachment.h
@@ -16,13 +16,6 @@
#include "angle_gl.h"
-namespace rx
-{
-class Renderer;
-class RenderTarget;
-class TextureStorage;
-}
-
namespace gl
{
class Renderbuffer;
diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp b/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp
index 3522b997e8..b45cd9c169 100644
--- a/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ImageIndex.cpp
@@ -48,10 +48,101 @@ ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex)
return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex);
}
+ImageIndex ImageIndex::MakeInvalid()
+{
+ return ImageIndex(GL_NONE, -1, -1);
+}
+
ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn)
: type(typeIn),
mipIndex(mipIndexIn),
layerIndex(layerIndexIn)
{}
+ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip)
+{
+ return ImageIndexIterator(GL_TEXTURE_2D, rx::Range<GLint>(minMip, maxMip),
+ rx::Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), NULL);
+}
+
+ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip)
+{
+ return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, rx::Range<GLint>(minMip, maxMip), rx::Range<GLint>(0, 6), NULL);
+}
+
+ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, GLint maxMip,
+ GLint minLayer, GLint maxLayer)
+{
+ return ImageIndexIterator(GL_TEXTURE_3D, rx::Range<GLint>(minMip, maxMip), rx::Range<GLint>(minLayer, maxLayer), NULL);
+}
+
+ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip,
+ const GLsizei *layerCounts)
+{
+ return ImageIndexIterator(GL_TEXTURE_2D_ARRAY, rx::Range<GLint>(minMip, maxMip),
+ rx::Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), layerCounts);
+}
+
+ImageIndexIterator::ImageIndexIterator(GLenum type, const rx::Range<GLint> &mipRange,
+ const rx::Range<GLint> &layerRange, const GLsizei *layerCounts)
+ : mType(type),
+ mMipRange(mipRange),
+ mLayerRange(layerRange),
+ mLayerCounts(layerCounts),
+ mCurrentMip(mipRange.start),
+ mCurrentLayer(layerRange.start)
+{}
+
+GLint ImageIndexIterator::maxLayer() const
+{
+ return (mLayerCounts ? static_cast<GLint>(mLayerCounts[mCurrentMip]) : mLayerRange.end);
+}
+
+ImageIndex ImageIndexIterator::next()
+{
+ ASSERT(hasNext());
+
+ ImageIndex value = current();
+
+ // Iterate layers in the inner loop for now. We can add switchable
+ // layer or mip iteration if we need it.
+
+ if (mCurrentLayer != ImageIndex::ENTIRE_LEVEL)
+ {
+ if (mCurrentLayer < maxLayer()-1)
+ {
+ mCurrentLayer++;
+ }
+ else if (mCurrentMip < mMipRange.end-1)
+ {
+ mCurrentMip++;
+ mCurrentLayer = mLayerRange.start;
+ }
+ }
+ else if (mCurrentMip < mMipRange.end-1)
+ {
+ mCurrentMip++;
+ mCurrentLayer = mLayerRange.start;
+ }
+
+ return value;
+}
+
+ImageIndex ImageIndexIterator::current() const
+{
+ ImageIndex value(mType, mCurrentMip, mCurrentLayer);
+
+ if (mType == GL_TEXTURE_CUBE_MAP)
+ {
+ value.type = TextureCubeMap::layerIndexToTarget(mCurrentLayer);
+ }
+
+ return value;
+}
+
+bool ImageIndexIterator::hasNext() const
+{
+ return (mCurrentMip < mMipRange.end || mCurrentLayer < maxLayer());
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/ImageIndex.h b/src/3rdparty/angle/src/libGLESv2/ImageIndex.h
index 9f2df88061..8bb14fd555 100644
--- a/src/3rdparty/angle/src/libGLESv2/ImageIndex.h
+++ b/src/3rdparty/angle/src/libGLESv2/ImageIndex.h
@@ -10,6 +10,7 @@
#define LIBGLESV2_IMAGE_INDEX_H_
#include "angle_gl.h"
+#include "common/mathutil.h"
namespace gl
{
@@ -20,6 +21,7 @@ struct ImageIndex
GLint mipIndex;
GLint layerIndex;
+ ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
ImageIndex(const ImageIndex &other);
ImageIndex &operator=(const ImageIndex &other);
@@ -29,11 +31,36 @@ 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 MakeInvalid();
static const GLint ENTIRE_LEVEL = static_cast<GLint>(-1);
+};
+
+class ImageIndexIterator
+{
+ public:
+ static ImageIndexIterator Make2D(GLint minMip, GLint maxMip);
+ static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip);
+ static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer);
+ static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts);
+
+ ImageIndex next();
+ ImageIndex current() const;
+ bool hasNext() const;
private:
- ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
+
+ ImageIndexIterator(GLenum type, const rx::Range<GLint> &mipRange,
+ const rx::Range<GLint> &layerRange, const GLsizei *layerCounts);
+
+ GLint maxLayer() const;
+
+ GLenum mType;
+ rx::Range<GLint> mMipRange;
+ rx::Range<GLint> mLayerRange;
+ const GLsizei *mLayerCounts;
+ GLint mCurrentMip;
+ GLint mCurrentLayer;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Program.cpp b/src/3rdparty/angle/src/libGLESv2/Program.cpp
index 9bfda09a64..3faa8c56f6 100644
--- a/src/3rdparty/angle/src/libGLESv2/Program.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Program.cpp
@@ -244,7 +244,7 @@ void Program::bindAttributeLocation(GLuint index, const char *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
-bool Program::link(const Caps &caps)
+Error Program::link(const Data &data)
{
unlink(false);
@@ -252,10 +252,15 @@ bool Program::link(const Caps &caps)
resetUniformBlockBindings();
mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
- mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
- mTransformFeedbackVaryings, mTransformFeedbackBufferMode, caps);
+ LinkResult result = mProgramBinary->link(data, mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
+ mTransformFeedbackVaryings, mTransformFeedbackBufferMode);
+ if (result.error.isError())
+ {
+ return result.error;
+ }
- return mLinked;
+ mLinked = result.linkSuccess;
+ return gl::Error(GL_NO_ERROR);
}
int AttributeBindings::getAttributeBinding(const std::string &name) const
@@ -303,21 +308,22 @@ ProgramBinary* Program::getProgramBinary() const
return mProgramBinary.get();
}
-bool Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
+Error Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
{
unlink(false);
mInfoLog.reset();
mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
- mLinked = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
-
- if (!mLinked)
+ LinkResult result = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
+ if (result.error.isError())
{
mProgramBinary.set(NULL);
+ return result.error;
}
- return mLinked;
+ mLinked = result.linkSuccess;
+ return Error(GL_NO_ERROR);
}
void Program::release()
diff --git a/src/3rdparty/angle/src/libGLESv2/Program.h b/src/3rdparty/angle/src/libGLESv2/Program.h
index 6528dd1191..b92349eeef 100644
--- a/src/3rdparty/angle/src/libGLESv2/Program.h
+++ b/src/3rdparty/angle/src/libGLESv2/Program.h
@@ -29,6 +29,7 @@ class Renderer;
namespace gl
{
struct Caps;
+struct Data;
class ResourceManager;
class Shader;
@@ -77,9 +78,9 @@ class Program
void bindAttributeLocation(GLuint index, const char *name);
- bool link(const Caps &caps);
+ Error link(const Data &data);
bool isLinked();
- bool setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
+ Error setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length);
ProgramBinary *getProgramBinary() const;
int getInfoLogLength() const;
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
index 3f6d9e0ef9..6d64b38b56 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
@@ -23,13 +23,11 @@
#include "libGLESv2/Shader.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/renderer/ProgramImpl.h"
-#include "libGLESv2/renderer/Renderer.h"
-#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
#include "libGLESv2/renderer/d3d/ShaderD3D.h"
-#include "libGLESv2/renderer/d3d/VertexDataManager.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/Buffer.h"
#include "common/blocklayout.h"
+#include "common/features.h"
namespace gl
{
@@ -37,36 +35,6 @@ namespace gl
namespace
{
-GLenum GetTextureType(GLenum samplerType)
-{
- switch (samplerType)
- {
- case GL_SAMPLER_2D:
- case GL_INT_SAMPLER_2D:
- case GL_UNSIGNED_INT_SAMPLER_2D:
- case GL_SAMPLER_2D_SHADOW:
- return GL_TEXTURE_2D;
- case GL_SAMPLER_3D:
- case GL_INT_SAMPLER_3D:
- case GL_UNSIGNED_INT_SAMPLER_3D:
- return GL_TEXTURE_3D;
- case GL_SAMPLER_CUBE:
- case GL_SAMPLER_CUBE_SHADOW:
- return GL_TEXTURE_CUBE_MAP;
- case GL_INT_SAMPLER_CUBE:
- case GL_UNSIGNED_INT_SAMPLER_CUBE:
- return GL_TEXTURE_CUBE_MAP;
- case GL_SAMPLER_2D_ARRAY:
- case GL_INT_SAMPLER_2D_ARRAY:
- case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
- case GL_SAMPLER_2D_ARRAY_SHADOW:
- return GL_TEXTURE_2D_ARRAY;
- default: UNREACHABLE();
- }
-
- return GL_TEXTURE_2D;
-}
-
unsigned int ParseAndStripArrayIndex(std::string* name)
{
unsigned int subscript = GL_INVALID_INDEX;
@@ -83,52 +51,6 @@ unsigned int ParseAndStripArrayIndex(std::string* name)
return subscript;
}
-void GetDefaultInputLayoutFromShader(const std::vector<sh::Attribute> &shaderAttributes, VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
-{
- size_t layoutIndex = 0;
- for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++)
- {
- ASSERT(layoutIndex < MAX_VERTEX_ATTRIBS);
-
- const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex];
-
- if (shaderAttr.type != GL_NONE)
- {
- GLenum transposedType = TransposeMatrixType(shaderAttr.type);
-
- for (size_t rowIndex = 0; static_cast<int>(rowIndex) < VariableRowCount(transposedType); rowIndex++, layoutIndex++)
- {
- VertexFormat *defaultFormat = &inputLayout[layoutIndex];
-
- defaultFormat->mType = VariableComponentType(transposedType);
- defaultFormat->mNormalized = false;
- defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool
- defaultFormat->mComponents = VariableColumnCount(transposedType);
- }
- }
- }
-}
-
-std::vector<GLenum> GetDefaultOutputLayoutFromShader(const std::vector<rx::PixelShaderOutputVariable> &shaderOutputVars)
-{
- std::vector<GLenum> defaultPixelOutput(1);
-
- ASSERT(!shaderOutputVars.empty());
- defaultPixelOutput[0] = GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex;
-
- return defaultPixelOutput;
-}
-
-bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
-{
- return var.isRowMajorLayout;
-}
-
-bool IsRowMajorLayout(const sh::ShaderVariable &var)
-{
- return false;
-}
-
}
VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index)
@@ -136,47 +58,6 @@ VariableLocation::VariableLocation(const std::string &name, unsigned int element
{
}
-ProgramBinary::VertexExecutable::VertexExecutable(const VertexFormat inputLayout[],
- const GLenum signature[],
- rx::ShaderExecutable *shaderExecutable)
- : mShaderExecutable(shaderExecutable)
-{
- for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- mInputs[attributeIndex] = inputLayout[attributeIndex];
- mSignature[attributeIndex] = signature[attributeIndex];
- }
-}
-
-ProgramBinary::VertexExecutable::~VertexExecutable()
-{
- SafeDelete(mShaderExecutable);
-}
-
-bool ProgramBinary::VertexExecutable::matchesSignature(const GLenum signature[]) const
-{
- for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- if (mSignature[attributeIndex] != signature[attributeIndex])
- {
- return false;
- }
- }
-
- return true;
-}
-
-ProgramBinary::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable)
- : mOutputSignature(outputSignature),
- mShaderExecutable(shaderExecutable)
-{
-}
-
-ProgramBinary::PixelExecutable::~PixelExecutable()
-{
- SafeDelete(mShaderExecutable);
-}
-
LinkedVarying::LinkedVarying()
{
}
@@ -187,17 +68,17 @@ LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size,
{
}
+LinkResult::LinkResult(bool linkSuccess, const Error &error)
+ : linkSuccess(linkSuccess),
+ error(error)
+{
+}
+
unsigned int ProgramBinary::mCurrentSerial = 1;
ProgramBinary::ProgramBinary(rx::ProgramImpl *impl)
: RefCountObject(0),
mProgram(impl),
- mGeometryExecutable(NULL),
- mUsedVertexSamplerRange(0),
- mUsedPixelSamplerRange(0),
- mUsesPointSize(false),
- mShaderVersion(100),
- mDirtySamplerMapping(true),
mValidated(false),
mSerial(issueSerial())
{
@@ -220,103 +101,11 @@ unsigned int ProgramBinary::getSerial() const
return mSerial;
}
-int ProgramBinary::getShaderVersion() const
-{
- return mShaderVersion;
-}
-
unsigned int ProgramBinary::issueSerial()
{
return mCurrentSerial++;
}
-rx::ShaderExecutable *ProgramBinary::getPixelExecutableForFramebuffer(const Framebuffer *fbo)
-{
- std::vector<GLenum> outputs;
-
- const gl::ColorbufferInfo &colorbuffers = fbo->getColorbuffersForRender();
-
- for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
- {
- const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
-
- if (colorbuffer)
- {
- outputs.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding());
- }
- else
- {
- outputs.push_back(GL_NONE);
- }
- }
-
- return getPixelExecutableForOutputLayout(outputs);
-}
-
-rx::ShaderExecutable *ProgramBinary::getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputSignature)
-{
- for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
- {
- if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature))
- {
- return mPixelExecutables[executableIndex]->shaderExecutable();
- }
- }
-
- InfoLog tempInfoLog;
- rx::ShaderExecutable *pixelExecutable = mProgram->getPixelExecutableForOutputLayout(tempInfoLog, outputSignature,
- mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- if (!pixelExecutable)
- {
- 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));
- }
-
- return pixelExecutable;
-}
-
-rx::ShaderExecutable *ProgramBinary::getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS])
-{
- GLenum signature[MAX_VERTEX_ATTRIBS];
- mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
-
- for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
- {
- if (mVertexExecutables[executableIndex]->matchesSignature(signature))
- {
- return mVertexExecutables[executableIndex]->shaderExecutable();
- }
- }
-
- InfoLog tempInfoLog;
- rx::ShaderExecutable *vertexExecutable = mProgram->getVertexExecutableForInputLayout(tempInfoLog, inputLayout, mShaderAttributes,
- mTransformFeedbackLinkedVaryings, (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- 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]);
- }
- else
- {
- mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable));
- }
-
- return vertexExecutable;
-}
-
-rx::ShaderExecutable *ProgramBinary::getGeometryExecutable() const
-{
- return mGeometryExecutable;
-}
-
GLuint ProgramBinary::getAttributeLocation(const char *name)
{
if (name)
@@ -343,157 +132,42 @@ int ProgramBinary::getSemanticIndex(int attributeIndex)
// Returns one more than the highest sampler index used.
GLint ProgramBinary::getUsedSamplerRange(SamplerType type)
{
- switch (type)
- {
- case SAMPLER_PIXEL:
- return mUsedPixelSamplerRange;
- case SAMPLER_VERTEX:
- return mUsedVertexSamplerRange;
- default:
- UNREACHABLE();
- return 0;
- }
+ return mProgram->getUsedSamplerRange(type);
}
bool ProgramBinary::usesPointSize() const
{
- return mUsesPointSize;
-}
-
-bool ProgramBinary::usesPointSpriteEmulation() const
-{
- return mUsesPointSize && mProgram->getRenderer()->getMajorShaderModel() >= 4;
-}
-
-bool ProgramBinary::usesGeometryShader() const
-{
- return usesPointSpriteEmulation();
+ return mProgram->usesPointSize();
}
GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps)
{
- GLint logicalTextureUnit = -1;
-
- switch (type)
- {
- case SAMPLER_PIXEL:
- ASSERT(samplerIndex < caps.maxTextureImageUnits);
- if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active)
- {
- logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit;
- }
- break;
- case SAMPLER_VERTEX:
- ASSERT(samplerIndex < caps.maxVertexTextureImageUnits);
- if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active)
- {
- logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit;
- }
- break;
- default: UNREACHABLE();
- }
-
- if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits))
- {
- return logicalTextureUnit;
- }
-
- return -1;
+ return mProgram->getSamplerMapping(type, samplerIndex, caps);
}
-// Returns the texture type for a given Direct3D 9 sampler type and
-// index (0-15 for the pixel shader and 0-3 for the vertex shader).
GLenum ProgramBinary::getSamplerTextureType(SamplerType type, unsigned int samplerIndex)
{
- switch (type)
- {
- case SAMPLER_PIXEL:
- ASSERT(samplerIndex < mSamplersPS.size());
- ASSERT(mSamplersPS[samplerIndex].active);
- return mSamplersPS[samplerIndex].textureType;
- case SAMPLER_VERTEX:
- ASSERT(samplerIndex < mSamplersVS.size());
- ASSERT(mSamplersVS[samplerIndex].active);
- return mSamplersVS[samplerIndex].textureType;
- default: UNREACHABLE();
- }
-
- return GL_TEXTURE_2D;
+ return mProgram->getSamplerTextureType(type, samplerIndex);
}
GLint ProgramBinary::getUniformLocation(std::string name)
{
- unsigned int subscript = ParseAndStripArrayIndex(&name);
-
- unsigned int numUniforms = mUniformIndex.size();
- for (unsigned int location = 0; location < numUniforms; location++)
- {
- if (mUniformIndex[location].name == name)
- {
- const int index = mUniformIndex[location].index;
- const bool isArray = mUniforms[index]->isArray();
-
- if ((isArray && mUniformIndex[location].element == subscript) ||
- (subscript == GL_INVALID_INDEX))
- {
- return location;
- }
- }
- }
-
- return -1;
+ return mProgram->getUniformLocation(name);
}
GLuint ProgramBinary::getUniformIndex(std::string name)
{
- unsigned int subscript = ParseAndStripArrayIndex(&name);
-
- // The app is not allowed to specify array indices other than 0 for arrays of basic types
- if (subscript != 0 && subscript != GL_INVALID_INDEX)
- {
- return GL_INVALID_INDEX;
- }
-
- unsigned int numUniforms = mUniforms.size();
- for (unsigned int index = 0; index < numUniforms; index++)
- {
- if (mUniforms[index]->name == name)
- {
- if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
- {
- return index;
- }
- }
- }
-
- return GL_INVALID_INDEX;
+ return mProgram->getUniformIndex(name);
}
GLuint ProgramBinary::getUniformBlockIndex(std::string name)
{
- unsigned int subscript = ParseAndStripArrayIndex(&name);
-
- unsigned int numUniformBlocks = mUniformBlocks.size();
- for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
- {
- const UniformBlock &uniformBlock = *mUniformBlocks[blockIndex];
- if (uniformBlock.name == name)
- {
- const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
- if (subscript == uniformBlock.elementIndex || arrayElementZero)
- {
- return blockIndex;
- }
- }
- }
-
- return GL_INVALID_INDEX;
+ return mProgram->getUniformBlockIndex(name);
}
UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex)
{
- ASSERT(blockIndex < mUniformBlocks.size());
- return mUniformBlocks[blockIndex];
+ return mProgram->getUniformBlockByIndex(blockIndex);
}
GLint ProgramBinary::getFragDataLocation(const char *name) const
@@ -517,524 +191,129 @@ GLint ProgramBinary::getFragDataLocation(const char *name) const
size_t ProgramBinary::getTransformFeedbackVaryingCount() const
{
- return mTransformFeedbackLinkedVaryings.size();
+ return mProgram->getTransformFeedbackLinkedVaryings().size();
}
const LinkedVarying &ProgramBinary::getTransformFeedbackVarying(size_t idx) const
{
- return mTransformFeedbackLinkedVaryings[idx];
+ return mProgram->getTransformFeedbackLinkedVaryings()[idx];
}
GLenum ProgramBinary::getTransformFeedbackBufferMode() const
{
- return mTransformFeedbackBufferMode;
-}
-
-template <typename T>
-static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag)
-{
- ASSERT(dest != NULL);
- ASSERT(dirtyFlag != NULL);
-
- *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0);
- *dest = source;
-}
-
-template <typename T>
-void ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType)
-{
- const int components = VariableComponentCount(targetUniformType);
- const GLenum targetBoolType = VariableBoolVectorType(targetUniformType);
-
- LinkedUniform *targetUniform = getUniformByLocation(location);
-
- int elementCount = targetUniform->elementCount();
-
- count = std::min(elementCount - (int)mUniformIndex[location].element, count);
-
- if (targetUniform->type == targetUniformType)
- {
- T *target = reinterpret_cast<T*>(targetUniform->data) + mUniformIndex[location].element * 4;
-
- for (int i = 0; i < count; i++)
- {
- T *dest = target + (i * 4);
- const T *source = v + (i * components);
-
- for (int c = 0; c < components; c++)
- {
- SetIfDirty(dest + c, source[c], &targetUniform->dirty);
- }
- for (int c = components; c < 4; c++)
- {
- SetIfDirty(dest + c, T(0), &targetUniform->dirty);
- }
- }
- }
- else if (targetUniform->type == targetBoolType)
- {
- GLint *boolParams = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
-
- for (int i = 0; i < count; i++)
- {
- GLint *dest = boolParams + (i * 4);
- const T *source = v + (i * components);
-
- for (int c = 0; c < components; c++)
- {
- SetIfDirty(dest + c, (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty);
- }
- for (int c = components; c < 4; c++)
- {
- SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty);
- }
- }
- }
- else if (IsSampler(targetUniform->type))
- {
- ASSERT(targetUniformType == GL_INT);
-
- GLint *target = reinterpret_cast<GLint*>(targetUniform->data) + mUniformIndex[location].element * 4;
-
- bool wasDirty = targetUniform->dirty;
-
- for (int i = 0; i < count; i++)
- {
- GLint *dest = target + (i * 4);
- const GLint *source = reinterpret_cast<const GLint*>(v) + (i * components);
-
- SetIfDirty(dest + 0, source[0], &targetUniform->dirty);
- SetIfDirty(dest + 1, 0, &targetUniform->dirty);
- SetIfDirty(dest + 2, 0, &targetUniform->dirty);
- SetIfDirty(dest + 3, 0, &targetUniform->dirty);
- }
-
- if (!wasDirty && targetUniform->dirty)
- {
- mDirtySamplerMapping = true;
- }
- }
- else UNREACHABLE();
-}
-
-void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
-{
- setUniform(location, count, v, GL_FLOAT);
+ return mProgram->getTransformFeedbackBufferMode();
}
-void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
-{
- setUniform(location, count, v, GL_FLOAT_VEC2);
-}
-
-void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
-{
- setUniform(location, count, v, GL_FLOAT_VEC3);
-}
-
-void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
-{
- setUniform(location, count, v, GL_FLOAT_VEC4);
-}
-
-template<typename T>
-bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
-{
- bool dirty = false;
- int copyWidth = std::min(targetHeight, srcWidth);
- int copyHeight = std::min(targetWidth, srcHeight);
-
- for (int x = 0; x < copyWidth; x++)
- {
- for (int y = 0; y < copyHeight; y++)
- {
- SetIfDirty(target + (x * targetWidth + y), static_cast<T>(value[y * srcWidth + x]), &dirty);
- }
- }
- // clear unfilled right side
- for (int y = 0; y < copyWidth; y++)
- {
- for (int x = copyHeight; x < targetWidth; x++)
- {
- SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
- }
- }
- // clear unfilled bottom.
- for (int y = copyWidth; y < targetHeight; y++)
- {
- for (int x = 0; x < targetWidth; x++)
- {
- SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
- }
- }
-
- return dirty;
-}
-
-template<typename T>
-bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
-{
- bool dirty = false;
- int copyWidth = std::min(targetWidth, srcWidth);
- int copyHeight = std::min(targetHeight, srcHeight);
-
- for (int y = 0; y < copyHeight; y++)
- {
- for (int x = 0; x < copyWidth; x++)
- {
- SetIfDirty(target + (y * targetWidth + x), static_cast<T>(value[y * srcWidth + x]), &dirty);
- }
- }
- // clear unfilled right side
- for (int y = 0; y < copyHeight; y++)
- {
- for (int x = copyWidth; x < targetWidth; x++)
- {
- SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
- }
- }
- // clear unfilled bottom.
- for (int y = copyHeight; y < targetHeight; y++)
- {
- for (int x = 0; x < targetWidth; x++)
- {
- SetIfDirty(target + (y * targetWidth + x), static_cast<T>(0), &dirty);
- }
- }
-
- return dirty;
+void ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) {
+ mProgram->setUniform1fv(location, count, v);
}
-template <int cols, int rows>
-void ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType)
-{
- LinkedUniform *targetUniform = getUniformByLocation(location);
-
- int elementCount = targetUniform->elementCount();
-
- count = std::min(elementCount - (int)mUniformIndex[location].element, count);
- const unsigned int targetMatrixStride = (4 * rows);
- GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride);
-
- for (int i = 0; i < count; i++)
- {
- // Internally store matrices as transposed versions to accomodate HLSL matrix indexing
- if (transpose == GL_FALSE)
- {
- targetUniform->dirty = transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols) || targetUniform->dirty;
- }
- else
- {
- targetUniform->dirty = expandMatrix<GLfloat>(target, value, 4, rows, cols, rows) || targetUniform->dirty;
- }
- target += targetMatrixStride;
- value += cols * rows;
- }
+void ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) {
+ mProgram->setUniform2fv(location, count, v);
}
-void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2);
+void ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) {
+ mProgram->setUniform3fv(location, count, v);
}
-void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3);
+void ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) {
+ mProgram->setUniform4fv(location, count, v);
}
-void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4);
+void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) {
+ mProgram->setUniform1iv(location, count, v);
}
-void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3);
+void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) {
+ mProgram->setUniform2iv(location, count, v);
}
-void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2);
+void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) {
+ mProgram->setUniform3iv(location, count, v);
}
-void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4);
+void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) {
+ mProgram->setUniform4iv(location, count, v);
}
-void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2);
+void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) {
+ mProgram->setUniform1uiv(location, count, v);
}
-void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4);
+void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) {
+ mProgram->setUniform2uiv(location, count, v);
}
-void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-{
- setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3);
+void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) {
+ mProgram->setUniform3uiv(location, count, v);
}
-void ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
-{
- setUniform(location, count, v, GL_INT);
+void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) {
+ mProgram->setUniform4uiv(location, count, v);
}
-void ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
-{
- setUniform(location, count, v, GL_INT_VEC2);
+void ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix2fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v)
-{
- setUniform(location, count, v, GL_INT_VEC3);
+void ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix3fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v)
-{
- setUniform(location, count, v, GL_INT_VEC4);
+void ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix4fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
-{
- setUniform(location, count, v, GL_UNSIGNED_INT);
+void ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix2x3fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
-{
- setUniform(location, count, v, GL_UNSIGNED_INT_VEC2);
+void ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix2x4fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
-{
- setUniform(location, count, v, GL_UNSIGNED_INT_VEC3);
+void ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix3x2fv(location, count, transpose, v);
}
-void ProgramBinary::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
-{
- setUniform(location, count, v, GL_UNSIGNED_INT_VEC4);
+void ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix3x4fv(location, count, transpose, v);
}
-template <typename T>
-void ProgramBinary::getUniformv(GLint location, T *params, GLenum uniformType)
-{
- LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index];
-
- if (IsMatrixType(targetUniform->type))
- {
- const int rows = VariableRowCount(targetUniform->type);
- const int cols = VariableColumnCount(targetUniform->type);
- transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows);
- }
- else if (uniformType == VariableComponentType(targetUniform->type))
- {
- unsigned int size = VariableComponentCount(targetUniform->type);
- memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T),
- size * sizeof(T));
- }
- else
- {
- unsigned int size = VariableComponentCount(targetUniform->type);
- switch (VariableComponentType(targetUniform->type))
- {
- case GL_BOOL:
- {
- GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (unsigned int i = 0; i < size; i++)
- {
- params[i] = (boolParams[i] == GL_FALSE) ? static_cast<T>(0) : static_cast<T>(1);
- }
- }
- break;
-
- case GL_FLOAT:
- {
- GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (unsigned int i = 0; i < size; i++)
- {
- params[i] = static_cast<T>(floatParams[i]);
- }
- }
- break;
-
- case GL_INT:
- {
- GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (unsigned int i = 0; i < size; i++)
- {
- params[i] = static_cast<T>(intParams[i]);
- }
- }
- break;
-
- case GL_UNSIGNED_INT:
- {
- GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (unsigned int i = 0; i < size; i++)
- {
- params[i] = static_cast<T>(uintParams[i]);
- }
- }
- break;
-
- default: UNREACHABLE();
- }
- }
+void ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix4x2fv(location, count, transpose, v);
}
-void ProgramBinary::getUniformfv(GLint location, GLfloat *params)
-{
- getUniformv(location, params, GL_FLOAT);
+void ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) {
+ mProgram->setUniformMatrix4x3fv(location, count, transpose, v);
}
-void ProgramBinary::getUniformiv(GLint location, GLint *params)
-{
- getUniformv(location, params, GL_INT);
+void ProgramBinary::getUniformfv(GLint location, GLfloat *v) {
+ mProgram->getUniformfv(location, v);
}
-void ProgramBinary::getUniformuiv(GLint location, GLuint *params)
-{
- getUniformv(location, params, GL_UNSIGNED_INT);
+void ProgramBinary::getUniformiv(GLint location, GLint *v) {
+ mProgram->getUniformiv(location, v);
}
-void ProgramBinary::dirtyAllUniforms()
-{
- unsigned int numUniforms = mUniforms.size();
- for (unsigned int index = 0; index < numUniforms; index++)
- {
- mUniforms[index]->dirty = true;
- }
+void ProgramBinary::getUniformuiv(GLint location, GLuint *v) {
+ mProgram->getUniformuiv(location, v);
}
void ProgramBinary::updateSamplerMapping()
{
- if (!mDirtySamplerMapping)
- {
- return;
- }
-
- mDirtySamplerMapping = false;
-
- // Retrieve sampler uniform values
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
- {
- LinkedUniform *targetUniform = mUniforms[uniformIndex];
-
- if (targetUniform->dirty)
- {
- if (IsSampler(targetUniform->type))
- {
- int count = targetUniform->elementCount();
- GLint (*v)[4] = reinterpret_cast<GLint(*)[4]>(targetUniform->data);
-
- if (targetUniform->isReferencedByFragmentShader())
- {
- unsigned int firstIndex = targetUniform->psRegisterIndex;
-
- for (int i = 0; i < count; i++)
- {
- unsigned int samplerIndex = firstIndex + i;
-
- if (samplerIndex < mSamplersPS.size())
- {
- ASSERT(mSamplersPS[samplerIndex].active);
- mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
- }
- }
- }
-
- if (targetUniform->isReferencedByVertexShader())
- {
- unsigned int firstIndex = targetUniform->vsRegisterIndex;
-
- for (int i = 0; i < count; i++)
- {
- unsigned int samplerIndex = firstIndex + i;
-
- if (samplerIndex < mSamplersVS.size())
- {
- ASSERT(mSamplersVS[samplerIndex].active);
- mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
- }
- }
- }
- }
- }
- }
+ return mProgram->updateSamplerMapping();
}
// Applies all the uniforms set for this program object to the renderer
Error ProgramBinary::applyUniforms()
{
- updateSamplerMapping();
-
- Error error = mProgram->getRenderer()->applyUniforms(*this);
- if (error.isError())
- {
- return error;
- }
-
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
- {
- mUniforms[uniformIndex]->dirty = false;
- }
-
- return gl::Error(GL_NO_ERROR);
+ return mProgram->applyUniforms();
}
Error ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const Caps &caps)
{
- const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
- const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
-
- const unsigned int reservedBuffersInVS = mProgram->getRenderer()->getReservedVertexUniformBuffers();
- const unsigned int reservedBuffersInFS = mProgram->getRenderer()->getReservedFragmentUniformBuffers();
-
- ASSERT(boundBuffers.size() == mUniformBlocks.size());
-
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++)
- {
- UniformBlock *uniformBlock = getUniformBlockByIndex(uniformBlockIndex);
- gl::Buffer *uniformBuffer = boundBuffers[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.");
- }
-
- // Unnecessary to apply an unreferenced standard or shared UBO
- if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader())
- {
- continue;
- }
-
- if (uniformBlock->isReferencedByVertexShader())
- {
- unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
- ASSERT(vertexUniformBuffers[registerIndex] == NULL);
- ASSERT(registerIndex < caps.maxVertexUniformBlocks);
- vertexUniformBuffers[registerIndex] = uniformBuffer;
- }
-
- if (uniformBlock->isReferencedByFragmentShader())
- {
- unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
- ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
- ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
- fragmentUniformBuffers[registerIndex] = uniformBuffer;
- }
- }
-
- return mProgram->getRenderer()->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
+ return mProgram->applyUniformBuffers(boundBuffers, caps);
}
bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
@@ -1082,10 +361,10 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shade
return true;
}
-bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
+LinkResult ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length)
{
-#ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
- return false;
+#if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_DISABLED
+ return LinkResult(false, Error(GL_NO_ERROR));
#else
ASSERT(binaryFormat == mProgram->getBinaryFormat());
@@ -1097,7 +376,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (format != mProgram->getBinaryFormat())
{
infoLog.append("Invalid program binary format.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
int majorVersion = stream.readInt<int>();
@@ -1105,7 +384,7 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION)
{
infoLog.append("Invalid program binary version.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
unsigned char commitString[ANGLE_COMMIT_HASH_SIZE];
@@ -1113,250 +392,38 @@ bool ProgramBinary::load(InfoLog &infoLog, GLenum binaryFormat, const void *bina
if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0)
{
infoLog.append("Invalid program binary version.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
int compileFlags = stream.readInt<int>();
if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
{
infoLog.append("Mismatched compilation flags.");
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
{
stream.readInt(&mLinkedAttribute[i].type);
stream.readString(&mLinkedAttribute[i].name);
- stream.readInt(&mShaderAttributes[i].type);
- stream.readString(&mShaderAttributes[i].name);
+ stream.readInt(&mProgram->getShaderAttributes()[i].type);
+ stream.readString(&mProgram->getShaderAttributes()[i].name);
stream.readInt(&mSemanticIndex[i]);
}
initAttributesByLayout();
- const unsigned int psSamplerCount = stream.readInt<unsigned int>();
- for (unsigned int i = 0; i < psSamplerCount; ++i)
- {
- Sampler sampler;
- stream.readBool(&sampler.active);
- stream.readInt(&sampler.logicalTextureUnit);
- stream.readInt(&sampler.textureType);
- mSamplersPS.push_back(sampler);
- }
- const unsigned int vsSamplerCount = stream.readInt<unsigned int>();
- for (unsigned int i = 0; i < vsSamplerCount; ++i)
- {
- Sampler sampler;
- stream.readBool(&sampler.active);
- stream.readInt(&sampler.logicalTextureUnit);
- stream.readInt(&sampler.textureType);
- mSamplersVS.push_back(sampler);
- }
-
- stream.readInt(&mUsedVertexSamplerRange);
- stream.readInt(&mUsedPixelSamplerRange);
- stream.readBool(&mUsesPointSize);
- stream.readInt(&mShaderVersion);
-
- const unsigned int uniformCount = stream.readInt<unsigned int>();
- if (stream.error())
- {
- infoLog.append("Invalid program binary.");
- return false;
- }
-
- mUniforms.resize(uniformCount);
- for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
- {
- GLenum type = stream.readInt<GLenum>();
- GLenum precision = stream.readInt<GLenum>();
- std::string name = stream.readString();
- unsigned int arraySize = stream.readInt<unsigned int>();
- int blockIndex = stream.readInt<int>();
-
- int offset = stream.readInt<int>();
- int arrayStride = stream.readInt<int>();
- int matrixStride = stream.readInt<int>();
- bool isRowMajorMatrix = stream.readBool();
-
- const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix);
-
- LinkedUniform *uniform = new LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo);
-
- stream.readInt(&uniform->psRegisterIndex);
- stream.readInt(&uniform->vsRegisterIndex);
- stream.readInt(&uniform->registerCount);
- stream.readInt(&uniform->registerElement);
-
- mUniforms[uniformIndex] = uniform;
- }
-
- unsigned int uniformBlockCount = stream.readInt<unsigned int>();
- if (stream.error())
- {
- infoLog.append("Invalid program binary.");
- return false;
- }
-
- mUniformBlocks.resize(uniformBlockCount);
- for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex)
- {
- std::string name = stream.readString();
- unsigned int elementIndex = stream.readInt<unsigned int>();
- unsigned int dataSize = stream.readInt<unsigned int>();
-
- UniformBlock *uniformBlock = new UniformBlock(name, elementIndex, dataSize);
-
- stream.readInt(&uniformBlock->psRegisterIndex);
- stream.readInt(&uniformBlock->vsRegisterIndex);
-
- unsigned int numMembers = stream.readInt<unsigned int>();
- uniformBlock->memberUniformIndexes.resize(numMembers);
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
- {
- stream.readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]);
- }
-
- mUniformBlocks[uniformBlockIndex] = uniformBlock;
- }
-
- const unsigned int uniformIndexCount = stream.readInt<unsigned int>();
- if (stream.error())
- {
- infoLog.append("Invalid program binary.");
- return false;
- }
-
- mUniformIndex.resize(uniformIndexCount);
- for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++)
- {
- stream.readString(&mUniformIndex[uniformIndexIndex].name);
- stream.readInt(&mUniformIndex[uniformIndexIndex].element);
- stream.readInt(&mUniformIndex[uniformIndexIndex].index);
- }
-
- stream.readInt(&mTransformFeedbackBufferMode);
- const unsigned int transformFeedbackVaryingCount = stream.readInt<unsigned int>();
- mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount);
- for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++)
- {
- LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex];
-
- stream.readString(&varying.name);
- stream.readInt(&varying.type);
- stream.readInt(&varying.size);
- stream.readString(&varying.semanticName);
- stream.readInt(&varying.semanticIndex);
- stream.readInt(&varying.semanticIndexCount);
- }
-
- const unsigned int vertexShaderCount = stream.readInt<unsigned int>();
- for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
- {
- VertexFormat inputLayout[MAX_VERTEX_ATTRIBS];
-
- for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++)
- {
- VertexFormat *vertexInput = &inputLayout[inputIndex];
- stream.readInt(&vertexInput->mType);
- stream.readInt(&vertexInput->mNormalized);
- stream.readInt(&vertexInput->mComponents);
- stream.readBool(&vertexInput->mPureInteger);
- }
-
- unsigned int vertexShaderSize = stream.readInt<unsigned int>();
- const unsigned char *vertexShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
- rx::ShaderExecutable *shaderExecutable = mProgram->getRenderer()->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
- vertexShaderSize, rx::SHADER_VERTEX,
- mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
- if (!shaderExecutable)
- {
- infoLog.append("Could not create vertex shader.");
- return false;
- }
-
- // generated converted input layout
- GLenum signature[MAX_VERTEX_ATTRIBS];
- mProgram->getDynamicHLSL()->getInputLayoutSignature(inputLayout, signature);
-
- // add new binary
- mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable));
-
- stream.skip(vertexShaderSize);
- }
-
- const size_t pixelShaderCount = stream.readInt<unsigned int>();
- for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
+ LinkResult result = mProgram->load(infoLog, &stream);
+ if (result.error.isError() || !result.linkSuccess)
{
- const size_t outputCount = stream.readInt<unsigned int>();
- std::vector<GLenum> outputs(outputCount);
- for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
- {
- stream.readInt(&outputs[outputIndex]);
- }
-
- const size_t pixelShaderSize = stream.readInt<unsigned int>();
- const unsigned char *pixelShaderFunction = reinterpret_cast<const unsigned char*>(binary) + stream.offset();
- rx::Renderer *renderer = mProgram->getRenderer();
- rx::ShaderExecutable *shaderExecutable = renderer->loadExecutable(pixelShaderFunction, pixelShaderSize,
- rx::SHADER_PIXEL, mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- if (!shaderExecutable)
- {
- infoLog.append("Could not create pixel shader.");
- return false;
- }
-
- // add new binary
- mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable));
-
- stream.skip(pixelShaderSize);
+ return result;
}
- unsigned int geometryShaderSize = stream.readInt<unsigned int>();
-
- if (geometryShaderSize > 0)
- {
- const char *geometryShaderFunction = (const char*) binary + stream.offset();
- rx::Renderer *renderer = mProgram->getRenderer();
- mGeometryExecutable = renderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
- geometryShaderSize, rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS));
-
- if (!mGeometryExecutable)
- {
- infoLog.append("Could not create geometry shader.");
- return false;
- }
- stream.skip(geometryShaderSize);
- }
-
- if (!mProgram->load(infoLog, &stream))
- {
- return false;
- }
-
- const char *ptr = (const char*) binary + stream.offset();
-
- const GUID *binaryIdentifier = (const GUID *) ptr;
- ptr += sizeof(GUID);
-
- GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
- if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0)
- {
- infoLog.append("Invalid program binary.");
- return false;
- }
-
- mProgram->initializeUniformStorage(mUniforms);
-
- return true;
-#endif // #ifdef ANGLE_DISABLE_PROGRAM_BINARY_LOAD
+ return LinkResult(true, Error(GL_NO_ERROR));
+#endif // #if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_ENABLED
}
-bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
+Error ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length)
{
if (binaryFormat)
{
@@ -1375,168 +442,27 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
{
stream.writeInt(mLinkedAttribute[i].type);
stream.writeString(mLinkedAttribute[i].name);
- stream.writeInt(mShaderAttributes[i].type);
- stream.writeString(mShaderAttributes[i].name);
+ stream.writeInt(mProgram->getShaderAttributes()[i].type);
+ stream.writeString(mProgram->getShaderAttributes()[i].name);
stream.writeInt(mSemanticIndex[i]);
}
- stream.writeInt(mSamplersPS.size());
- for (unsigned int i = 0; i < mSamplersPS.size(); ++i)
- {
- stream.writeInt(mSamplersPS[i].active);
- stream.writeInt(mSamplersPS[i].logicalTextureUnit);
- stream.writeInt(mSamplersPS[i].textureType);
- }
-
- stream.writeInt(mSamplersVS.size());
- for (unsigned int i = 0; i < mSamplersVS.size(); ++i)
- {
- stream.writeInt(mSamplersVS[i].active);
- stream.writeInt(mSamplersVS[i].logicalTextureUnit);
- stream.writeInt(mSamplersVS[i].textureType);
- }
-
- stream.writeInt(mUsedVertexSamplerRange);
- stream.writeInt(mUsedPixelSamplerRange);
- stream.writeInt(mUsesPointSize);
- stream.writeInt(mShaderVersion);
-
- stream.writeInt(mUniforms.size());
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
- {
- const LinkedUniform &uniform = *mUniforms[uniformIndex];
-
- stream.writeInt(uniform.type);
- stream.writeInt(uniform.precision);
- stream.writeString(uniform.name);
- stream.writeInt(uniform.arraySize);
- stream.writeInt(uniform.blockIndex);
-
- stream.writeInt(uniform.blockInfo.offset);
- stream.writeInt(uniform.blockInfo.arrayStride);
- stream.writeInt(uniform.blockInfo.matrixStride);
- stream.writeInt(uniform.blockInfo.isRowMajorMatrix);
-
- stream.writeInt(uniform.psRegisterIndex);
- stream.writeInt(uniform.vsRegisterIndex);
- stream.writeInt(uniform.registerCount);
- stream.writeInt(uniform.registerElement);
- }
-
- stream.writeInt(mUniformBlocks.size());
- for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex)
- {
- const UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex];
-
- stream.writeString(uniformBlock.name);
- stream.writeInt(uniformBlock.elementIndex);
- stream.writeInt(uniformBlock.dataSize);
-
- stream.writeInt(uniformBlock.memberUniformIndexes.size());
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
- {
- stream.writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]);
- }
-
- stream.writeInt(uniformBlock.psRegisterIndex);
- stream.writeInt(uniformBlock.vsRegisterIndex);
- }
-
- stream.writeInt(mUniformIndex.size());
- for (size_t i = 0; i < mUniformIndex.size(); ++i)
- {
- stream.writeString(mUniformIndex[i].name);
- stream.writeInt(mUniformIndex[i].element);
- stream.writeInt(mUniformIndex[i].index);
- }
-
- stream.writeInt(mTransformFeedbackBufferMode);
- stream.writeInt(mTransformFeedbackLinkedVaryings.size());
- for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++)
- {
- const LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i];
-
- stream.writeString(varying.name);
- stream.writeInt(varying.type);
- stream.writeInt(varying.size);
- stream.writeString(varying.semanticName);
- stream.writeInt(varying.semanticIndex);
- stream.writeInt(varying.semanticIndexCount);
- }
-
- stream.writeInt(mVertexExecutables.size());
- for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++)
- {
- VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex];
-
- for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++)
- {
- const VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex];
- stream.writeInt(vertexInput.mType);
- stream.writeInt(vertexInput.mNormalized);
- stream.writeInt(vertexInput.mComponents);
- stream.writeInt(vertexInput.mPureInteger);
- }
-
- size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
- stream.writeInt(vertexShaderSize);
-
- const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
- stream.writeBytes(vertexBlob, vertexShaderSize);
- }
-
- stream.writeInt(mPixelExecutables.size());
- for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++)
- {
- PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex];
-
- const std::vector<GLenum> outputs = pixelExecutable->outputSignature();
- stream.writeInt(outputs.size());
- for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
- {
- stream.writeInt(outputs[outputIndex]);
- }
-
- size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
- stream.writeInt(pixelShaderSize);
-
- const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
- stream.writeBytes(pixelBlob, pixelShaderSize);
- }
-
- size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
- stream.writeInt(geometryShaderSize);
-
- if (mGeometryExecutable != NULL && geometryShaderSize > 0)
- {
- const uint8_t *geometryBlob = mGeometryExecutable->getFunction();
- stream.writeBytes(geometryBlob, geometryShaderSize);
- }
-
- if (!mProgram->save(&stream))
- {
- if (length)
- {
- *length = 0;
- }
-
- return false;
- }
-
- GUID identifier = mProgram->getRenderer()->getAdapterIdentifier();
+ mProgram->save(&stream);
GLsizei streamLength = stream.length();
const void *streamData = stream.data();
- GLsizei totalLength = streamLength + sizeof(GUID);
- if (totalLength > bufSize)
+ if (streamLength > bufSize)
{
if (length)
{
*length = 0;
}
- return false;
+ // TODO: This should be moved to the validation layer but computing the size of the binary before saving
+ // it causes the save to happen twice. It may be possible to write the binary to a separate buffer, validate
+ // sizes and then copy it.
+ return Error(GL_INVALID_OPERATION);
}
if (binary)
@@ -1546,129 +472,197 @@ bool ProgramBinary::save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GL
memcpy(ptr, streamData, streamLength);
ptr += streamLength;
- memcpy(ptr, &identifier, sizeof(GUID));
- ptr += sizeof(GUID);
-
- ASSERT(ptr - totalLength == binary);
+ ASSERT(ptr - streamLength == binary);
}
if (length)
{
- *length = totalLength;
+ *length = streamLength;
}
- return true;
+ return Error(GL_NO_ERROR);
}
GLint ProgramBinary::getLength()
{
GLint length;
- if (save(NULL, NULL, INT_MAX, &length))
- {
- return length;
- }
- else
+ Error error = save(NULL, NULL, INT_MAX, &length);
+ if (error.isError())
{
return 0;
}
+
+ return length;
}
-bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps)
+LinkResult ProgramBinary::link(const Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings,
+ Shader *fragmentShader, Shader *vertexShader,
+ const std::vector<std::string> &transformFeedbackVaryings,
+ GLenum transformFeedbackBufferMode)
{
if (!fragmentShader || !fragmentShader->isCompiled())
{
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER);
if (!vertexShader || !vertexShader->isCompiled())
{
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
ASSERT(vertexShader->getType() == GL_VERTEX_SHADER);
reset();
- mSamplersPS.resize(caps.maxTextureImageUnits);
- mSamplersVS.resize(caps.maxVertexTextureImageUnits);
+ 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)
+ {
+ return result;
+ }
- mTransformFeedbackBufferMode = transformFeedbackBufferMode;
+ if (!linkAttributes(infoLog, attributeBindings, vertexShader))
+ {
+ return LinkResult(false, Error(GL_NO_ERROR));
+ }
- rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
- rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+ if (!mProgram->linkUniforms(infoLog, *vertexShader, *fragmentShader, *data.caps))
+ {
+ return LinkResult(false, Error(GL_NO_ERROR));
+ }
- mShaderVersion = vertexShaderD3D->getShaderVersion();
+ if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, *data.caps))
+ {
+ return LinkResult(false, Error(GL_NO_ERROR));
+ }
- int registers;
- std::vector<LinkedVarying> linkedVaryings;
- if (!mProgram->link(infoLog, fragmentShader, vertexShader, transformFeedbackVaryings, &registers, &linkedVaryings, &mOutputVariables))
+ if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
+ transformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps))
{
- return false;
+ return LinkResult(false, Error(GL_NO_ERROR));
}
- mUsesPointSize = vertexShaderD3D->usesPointSize();
+ // 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)
+ {
+ infoLog.append("Failed to create D3D shaders.");
+ reset();
+ return result;
+ }
- bool success = true;
+ return LinkResult(true, Error(GL_NO_ERROR));
+}
- if (!linkAttributes(infoLog, attributeBindings, vertexShader))
+bool ProgramBinary::linkUniformBlocks(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
+ const gl::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++)
{
- success = false;
+ const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
+ linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
}
- if (!linkUniforms(infoLog, *vertexShader, *fragmentShader, caps))
+ for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
{
- success = false;
+ 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;
+ }
+ }
}
- // special case for gl_DepthRange, the only built-in uniform (also a struct)
- if (vertexShaderD3D->usesDepthRange() || fragmentShaderD3D->usesDepthRange())
+ for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
{
- const sh::BlockMemberInfo &defaultInfo = sh::BlockMemberInfo::getDefaultBlockInfo();
+ const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex];
- mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, defaultInfo));
- mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, defaultInfo));
- mUniforms.push_back(new LinkedUniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, defaultInfo));
+ // 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;
+ }
+ }
}
- if (!linkUniformBlocks(infoLog, *vertexShader, *fragmentShader, caps))
+ for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
{
- success = false;
+ 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;
+ }
+ }
}
- if (!gatherTransformFeedbackLinkedVaryings(infoLog, linkedVaryings, transformFeedbackVaryings,
- transformFeedbackBufferMode, &mTransformFeedbackLinkedVaryings, caps))
+ return true;
+}
+
+bool ProgramBinary::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())
{
- success = false;
+ infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName);
+ return false;
}
- if (success)
+ if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize)
{
- VertexFormat defaultInputLayout[MAX_VERTEX_ATTRIBS];
- GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout);
- rx::ShaderExecutable *defaultVertexExecutable = getVertexExecutableForInputLayout(defaultInputLayout);
+ infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName);
+ return false;
+ }
- std::vector<GLenum> defaultPixelOutput = GetDefaultOutputLayoutFromShader(mProgram->getPixelShaderKey());
- rx::ShaderExecutable *defaultPixelExecutable = getPixelExecutableForOutputLayout(defaultPixelOutput);
+ 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;
+ }
- if (usesGeometryShader())
+ 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)
{
- std::string geometryHLSL = mProgram->getDynamicHLSL()->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
- mGeometryExecutable = mProgram->getRenderer()->compileToExecutable(infoLog, geometryHLSL.c_str(),
- rx::SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
- (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS),
- rx::ANGLE_D3D_WORKAROUND_NONE);
+ 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;
}
- if (!defaultVertexExecutable || !defaultPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
+ std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
+ if (!gl::ProgramBinary::linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember))
{
- infoLog.append("Failed to create D3D shaders.");
- success = false;
- reset();
+ return false;
}
}
- return success;
+ return true;
}
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
@@ -1688,7 +682,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location;
- mShaderAttributes[attributeIndex] = attribute;
+ mProgram->getShaderAttributes()[attributeIndex] = attribute;
if (location != -1) // Set by glBindAttribLocation or by location layout qualifier
{
@@ -1708,7 +702,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
// In GLSL 3.00, attribute aliasing produces a link error
// In GLSL 1.00, attribute aliasing is allowed
- if (mShaderVersion >= 300)
+ if (mProgram->getShaderVersion() >= 300)
{
if (!linkedAttribute.name.empty())
{
@@ -1856,346 +850,6 @@ bool ProgramBinary::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std
return true;
}
-bool ProgramBinary::linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps)
-{
- const rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader.getImplementation());
- const rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader.getImplementation());
-
- const std::vector<sh::Uniform> &vertexUniforms = vertexShader.getUniforms();
- const std::vector<sh::Uniform> &fragmentUniforms = fragmentShader.getUniforms();
-
- // Check that uniforms defined in the vertex and fragment shaders are identical
- typedef std::map<std::string, const sh::Uniform*> UniformMap;
- UniformMap linkedUniforms;
-
- for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++)
- {
- const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex];
- linkedUniforms[vertexUniform.name] = &vertexUniform;
- }
-
- for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++)
- {
- const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex];
- UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name);
- if (entry != linkedUniforms.end())
- {
- const sh::Uniform &vertexUniform = *entry->second;
- const std::string &uniformName = "uniform '" + vertexUniform.name + "'";
- if (!linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform))
- {
- return false;
- }
- }
- }
-
- for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++)
- {
- const sh::Uniform &uniform = vertexUniforms[uniformIndex];
-
- if (uniform.staticUse)
- {
- defineUniformBase(GL_VERTEX_SHADER, uniform, vertexShaderD3D->getUniformRegister(uniform.name));
- }
- }
-
- for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++)
- {
- const sh::Uniform &uniform = fragmentUniforms[uniformIndex];
-
- if (uniform.staticUse)
- {
- defineUniformBase(GL_FRAGMENT_SHADER, uniform, fragmentShaderD3D->getUniformRegister(uniform.name));
- }
- }
-
- if (!indexUniforms(infoLog, caps))
- {
- return false;
- }
-
- mProgram->initializeUniformStorage(mUniforms);
-
- return true;
-}
-
-void ProgramBinary::defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister)
-{
- ShShaderOutput outputType = rx::ShaderD3D::getCompilerOutputType(shader);
- sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType));
- encoder.skipRegisters(uniformRegister);
-
- defineUniform(shader, uniform, uniform.name, &encoder);
-}
-
-void ProgramBinary::defineUniform(GLenum shader, const sh::ShaderVariable &uniform,
- const std::string &fullName, sh::HLSLBlockEncoder *encoder)
-{
- if (uniform.isStruct())
- {
- for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++)
- {
- const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : "");
-
- encoder->enterAggregateType();
-
- for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++)
- {
- const sh::ShaderVariable &field = uniform.fields[fieldIndex];
- const std::string &fieldFullName = (fullName + elementString + "." + field.name);
-
- defineUniform(shader, field, fieldFullName, encoder);
- }
-
- encoder->exitAggregateType();
- }
- }
- else // Not a struct
- {
- // Arrays are treated as aggregate types
- if (uniform.isArray())
- {
- encoder->enterAggregateType();
- }
-
- LinkedUniform *linkedUniform = getUniformByName(fullName);
-
- if (!linkedUniform)
- {
- linkedUniform = new LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize,
- -1, sh::BlockMemberInfo::getDefaultBlockInfo());
- ASSERT(linkedUniform);
- linkedUniform->registerElement = encoder->getCurrentElement();
- mUniforms.push_back(linkedUniform);
- }
-
- ASSERT(linkedUniform->registerElement == encoder->getCurrentElement());
-
- if (shader == GL_FRAGMENT_SHADER)
- {
- linkedUniform->psRegisterIndex = encoder->getCurrentRegister();
- }
- else if (shader == GL_VERTEX_SHADER)
- {
- linkedUniform->vsRegisterIndex = encoder->getCurrentRegister();
- }
- 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())
- {
- encoder->exitAggregateType();
- }
- }
-}
-
-bool ProgramBinary::indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps)
-{
- ASSERT(IsSampler(uniform.type));
- ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX);
-
- if (uniform.vsRegisterIndex != GL_INVALID_INDEX)
- {
- if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS,
- &mUsedVertexSamplerRange))
- {
- infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).",
- mSamplersVS.size());
- return false;
- }
-
- unsigned int maxVertexVectors = mProgram->getRenderer()->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors;
- if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors)
- {
- infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)",
- caps.maxVertexUniformVectors);
- return false;
- }
- }
-
- if (uniform.psRegisterIndex != GL_INVALID_INDEX)
- {
- if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS,
- &mUsedPixelSamplerRange))
- {
- infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).",
- mSamplersPS.size());
- return false;
- }
-
- unsigned int maxFragmentVectors = mProgram->getRenderer()->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors;
- if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors)
- {
- infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)",
- caps.maxFragmentUniformVectors);
- return false;
- }
- }
-
- return true;
-}
-
-bool ProgramBinary::indexUniforms(InfoLog &infoLog, const Caps &caps)
-{
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
- {
- const LinkedUniform &uniform = *mUniforms[uniformIndex];
-
- if (IsSampler(uniform.type))
- {
- if (!indexSamplerUniform(uniform, infoLog, caps))
- {
- return false;
- }
- }
-
- for (unsigned int arrayElementIndex = 0; arrayElementIndex < uniform.elementCount(); arrayElementIndex++)
- {
- mUniformIndex.push_back(VariableLocation(uniform.name, arrayElementIndex, uniformIndex));
- }
- }
-
- return true;
-}
-
-bool ProgramBinary::assignSamplers(unsigned int startSamplerIndex,
- GLenum samplerType,
- unsigned int samplerCount,
- std::vector<Sampler> &outSamplers,
- GLuint *outUsedRange)
-{
- unsigned int samplerIndex = startSamplerIndex;
-
- do
- {
- if (samplerIndex < outSamplers.size())
- {
- Sampler& sampler = outSamplers[samplerIndex];
- sampler.active = true;
- sampler.textureType = GetTextureType(samplerType);
- sampler.logicalTextureUnit = 0;
- *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
- }
- else
- {
- return false;
- }
-
- samplerIndex++;
- } while (samplerIndex < startSamplerIndex + samplerCount);
-
- return true;
-}
-
-bool ProgramBinary::areMatchingInterfaceBlocks(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 ProgramBinary::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 (!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 (!defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps))
- {
- return false;
- }
- }
- }
-
- return true;
-}
-
bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
const std::vector<std::string> &transformFeedbackVaryingNames,
GLenum transformFeedbackBufferMode,
@@ -2253,142 +907,6 @@ bool ProgramBinary::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, cons
return true;
}
-template <typename VarT>
-void ProgramBinary::defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
- sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
- bool inRowMajorLayout)
-{
- for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++)
- {
- const VarT &field = fields[uniformIndex];
- const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
-
- if (field.isStruct())
- {
- bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
-
- for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
- {
- encoder->enterAggregateType();
-
- const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
- defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout);
-
- encoder->exitAggregateType();
- }
- }
- else
- {
- bool isRowMajorMatrix = (IsMatrixType(field.type) && inRowMajorLayout);
-
- sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
-
- LinkedUniform *newUniform = new LinkedUniform(field.type, field.precision, fieldName, field.arraySize,
- blockIndex, memberInfo);
-
- // add to uniform list, but not index, since uniform block uniforms have no location
- blockUniformIndexes->push_back(mUniforms.size());
- mUniforms.push_back(newUniform);
- }
- }
-}
-
-bool ProgramBinary::defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps)
-{
- const rx::ShaderD3D* shaderD3D = rx::ShaderD3D::makeShaderD3D(shader.getImplementation());
-
- // create uniform block entries if they do not exist
- if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX)
- {
- std::vector<unsigned int> blockUniformIndexes;
- const unsigned int blockIndex = mUniformBlocks.size();
-
- // define member uniforms
- sh::BlockLayoutEncoder *encoder = NULL;
-
- if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD)
- {
- encoder = new sh::Std140BlockEncoder;
- }
- else
- {
- encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED);
- }
- ASSERT(encoder);
-
- defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout);
-
- size_t dataSize = encoder->getBlockSize();
-
- // create all the uniform blocks
- if (interfaceBlock.arraySize > 0)
- {
- for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++)
- {
- UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize);
- newUniformBlock->memberUniformIndexes = blockUniformIndexes;
- mUniformBlocks.push_back(newUniformBlock);
- }
- }
- else
- {
- UniformBlock *newUniformBlock = new UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize);
- newUniformBlock->memberUniformIndexes = blockUniformIndexes;
- mUniformBlocks.push_back(newUniformBlock);
- }
- }
-
- if (interfaceBlock.staticUse)
- {
- // Assign registers to the uniform blocks
- const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name);
- const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize);
- ASSERT(blockIndex != GL_INVALID_INDEX);
- ASSERT(blockIndex + elementCount <= mUniformBlocks.size());
-
- unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name);
-
- for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++)
- {
- UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
- ASSERT(uniformBlock->name == interfaceBlock.name);
-
- if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
- interfaceBlockRegister + uniformBlockElement, caps))
- {
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool ProgramBinary::assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps)
-{
- if (shader == GL_VERTEX_SHADER)
- {
- uniformBlock->vsRegisterIndex = registerIndex;
- if (registerIndex - mProgram->getRenderer()->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks)
- {
- infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks);
- return false;
- }
- }
- else if (shader == GL_FRAGMENT_SHADER)
- {
- uniformBlock->psRegisterIndex = registerIndex;
- if (registerIndex - mProgram->getRenderer()->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks)
- {
- infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks);
- return false;
- }
- }
- else UNREACHABLE();
-
- return true;
-}
-
bool ProgramBinary::isValidated() const
{
return mValidated;
@@ -2464,13 +982,13 @@ GLint ProgramBinary::getActiveAttributeMaxLength() const
void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
{
- ASSERT(index < mUniforms.size()); // index must be smaller than getActiveUniformCount()
+ ASSERT(index < mProgram->getUniforms().size()); // index must be smaller than getActiveUniformCount()
if (bufsize > 0)
{
- std::string string = mUniforms[index]->name;
+ std::string string = mProgram->getUniforms()[index]->name;
- if (mUniforms[index]->isArray())
+ if (mProgram->getUniforms()[index]->isArray())
{
string += "[0]";
}
@@ -2484,27 +1002,27 @@ void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *len
}
}
- *size = mUniforms[index]->elementCount();
+ *size = mProgram->getUniforms()[index]->elementCount();
- *type = mUniforms[index]->type;
+ *type = mProgram->getUniforms()[index]->type;
}
GLint ProgramBinary::getActiveUniformCount() const
{
- return mUniforms.size();
+ return mProgram->getUniforms().size();
}
GLint ProgramBinary::getActiveUniformMaxLength() const
{
int maxLength = 0;
- unsigned int numUniforms = mUniforms.size();
+ unsigned int numUniforms = mProgram->getUniforms().size();
for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
{
- if (!mUniforms[uniformIndex]->name.empty())
+ if (!mProgram->getUniforms()[uniformIndex]->name.empty())
{
- int length = (int)(mUniforms[uniformIndex]->name.length() + 1);
- if (mUniforms[uniformIndex]->isArray())
+ int length = (int)(mProgram->getUniforms()[uniformIndex]->name.length() + 1);
+ if (mProgram->getUniforms()[uniformIndex]->isArray())
{
length += 3; // Counting in "[0]".
}
@@ -2517,7 +1035,7 @@ GLint ProgramBinary::getActiveUniformMaxLength() const
GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const
{
- const gl::LinkedUniform& uniform = *mUniforms[index];
+ const gl::LinkedUniform& uniform = *mProgram->getUniforms()[index];
switch (pname)
{
@@ -2540,34 +1058,25 @@ GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const
bool ProgramBinary::isValidUniformLocation(GLint location) const
{
- ASSERT(rx::IsIntegerCastSafe<GLint>(mUniformIndex.size()));
- return (location >= 0 && location < static_cast<GLint>(mUniformIndex.size()));
+ ASSERT(rx::IsIntegerCastSafe<GLint>(mProgram->getUniformIndices().size()));
+ return (location >= 0 && location < static_cast<GLint>(mProgram->getUniformIndices().size()));
}
LinkedUniform *ProgramBinary::getUniformByLocation(GLint location) const
{
- ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size());
- return mUniforms[mUniformIndex[location].index];
+ return mProgram->getUniformByLocation(location);
}
LinkedUniform *ProgramBinary::getUniformByName(const std::string &name) const
{
- for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
- {
- if (mUniforms[uniformIndex]->name == name)
- {
- return mUniforms[uniformIndex];
- }
- }
-
- return NULL;
+ return mProgram->getUniformByName(name);
}
void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const
{
- ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount()
+ ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
- const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex];
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
if (bufSize > 0)
{
@@ -2590,9 +1099,9 @@ void ProgramBinary::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei
void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
{
- ASSERT(uniformBlockIndex < mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount()
+ ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount()
- const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex];
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
switch (pname)
{
@@ -2625,17 +1134,17 @@ void ProgramBinary::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pna
GLuint ProgramBinary::getActiveUniformBlockCount() const
{
- return mUniformBlocks.size();
+ return mProgram->getUniformBlocks().size();
}
GLuint ProgramBinary::getActiveUniformBlockMaxLength() const
{
unsigned int maxLength = 0;
- unsigned int numUniformBlocks = mUniformBlocks.size();
+ unsigned int numUniformBlocks = mProgram->getUniformBlocks().size();
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
{
- const UniformBlock &uniformBlock = *mUniformBlocks[uniformBlockIndex];
+ const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex];
if (!uniformBlock.name.empty())
{
const unsigned int length = uniformBlock.name.length() + 1;
@@ -2665,88 +1174,7 @@ void ProgramBinary::validate(InfoLog &infoLog, const Caps &caps)
bool ProgramBinary::validateSamplers(InfoLog *infoLog, const Caps &caps)
{
- // if any two active samplers in a program are of different types, but refer to the same
- // texture image unit, and this is the current program, then ValidateProgram will fail, and
- // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
- updateSamplerMapping();
-
- std::vector<GLenum> textureUnitTypes(caps.maxCombinedTextureImageUnits, GL_NONE);
-
- for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i)
- {
- if (mSamplersPS[i].active)
- {
- unsigned int unit = mSamplersPS[i].logicalTextureUnit;
-
- if (unit >= textureUnitTypes.size())
- {
- if (infoLog)
- {
- infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
- }
-
- return false;
- }
-
- if (textureUnitTypes[unit] != GL_NONE)
- {
- if (mSamplersPS[i].textureType != textureUnitTypes[unit])
- {
- if (infoLog)
- {
- infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
- }
-
- return false;
- }
- }
- else
- {
- textureUnitTypes[unit] = mSamplersPS[i].textureType;
- }
- }
- }
-
- for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i)
- {
- if (mSamplersVS[i].active)
- {
- unsigned int unit = mSamplersVS[i].logicalTextureUnit;
-
- if (unit >= textureUnitTypes.size())
- {
- if (infoLog)
- {
- infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, textureUnitTypes.size());
- }
-
- return false;
- }
-
- if (textureUnitTypes[unit] != GL_NONE)
- {
- if (mSamplersVS[i].textureType != textureUnitTypes[unit])
- {
- if (infoLog)
- {
- infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
- }
-
- return false;
- }
- }
- else
- {
- textureUnitTypes[unit] = mSamplersVS[i].textureType;
- }
- }
- }
-
- return true;
-}
-
-ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(GL_TEXTURE_2D)
-{
+ return mProgram->validateSamplers(infoLog, caps);
}
struct AttributeSorter
@@ -2795,26 +1223,6 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA
void ProgramBinary::reset()
{
- SafeDeleteContainer(mVertexExecutables);
- SafeDeleteContainer(mPixelExecutables);
-
- SafeDelete(mGeometryExecutable);
-
- mTransformFeedbackBufferMode = GL_NONE;
- mTransformFeedbackLinkedVaryings.clear();
-
- mSamplersPS.clear();
- mSamplersVS.clear();
-
- mUsedVertexSamplerRange = 0;
- mUsedPixelSamplerRange = 0;
- mUsesPointSize = false;
- mShaderVersion = 0;
- mDirtySamplerMapping = true;
-
- SafeDeleteContainer(mUniforms);
- SafeDeleteContainer(mUniformBlocks);
- mUniformIndex.clear();
mOutputVariables.clear();
mProgram->reset();
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
index ad470d417b..3142d66c6d 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
@@ -24,11 +24,6 @@
#include <string>
#include <vector>
-// TODO(jmadill): place this in workarounds library
-#define ANGLE_WORKAROUND_ENABLED 1
-#define ANGLE_WORKAROUND_DISABLED 2
-#define ANGLE_MRT_PERF_WORKAROUND ANGLE_WORKAROUND_ENABLED
-
namespace sh
{
class HLSLBlockEncoder;
@@ -44,7 +39,6 @@ class HLSLBlockEncoder;
namespace rx
{
class ShaderExecutable;
-class Renderer;
struct TranslatedAttribute;
class UniformStorage;
class ProgramImpl;
@@ -58,6 +52,7 @@ class InfoLog;
class AttributeBindings;
class Buffer;
class Framebuffer;
+struct Data;
// Struct used for correlating uniforms/elements of uniform arrays to handles
struct VariableLocation
@@ -91,6 +86,14 @@ 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
{
@@ -101,11 +104,6 @@ class ProgramBinary : public RefCountObject
rx::ProgramImpl *getImplementation() { return mProgram; }
const rx::ProgramImpl *getImplementation() const { return mProgram; }
- rx::ShaderExecutable *getPixelExecutableForFramebuffer(const Framebuffer *fbo);
- rx::ShaderExecutable *getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout);
- rx::ShaderExecutable *getVertexExecutableForInputLayout(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS]);
- rx::ShaderExecutable *getGeometryExecutable() const;
-
GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex);
@@ -113,8 +111,6 @@ class ProgramBinary : public RefCountObject
GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLint getUsedSamplerRange(SamplerType type);
bool usesPointSize() const;
- bool usesPointSpriteEmulation() const;
- bool usesGeometryShader() const;
GLint getUniformLocation(std::string name);
GLuint getUniformIndex(std::string name);
@@ -145,18 +141,17 @@ class ProgramBinary : public RefCountObject
void getUniformiv(GLint location, GLint *params);
void getUniformuiv(GLint location, GLuint *params);
- void dirtyAllUniforms();
-
Error applyUniforms();
Error applyUniformBuffers(const std::vector<Buffer*> boundBuffers, const Caps &caps);
- bool load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
- bool save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
+ LinkResult load(InfoLog &infoLog, GLenum binaryFormat, const void *binary, GLsizei length);
+ Error save(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length);
GLint getLength();
- bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, Shader *fragmentShader, Shader *vertexShader,
- const std::vector<std::string>& transformFeedbackVaryings, GLenum transformFeedbackBufferMode, const Caps &caps);
- void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
+ 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;
@@ -188,30 +183,23 @@ class ProgramBinary : public RefCountObject
void updateSamplerMapping();
unsigned int getSerial() const;
- int getShaderVersion() const;
void initAttributesByLayout();
void sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const;
- const std::vector<LinkedUniform*> &getUniforms() const { return mUniforms; }
-
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);
- struct Sampler
- {
- Sampler();
-
- bool active;
- GLint logicalTextureUnit;
- GLenum textureType;
- };
-
void reset();
bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader);
+ bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
+ bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock,
+ const sh::InterfaceBlock &fragmentInterfaceBlock);
static bool linkValidateVariablesBase(InfoLog &infoLog,
const std::string &variableName,
@@ -219,102 +207,21 @@ class ProgramBinary : public RefCountObject
const sh::ShaderVariable &fragmentVariable,
bool validatePrecision);
- static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform);
static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying);
- static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform);
- bool linkUniforms(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
- void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister);
- void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder);
- bool indexSamplerUniform(const LinkedUniform &uniform, InfoLog &infoLog, const Caps &caps);
- bool indexUniforms(InfoLog &infoLog, const Caps &caps);
- static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
- std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
- bool areMatchingInterfaceBlocks(InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock);
- bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps);
bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
const std::vector<std::string> &transformFeedbackVaryingNames,
GLenum transformFeedbackBufferMode,
std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
const Caps &caps) const;
- template <typename VarT>
- void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
- sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
- bool inRowMajorLayout);
- bool defineUniformBlock(InfoLog &infoLog, const Shader &shader, const sh::InterfaceBlock &interfaceBlock, const Caps &caps);
bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps);
void defineOutputVariables(Shader *fragmentShader);
- template <typename T>
- void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
-
- template <int cols, int rows>
- void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
-
- template <typename T>
- void getUniformv(GLint location, T *params, GLenum uniformType);
-
- class VertexExecutable
- {
- public:
- VertexExecutable(const VertexFormat inputLayout[MAX_VERTEX_ATTRIBS],
- const GLenum signature[MAX_VERTEX_ATTRIBS],
- rx::ShaderExecutable *shaderExecutable);
- ~VertexExecutable();
-
- bool matchesSignature(const GLenum convertedLayout[MAX_VERTEX_ATTRIBS]) const;
-
- const VertexFormat *inputs() const { return mInputs; }
- const GLenum *signature() const { return mSignature; }
- rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
-
- private:
- VertexFormat mInputs[MAX_VERTEX_ATTRIBS];
- GLenum mSignature[MAX_VERTEX_ATTRIBS];
- rx::ShaderExecutable *mShaderExecutable;
- };
-
- class PixelExecutable
- {
- public:
- PixelExecutable(const std::vector<GLenum> &outputSignature, rx::ShaderExecutable *shaderExecutable);
- ~PixelExecutable();
-
- bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
-
- const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
- rx::ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
-
- private:
- std::vector<GLenum> mOutputSignature;
- rx::ShaderExecutable *mShaderExecutable;
- };
-
rx::ProgramImpl *mProgram;
- std::vector<VertexExecutable *> mVertexExecutables;
- std::vector<PixelExecutable *> mPixelExecutables;
-
- rx::ShaderExecutable *mGeometryExecutable;
-
sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
- sh::Attribute mShaderAttributes[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
int mAttributesByLayout[MAX_VERTEX_ATTRIBS];
- GLenum mTransformFeedbackBufferMode;
- std::vector<LinkedVarying> mTransformFeedbackLinkedVaryings;
-
- std::vector<Sampler> mSamplersPS;
- std::vector<Sampler> mSamplersVS;
- GLuint mUsedVertexSamplerRange;
- GLuint mUsedPixelSamplerRange;
- bool mUsesPointSize;
- int mShaderVersion;
- bool mDirtySamplerMapping;
-
- std::vector<LinkedUniform*> mUniforms;
- std::vector<UniformBlock*> mUniformBlocks;
- std::vector<VariableLocation> mUniformIndex;
std::map<int, VariableLocation> mOutputVariables;
bool mValidated;
diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
index 9406fce58d..911a389dfa 100644
--- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
@@ -4,77 +4,86 @@
// found in the LICENSE file.
//
-// Renderbuffer.cpp: the gl::Renderbuffer class and its derived classes
-// Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
+// Renderbuffer.cpp: Implements the renderer-agnostic gl::Renderbuffer class,
+// GL renderbuffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 4.4.3 page 108.
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/d3d/RendererD3D.h"
#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/renderer/RenderbufferImpl.h"
#include "common/utilities.h"
namespace gl
{
-unsigned int RenderbufferStorage::mCurrentSerial = 1;
-
-Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *newStorage)
+Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id)
: RefCountObject(id),
- mStorage(newStorage)
+ mRenderbuffer(impl)
{
- ASSERT(mStorage);
+ ASSERT(mRenderbuffer);
+
+ mWidth = mRenderbuffer->getWidth();
+ mHeight = mRenderbuffer->getHeight();
+ mInternalFormat = mRenderbuffer->getInternalFormat();
+ mActualFormat = mRenderbuffer->getActualFormat();
+ mSamples = mRenderbuffer->getSamples();
}
Renderbuffer::~Renderbuffer()
{
- SafeDelete(mStorage);
+ SafeDelete(mRenderbuffer);
}
-void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
+Error Renderbuffer::setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
{
- ASSERT(newStorage);
+ Error error = mRenderbuffer->setStorage(width, height, internalformat, samples);
+ if (error.isError())
+ {
+ return error;
+ }
- SafeDelete(mStorage);
- mStorage = newStorage;
+ mWidth = width;
+ mHeight = height;
+ mInternalFormat = internalformat;
+ mSamples = samples;
+ mActualFormat = mRenderbuffer->getActualFormat();
+
+ return Error(GL_NO_ERROR);
}
-RenderbufferStorage *Renderbuffer::getStorage()
+rx::RenderbufferImpl *Renderbuffer::getImplementation()
{
- ASSERT(mStorage);
- return mStorage;
+ ASSERT(mRenderbuffer);
+ return mRenderbuffer;
}
GLsizei Renderbuffer::getWidth() const
{
- ASSERT(mStorage);
- return mStorage->getWidth();
+ return mWidth;
}
GLsizei Renderbuffer::getHeight() const
{
- ASSERT(mStorage);
- return mStorage->getHeight();
+ return mHeight;
}
GLenum Renderbuffer::getInternalFormat() const
{
- ASSERT(mStorage);
- return mStorage->getInternalFormat();
+ return mInternalFormat;
}
GLenum Renderbuffer::getActualFormat() const
{
- ASSERT(mStorage);
- return mStorage->getActualFormat();
+ return mActualFormat;
}
GLsizei Renderbuffer::getSamples() const
{
- ASSERT(mStorage);
- return mStorage->getSamples();
+ return mSamples;
}
GLuint Renderbuffer::getRedSize() const
@@ -107,176 +116,4 @@ GLuint Renderbuffer::getStencilSize() const
return GetInternalFormatInfo(getActualFormat()).stencilBits;
}
-RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerials(1))
-{
- mWidth = 0;
- mHeight = 0;
- mInternalFormat = GL_RGBA4;
- mActualFormat = GL_RGBA8_OES;
- mSamples = 0;
-}
-
-RenderbufferStorage::~RenderbufferStorage()
-{
-}
-
-rx::RenderTarget *RenderbufferStorage::getRenderTarget()
-{
- return NULL;
-}
-
-GLsizei RenderbufferStorage::getWidth() const
-{
- return mWidth;
-}
-
-GLsizei RenderbufferStorage::getHeight() const
-{
- return mHeight;
-}
-
-GLenum RenderbufferStorage::getInternalFormat() const
-{
- return mInternalFormat;
-}
-
-GLenum RenderbufferStorage::getActualFormat() const
-{
- return mActualFormat;
-}
-
-GLsizei RenderbufferStorage::getSamples() const
-{
- return mSamples;
-}
-
-unsigned int RenderbufferStorage::getSerial() const
-{
- return mSerial;
-}
-
-unsigned int RenderbufferStorage::issueSerials(unsigned int count)
-{
- unsigned int firstSerial = mCurrentSerial;
- mCurrentSerial += count;
- return firstSerial;
-}
-
-bool RenderbufferStorage::isTexture() const
-{
- return false;
-}
-
-unsigned int RenderbufferStorage::getTextureSerial() const
-{
- return -1;
-}
-
-Colorbuffer::Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain)
-{
- mRenderTarget = renderer->createRenderTarget(swapChain, false);
-
- if (mRenderTarget)
- {
- mWidth = mRenderTarget->getWidth();
- mHeight = mRenderTarget->getHeight();
- mInternalFormat = mRenderTarget->getInternalFormat();
- mActualFormat = mRenderTarget->getActualFormat();
- mSamples = mRenderTarget->getSamples();
- }
-}
-
-Colorbuffer::Colorbuffer(rx::Renderer *renderer, int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
-{
- mRenderTarget = renderer->createRenderTarget(width, height, format, samples);
-
- if (mRenderTarget)
- {
- mWidth = width;
- mHeight = height;
- mInternalFormat = format;
- mActualFormat = mRenderTarget->getActualFormat();
- mSamples = mRenderTarget->getSamples();
- }
-}
-
-Colorbuffer::~Colorbuffer()
-{
- if (mRenderTarget)
- {
- delete mRenderTarget;
- }
-}
-
-rx::RenderTarget *Colorbuffer::getRenderTarget()
-{
- return mRenderTarget;
-}
-
-DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain)
-{
- mDepthStencil = renderer->createRenderTarget(swapChain, true);
- if (mDepthStencil)
- {
- mWidth = mDepthStencil->getWidth();
- mHeight = mDepthStencil->getHeight();
- mInternalFormat = mDepthStencil->getInternalFormat();
- mSamples = mDepthStencil->getSamples();
- mActualFormat = mDepthStencil->getActualFormat();
- }
-}
-
-DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples)
-{
-
- mDepthStencil = renderer->createRenderTarget(width, height, GL_DEPTH24_STENCIL8_OES, samples);
-
- mWidth = mDepthStencil->getWidth();
- mHeight = mDepthStencil->getHeight();
- mInternalFormat = GL_DEPTH24_STENCIL8_OES;
- mActualFormat = mDepthStencil->getActualFormat();
- mSamples = mDepthStencil->getSamples();
-}
-
-DepthStencilbuffer::~DepthStencilbuffer()
-{
- if (mDepthStencil)
- {
- delete mDepthStencil;
- }
-}
-
-rx::RenderTarget *DepthStencilbuffer::getRenderTarget()
-{
- return mDepthStencil;
-}
-
-Depthbuffer::Depthbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples)
-{
- if (mDepthStencil)
- {
- mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
- }
-}
-
-Depthbuffer::~Depthbuffer()
-{
-}
-
-Stencilbuffer::Stencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples)
-{
- if (mDepthStencil)
- {
- mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
- }
-}
-
-Stencilbuffer::~Stencilbuffer()
-{
-}
-
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
index 71bcb0e1f8..e9f12af3ce 100644
--- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
@@ -4,30 +4,27 @@
// found in the LICENSE file.
//
-// Renderbuffer.h: Defines the wrapper class gl::Renderbuffer, as well as the
-// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
-// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
-// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
+// Renderbuffer.h: Defines the renderer-agnostic container class gl::Renderbuffer.
+// Implements GL renderbuffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 4.4.3 page 108.
#ifndef LIBGLESV2_RENDERBUFFER_H_
#define LIBGLESV2_RENDERBUFFER_H_
#include "angle_gl.h"
+#include "libGLESv2/Error.h"
+
#include "common/angleutils.h"
#include "common/RefCountObject.h"
namespace rx
{
-class Renderer;
-class SwapChain;
-class RenderTarget;
-class TextureStorage;
+class RenderbufferImpl;
}
namespace gl
{
-class RenderbufferStorage;
class FramebufferAttachment;
// A GL renderbuffer object is usually used as a depth or stencil buffer attachment
@@ -38,11 +35,12 @@ class FramebufferAttachment;
class Renderbuffer : public RefCountObject
{
public:
- Renderbuffer(GLuint id, RenderbufferStorage *newStorage);
+ Renderbuffer(rx::RenderbufferImpl *impl, GLuint id);
virtual ~Renderbuffer();
- void setStorage(RenderbufferStorage *newStorage);
- RenderbufferStorage *getStorage();
+ Error setStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
+
+ rx::RenderbufferImpl *getImplementation();
GLsizei getWidth() const;
GLsizei getHeight() const;
@@ -57,102 +55,15 @@ class Renderbuffer : public RefCountObject
GLuint getStencilSize() const;
private:
- RenderbufferStorage *mStorage;
-};
-
-// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
-// is called. The specific concrete type depends on whether the internal format is
-// colour depth, stencil or packed depth/stencil.
-class RenderbufferStorage
-{
- public:
- RenderbufferStorage();
+ DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
- virtual ~RenderbufferStorage() = 0;
+ rx::RenderbufferImpl *mRenderbuffer;
- virtual rx::RenderTarget *getRenderTarget();
-
- virtual GLsizei getWidth() const;
- virtual GLsizei getHeight() const;
- virtual GLenum getInternalFormat() const;
- virtual GLenum getActualFormat() const;
- virtual GLsizei getSamples() const;
-
- virtual unsigned int getSerial() const;
-
- virtual bool isTexture() const;
- virtual unsigned int getTextureSerial() const;
-
- static unsigned int issueSerials(unsigned int count);
-
- protected:
GLsizei mWidth;
GLsizei mHeight;
GLenum mInternalFormat;
GLenum mActualFormat;
GLsizei mSamples;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage);
-
- const unsigned int mSerial;
-
- static unsigned int mCurrentSerial;
-};
-
-class Colorbuffer : public RenderbufferStorage
-{
- public:
- Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain);
- Colorbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples);
-
- virtual ~Colorbuffer();
-
- virtual rx::RenderTarget *getRenderTarget();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Colorbuffer);
-
- rx::RenderTarget *mRenderTarget;
-};
-
-class DepthStencilbuffer : public RenderbufferStorage
-{
- public:
- DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain);
- DepthStencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
-
- ~DepthStencilbuffer();
-
- virtual rx::RenderTarget *getRenderTarget();
-
- protected:
- rx::RenderTarget *mDepthStencil;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer);
-};
-
-class Depthbuffer : public DepthStencilbuffer
-{
- public:
- Depthbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
-
- virtual ~Depthbuffer();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Depthbuffer);
-};
-
-class Stencilbuffer : public DepthStencilbuffer
-{
- public:
- Stencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
-
- virtual ~Stencilbuffer();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Stencilbuffer);
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
index 9121de1750..38d53cad81 100644
--- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
@@ -21,9 +21,9 @@
namespace gl
{
ResourceManager::ResourceManager(rx::Renderer *renderer)
+ : mRenderer(renderer),
+ mRefCount(1)
{
- mRefCount = 1;
- mRenderer = renderer;
}
ResourceManager::~ResourceManager()
@@ -88,13 +88,13 @@ GLuint ResourceManager::createBuffer()
}
// Returns an unused shader/program name
-GLuint ResourceManager::createShader(GLenum type)
+GLuint ResourceManager::createShader(const gl::Data &data, GLenum type)
{
GLuint handle = mProgramShaderHandleAllocator.allocate();
if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER)
{
- mShaderMap[handle] = new Shader(this, mRenderer->createShader(type), type, handle);
+ mShaderMap[handle] = new Shader(this, mRenderer->createShader(data, type), type, handle);
}
else UNREACHABLE();
@@ -146,7 +146,7 @@ GLuint ResourceManager::createFenceSync()
{
GLuint handle = mFenceSyncHandleAllocator.allocate();
- FenceSync *fenceSync = new FenceSync(mRenderer, handle);
+ FenceSync *fenceSync = new FenceSync(mRenderer->createFenceSync(), handle);
fenceSync->addRef();
mFenceSyncMap[handle] = fenceSync;
@@ -295,9 +295,9 @@ Texture *ResourceManager::getTexture(unsigned int handle)
}
}
-Program *ResourceManager::getProgram(unsigned int handle)
+Program *ResourceManager::getProgram(unsigned int handle) const
{
- ProgramMap::iterator program = mProgramMap.find(handle);
+ ProgramMap::const_iterator program = mProgramMap.find(handle);
if (program == mProgramMap.end())
{
@@ -403,7 +403,7 @@ void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
{
if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
{
- Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
+ Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer->createRenderbuffer(), renderbuffer);
mRenderbufferMap[renderbuffer] = renderbufferObject;
renderbufferObject->addRef();
}
diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
index 7d53bd4854..acad29b51d 100644
--- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
+++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
@@ -32,6 +32,7 @@ class Texture;
class Renderbuffer;
class Sampler;
class FenceSync;
+struct Data;
class ResourceManager
{
@@ -43,7 +44,7 @@ class ResourceManager
void release();
GLuint createBuffer();
- GLuint createShader(GLenum type);
+ GLuint createShader(const gl::Data &data, GLenum type);
GLuint createProgram();
GLuint createTexture();
GLuint createRenderbuffer();
@@ -60,7 +61,7 @@ class ResourceManager
Buffer *getBuffer(GLuint handle);
Shader *getShader(GLuint handle);
- Program *getProgram(GLuint handle);
+ Program *getProgram(GLuint handle) const;
Texture *getTexture(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle);
Sampler *getSampler(GLuint handle);
@@ -78,8 +79,8 @@ class ResourceManager
private:
DISALLOW_COPY_AND_ASSIGN(ResourceManager);
- std::size_t mRefCount;
rx::Renderer *mRenderer;
+ std::size_t mRefCount;
typedef std::unordered_map<GLuint, Buffer*> BufferMap;
BufferMap mBufferMap;
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
index 4cf5251ff9..1cc17a0501 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
@@ -118,9 +118,15 @@ void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer);
}
-void Shader::compile()
+void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const
{
- mCompiled = mShader->compile(mSource);
+ std::string debugInfo(mShader->getDebugInfo());
+ getSourceImpl(debugInfo, bufSize, length, buffer);
+}
+
+void Shader::compile(const gl::Data &data)
+{
+ mCompiled = mShader->compile(data, mSource);
}
void Shader::addRef()
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.h b/src/3rdparty/angle/src/libGLESv2/Shader.h
index 7ba3bd165c..904217dab8 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.h
+++ b/src/3rdparty/angle/src/libGLESv2/Shader.h
@@ -31,6 +31,7 @@ class ShaderImpl;
namespace gl
{
class ResourceManager;
+struct Data;
struct PackedVarying : public sh::Varying
{
@@ -73,8 +74,9 @@ class Shader
void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
int getTranslatedSourceLength() const;
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
+ void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const;
- void compile();
+ void compile(const gl::Data &data);
bool isCompiled() const { return mCompiled; }
void addRef();
diff --git a/src/3rdparty/angle/src/libGLESv2/State.cpp b/src/3rdparty/angle/src/libGLESv2/State.cpp
index 3c03b90e56..b5b62f5848 100644
--- a/src/3rdparty/angle/src/libGLESv2/State.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/State.cpp
@@ -10,18 +10,20 @@
#include "libGLESv2/Context.h"
#include "libGLESv2/Caps.h"
-#include "libGLESv2/VertexArray.h"
-#include "libGLESv2/Query.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/FramebufferAttachment.h"
-#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/Query.h"
+#include "libGLESv2/VertexArray.h"
#include "libGLESv2/formatutils.h"
+#include "libGLESv2/renderer/RenderTarget.h"
namespace gl
{
State::State()
{
+ mMaxDrawBuffers = 0;
+ mMaxCombinedTextureImageUnits = 0;
}
State::~State()
@@ -31,7 +33,8 @@ State::~State()
void State::initialize(const Caps& caps, GLuint clientVersion)
{
- mContext = NULL;
+ mMaxDrawBuffers = caps.maxDrawBuffers;
+ mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -111,11 +114,15 @@ void State::initialize(const Caps& caps, GLuint clientVersion)
mActiveSampler = 0;
const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
- for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
+ mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
+ for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex)
{
mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
}
+ mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
+ mTransformFeedbackBuffers.resize(caps.maxTransformFeedbackSeparateAttributes);
+
mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
if (clientVersion >= 3)
@@ -153,12 +160,6 @@ void State::reset()
mSamplers[samplerIdx].set(NULL);
}
- const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
- for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
- {
- mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
- }
-
mArrayBuffer.set(NULL);
mRenderbuffer.set(NULL);
@@ -170,15 +171,15 @@ void State::reset()
}
mGenericUniformBuffer.set(NULL);
- for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
+ mGenericTransformFeedbackBuffer.set(NULL);
+ for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
{
- mUniformBuffers[i].set(NULL);
+ bufItr->set(NULL);
}
- mGenericTransformFeedbackBuffer.set(NULL);
- for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
+ for (BufferVector::iterator bufItr = mTransformFeedbackBuffers.begin(); bufItr != mTransformFeedbackBuffers.end(); ++bufItr)
{
- mTransformFeedbackBuffers[i].set(NULL);
+ bufItr->set(NULL);
}
mCopyReadBuffer.set(NULL);
@@ -485,7 +486,7 @@ void State::setSampleCoverageParams(GLclampf value, bool invert)
mSampleCoverageInvert = invert;
}
-void State::getSampleCoverageParams(GLclampf *value, bool *invert)
+void State::getSampleCoverageParams(GLclampf *value, bool *invert) const
{
ASSERT(value != NULL && invert != NULL);
@@ -612,14 +613,7 @@ void State::setSamplerTexture(GLenum type, Texture *texture)
Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
{
- const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler];
-
- if (binding.id() == 0) // Special case: 0 refers to default textures held by Context
- {
- return NULL;
- }
-
- return binding.get();
+ return mSamplerTextures.at(type)[sampler].get();
}
GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
@@ -627,7 +621,7 @@ GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
return mSamplerTextures.at(type)[sampler].id();
}
-void State::detachTexture(GLuint texture)
+void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
{
// Textures have a detach method on State rather than a simple
// removeBinding, because the zero/null texture objects are managed
@@ -640,13 +634,15 @@ void State::detachTexture(GLuint texture)
for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
{
+ GLenum textureType = bindingVec->first;
TextureBindingVector &textureVector = bindingVec->second;
for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
{
BindingPointer<Texture> &binding = textureVector[textureIdx];
if (binding.id() == texture)
{
- binding.set(NULL);
+ // Zero textures are the "default" textures instead of NULL
+ binding.set(zeroTextures.at(textureType).get());
}
}
}
@@ -667,6 +663,19 @@ void State::detachTexture(GLuint texture)
}
}
+void State::initializeZeroTextures(const TextureMap &zeroTextures)
+{
+ for (TextureMap::const_iterator i = zeroTextures.begin(); i != zeroTextures.end(); i++)
+ {
+ TextureBindingVector &samplerTextureArray = mSamplerTextures[i->first];
+
+ for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
+ {
+ samplerTextureArray[textureUnit].set(i->second.get());
+ }
+ }
+}
+
void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
{
mSamplers[textureUnit].set(sampler);
@@ -947,14 +956,14 @@ void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintpt
GLuint State::getIndexedUniformBufferId(GLuint index) const
{
- ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
+ ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
return mUniformBuffers[index].id();
}
Buffer *State::getIndexedUniformBuffer(GLuint index) const
{
- ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
+ ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
return mUniformBuffers[index].get();
}
@@ -971,25 +980,30 @@ void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffe
GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
{
- ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
+ ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
return mTransformFeedbackBuffers[index].id();
}
Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
{
- ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
+ ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
return mTransformFeedbackBuffers[index].get();
}
GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
{
- ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
+ ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
return mTransformFeedbackBuffers[index].getOffset();
}
+size_t State::getTransformFeedbackBufferIndexRange() const
+{
+ return mTransformFeedbackBuffers.size();
+}
+
void State::setCopyReadBufferBinding(Buffer *buffer)
{
mCopyReadBuffer.set(buffer);
@@ -1033,19 +1047,19 @@ void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
void State::setVertexAttribf(GLuint index, const GLfloat values[4])
{
- ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
+ ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
mVertexAttribCurrentValues[index].setFloatValues(values);
}
void State::setVertexAttribu(GLuint index, const GLuint values[4])
{
- ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
+ ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
}
void State::setVertexAttribi(GLuint index, const GLint values[4])
{
- ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
+ ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
mVertexAttribCurrentValues[index].setIntValues(values);
}
@@ -1062,15 +1076,10 @@ const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
{
- ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
+ ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
return mVertexAttribCurrentValues[attribNum];
}
-const VertexAttribCurrentValueData *State::getVertexAttribCurrentValues() const
-{
- return mVertexAttribCurrentValues;
-}
-
const void *State::getVertexAttribPointer(unsigned int attribNum) const
{
return getVertexArray()->getVertexAttribute(attribNum).pointer;
@@ -1180,12 +1189,12 @@ void State::getFloatv(GLenum pname, GLfloat *params)
}
}
-void State::getIntegerv(GLenum pname, GLint *params)
+void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
{
if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
{
unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
- ASSERT(colorAttachment < mContext->getCaps().maxDrawBuffers);
+ ASSERT(colorAttachment < mMaxDrawBuffers);
Framebuffer *framebuffer = mDrawFramebuffer;
*params = framebuffer->getDrawBufferState(colorAttachment);
return;
@@ -1238,12 +1247,12 @@ void State::getIntegerv(GLenum pname, GLint *params)
case GL_SAMPLES:
{
gl::Framebuffer *framebuffer = mDrawFramebuffer;
- if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+ if (framebuffer->completeness(data) == GL_FRAMEBUFFER_COMPLETE)
{
switch (pname)
{
case GL_SAMPLE_BUFFERS:
- if (framebuffer->getSamples() != 0)
+ if (framebuffer->getSamples(data) != 0)
{
*params = 1;
}
@@ -1253,7 +1262,7 @@ void State::getIntegerv(GLenum pname, GLint *params)
}
break;
case GL_SAMPLES:
- *params = framebuffer->getSamples();
+ *params = framebuffer->getSamples(data);
break;
}
}
@@ -1332,19 +1341,19 @@ void State::getIntegerv(GLenum pname, GLint *params)
}
break;
case GL_TEXTURE_BINDING_2D:
- ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+ ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_CUBE_MAP:
- ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+ ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_3D:
- ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits);
+ ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
break;
case GL_TEXTURE_BINDING_2D_ARRAY:
- ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
+ ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
*params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
break;
case GL_UNIFORM_BUFFER_BINDING:
@@ -1376,13 +1385,13 @@ bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
switch (target)
{
case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
- if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
+ if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
{
*data = mTransformFeedbackBuffers[index].id();
}
break;
case GL_UNIFORM_BUFFER_BINDING:
- if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
+ if (static_cast<size_t>(index) < mUniformBuffers.size())
{
*data = mUniformBuffers[index].id();
}
@@ -1399,25 +1408,25 @@ bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
switch (target)
{
case GL_TRANSFORM_FEEDBACK_BUFFER_START:
- if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
+ if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
{
*data = mTransformFeedbackBuffers[index].getOffset();
}
break;
case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
- if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
+ if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
{
*data = mTransformFeedbackBuffers[index].getSize();
}
break;
case GL_UNIFORM_BUFFER_START:
- if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
+ if (static_cast<size_t>(index) < mUniformBuffers.size())
{
*data = mUniformBuffers[index].getOffset();
}
break;
case GL_UNIFORM_BUFFER_SIZE:
- if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
+ if (static_cast<size_t>(index) < mUniformBuffers.size())
{
*data = mUniformBuffers[index].getSize();
}
@@ -1433,9 +1442,9 @@ bool State::hasMappedBuffer(GLenum target) const
{
if (target == GL_ARRAY_BUFFER)
{
- for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
+ for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++)
{
- const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
+ const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast<unsigned int>(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/libGLESv2/State.h
index 5f0433136c..c3e6106bd8 100644
--- a/src/3rdparty/angle/src/libGLESv2/State.h
+++ b/src/3rdparty/angle/src/libGLESv2/State.h
@@ -25,6 +25,9 @@ class Query;
class VertexArray;
class Context;
struct Caps;
+struct Data;
+
+typedef std::map< GLenum, BindingPointer<Texture> > TextureMap;
class State
{
@@ -35,8 +38,6 @@ class State
void initialize(const Caps& caps, GLuint clientVersion);
void reset();
- void setContext(Context *context) { mContext = context; }
-
// State chunk getters
const RasterizerState &getRasterizerState() const;
const BlendState &getBlendState() const;
@@ -100,7 +101,7 @@ class State
bool isSampleCoverageEnabled() const;
void setSampleCoverage(bool enabled);
void setSampleCoverageParams(GLclampf value, bool invert);
- void getSampleCoverageParams(GLclampf *value, bool *invert);
+ void getSampleCoverageParams(GLclampf *value, bool *invert) const;
// Scissor test state toggle & query
bool isScissorTestEnabled() const;
@@ -133,7 +134,8 @@ class State
void setSamplerTexture(GLenum type, Texture *texture);
Texture *getSamplerTexture(unsigned int sampler, GLenum type) const;
GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const;
- void detachTexture(GLuint texture);
+ void detachTexture(const TextureMap &zeroTextures, GLuint texture);
+ void initializeZeroTextures(const TextureMap &zeroTextures);
// Sampler object binding manipulation
void setSamplerBinding(GLuint textureUnit, Sampler *sampler);
@@ -199,6 +201,7 @@ class State
GLuint getIndexedTransformFeedbackBufferId(GLuint index) const;
Buffer *getIndexedTransformFeedbackBuffer(GLuint index) const;
GLuint getIndexedTransformFeedbackBufferOffset(GLuint index) const;
+ size_t getTransformFeedbackBufferIndexRange() const;
// GL_COPY_[READ/WRITE]_BUFFER
void setCopyReadBufferBinding(Buffer *buffer);
@@ -220,7 +223,6 @@ class State
bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
const VertexAttribute &getVertexAttribState(unsigned int attribNum) const;
const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const;
- const VertexAttribCurrentValueData *getVertexAttribCurrentValues() const;
const void *getVertexAttribPointer(unsigned int attribNum) const;
// Pixel pack state manipulation
@@ -238,7 +240,7 @@ class State
// State query functions
void getBooleanv(GLenum pname, GLboolean *params);
void getFloatv(GLenum pname, GLfloat *params);
- void getIntegerv(GLenum pname, GLint *params);
+ void getIntegerv(const gl::Data &data, GLenum pname, GLint *params);
bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data);
bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data);
@@ -247,7 +249,9 @@ class State
private:
DISALLOW_COPY_AND_ASSIGN(State);
- Context *mContext;
+ // Cached values from Context's caps
+ GLuint mMaxDrawBuffers;
+ GLuint mMaxCombinedTextureImageUnits;
ColorF mColorClearValue;
GLclampf mDepthClearValue;
@@ -283,7 +287,8 @@ class State
GLuint mCurrentProgramId;
BindingPointer<ProgramBinary> mCurrentProgramBinary;
- VertexAttribCurrentValueData mVertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib
+ typedef std::vector<VertexAttribCurrentValueData> VertexAttribVector;
+ VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib
VertexArray *mVertexArray;
// Texture and sampler bindings
@@ -300,11 +305,12 @@ class State
ActiveQueryMap mActiveQueries;
BindingPointer<Buffer> mGenericUniformBuffer;
- OffsetBindingPointer<Buffer> mUniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
+ typedef std::vector< OffsetBindingPointer<Buffer> > BufferVector;
+ BufferVector mUniformBuffers;
BindingPointer<TransformFeedback> mTransformFeedback;
BindingPointer<Buffer> mGenericTransformFeedbackBuffer;
- OffsetBindingPointer<Buffer> mTransformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
+ BufferVector mTransformFeedbackBuffers;
BindingPointer<Buffer> mCopyReadBuffer;
BindingPointer<Buffer> mCopyWriteBuffer;
diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.cpp b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
index 3ec492de07..cd4fc4e32a 100644
--- a/src/3rdparty/angle/src/libGLESv2/Texture.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
@@ -47,11 +47,14 @@ 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),
- mImmutable(false),
+ mImmutableLevelCount(0),
mTarget(target)
{
}
@@ -72,16 +75,6 @@ void Texture::setUsage(GLenum usage)
getImplementation()->setUsage(usage);
}
-void Texture::getSamplerStateWithNativeOffset(SamplerState *sampler)
-{
- *sampler = mSamplerState;
-
- // Offset the effective base level by the texture storage's top level
- rx::TextureStorage *texture = getNativeTexture();
- int topLevel = texture ? texture->getTopLevel() : 0;
- sampler->baseLevel = topLevel + mSamplerState.baseLevel;
-}
-
GLenum Texture::getUsage() const
{
return mUsage;
@@ -138,35 +131,35 @@ GLenum Texture::getActualFormat(const ImageIndex &index) const
return image->getActualFormat();
}
-rx::TextureStorage *Texture::getNativeTexture()
+Error Texture::generateMipmaps()
{
- return getImplementation()->getNativeTexture();
+ return getImplementation()->generateMipmaps();
}
-void Texture::generateMipmaps()
+Error Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
- getImplementation()->generateMipmaps();
+ return mTexture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
}
-void Texture::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+unsigned int Texture::getTextureSerial() const
{
- getImplementation()->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source);
+ return mTextureSerial;
}
-unsigned int Texture::getTextureSerial()
+unsigned int Texture::issueTextureSerial()
{
- rx::TextureStorage *texture = getNativeTexture();
- return texture ? texture->getTextureSerial() : 0;
+ return mCurrentTextureSerial++;
}
bool Texture::isImmutable() const
{
- return mImmutable;
+ return (mImmutableLevelCount > 0);
}
int Texture::immutableLevelCount()
{
- return (mImmutable ? getNativeTexture()->getLevelCount() : 0);
+ return mImmutableLevelCount;
}
int Texture::mipLevels() const
@@ -226,11 +219,11 @@ GLenum Texture2D::getActualFormat(GLint level) const
return GL_NONE;
}
-void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
releaseTexImage();
- mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
+ return mTexture->setImage(GL_TEXTURE_2D, level, width, height, 1, internalFormat, format, type, unpack, pixels);
}
void Texture2D::bindTexImage(egl::Surface *surface)
@@ -254,35 +247,44 @@ void Texture2D::releaseTexImage()
}
}
-void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+Error Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize,
+ const PixelUnpackState &unpack, const void *pixels)
{
releaseTexImage();
- mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, pixels);
+ return mTexture->setCompressedImage(GL_TEXTURE_2D, level, format, width, height, 1, imageSize, unpack, pixels);
}
-void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
+ return mTexture->subImage(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
}
-void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+Error Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels);
+ return mTexture->subImageCompressed(GL_TEXTURE_2D, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, unpack, pixels);
}
-void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+Error Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height,
+ Framebuffer *source)
{
releaseTexImage();
- mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
+ return mTexture->copyImage(GL_TEXTURE_2D, level, format, x, y, width, height, source);
}
-void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+Error Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
- mImmutable = true;
+ Error error = mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mImmutableLevelCount = levels;
- mTexture->storage(GL_TEXTURE_2D, levels, internalformat, width, height, 1);
+ return Error(GL_NO_ERROR);
}
// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
@@ -359,11 +361,11 @@ bool Texture2D::isDepth(GLint level) const
return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void Texture2D::generateMipmaps()
+Error Texture2D::generateMipmaps()
{
releaseTexImage();
- mTexture->generateMipmaps();
+ return mTexture->generateMipmaps();
}
// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
@@ -467,49 +469,27 @@ GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
return GL_NONE;
}
-void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
-}
-
-void TextureCubeMap::setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, width, height, 1, internalFormat, format, type, unpack, pixels);
-}
-
-void TextureCubeMap::setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
-}
-
-void TextureCubeMap::setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
-{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, width, height, 1, internalFormat, format, type, unpack, pixels);
-}
-
-void TextureCubeMap::setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
+ return mTexture->setImage(target, level, width, height, 1, internalFormat, format, type, unpack, pixels);
}
-void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height,
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, width, height, 1, internalFormat, format, type, unpack, pixels);
+ return mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, unpack, pixels);
}
-void TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *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)
{
- mTexture->setCompressedImage(target, level, format, width, height, 1, imageSize, pixels);
+ return mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
}
-void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *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)
{
- mTexture->subImage(target, level, xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels);
-}
-
-void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
-{
- mTexture->subImageCompressed(target, level, xoffset, yoffset, 0, width, height, 1, format, imageSize, 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.
@@ -549,16 +529,23 @@ bool TextureCubeMap::isDepth(GLenum target, GLint level) const
return GetInternalFormatInfo(getInternalFormat(target, level)).depthBits > 0;
}
-void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
+Error TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y,
+ GLsizei width, GLsizei height, Framebuffer *source)
{
- mTexture->copyImage(target, level, format, x, y, width, height, source);
+ return mTexture->copyImage(target, level, format, x, y, width, height, source);
}
-void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
+Error TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
{
- mImmutable = true;
+ Error error = mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mImmutableLevelCount = levels;
- mTexture->storage(GL_TEXTURE_CUBE_MAP, levels, internalformat, size, size, 1);
+ return Error(GL_NO_ERROR);
}
// Tests for texture sampling completeness
@@ -734,31 +721,40 @@ bool Texture3D::isDepth(GLint level) const
return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels);
+ return mTexture->setImage(GL_TEXTURE_3D, level, width, height, depth, internalFormat, format, type, unpack, pixels);
}
-void Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+Error Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, pixels);
+ return mTexture->setCompressedImage(GL_TEXTURE_3D, level, format, width, height, depth, imageSize, unpack, pixels);
}
-void 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)
+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)
{
- mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
+ return mTexture->subImage(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
}
-void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *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)
{
- mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
+ return mTexture->subImageCompressed(GL_TEXTURE_3D, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
}
-void Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+Error Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
- mImmutable = true;
+ Error error = mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
+ if (error.isError())
+ {
+ return error;
+ }
- mTexture->storage(GL_TEXTURE_3D, levels, internalformat, width, height, depth);
+ mImmutableLevelCount = levels;
+
+ return Error(GL_NO_ERROR);
}
bool Texture3D::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
@@ -892,31 +888,40 @@ bool Texture2DArray::isDepth(GLint level) const
return GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
}
-void Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
+Error Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels);
+ return mTexture->setImage(GL_TEXTURE_2D_ARRAY, level, width, height, depth, internalFormat, format, type, unpack, pixels);
}
-void Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
+Error Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth,
+ GLsizei imageSize, const PixelUnpackState &unpack, const void *pixels)
{
- mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, pixels);
+ return mTexture->setCompressedImage(GL_TEXTURE_2D_ARRAY, level, format, width, height, depth, imageSize, unpack, pixels);
}
-void 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)
+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)
{
- mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
+ return mTexture->subImage(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels);
}
-void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *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)
{
- mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels);
+ return mTexture->subImageCompressed(GL_TEXTURE_2D_ARRAY, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, unpack, pixels);
}
-void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+Error Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
- mImmutable = true;
+ Error error = mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
+ if (error.isError())
+ {
+ return error;
+ }
+
+ mImmutableLevelCount = levels;
- mTexture->storage(GL_TEXTURE_2D_ARRAY, levels, internalformat, width, height, depth);
+ return Error(GL_NO_ERROR);
}
bool Texture2DArray::isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const
diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.h b/src/3rdparty/angle/src/libGLESv2/Texture.h
index ca5686fde3..66d4df8015 100644
--- a/src/3rdparty/angle/src/libGLESv2/Texture.h
+++ b/src/3rdparty/angle/src/libGLESv2/Texture.h
@@ -14,7 +14,7 @@
#include "common/debug.h"
#include "common/RefCountObject.h"
#include "libGLESv2/angletypes.h"
-#include "libGLESv2/constants.h"
+#include "libGLESv2/Constants.h"
#include "libGLESv2/renderer/TextureImpl.h"
#include "libGLESv2/Caps.h"
@@ -52,7 +52,6 @@ class Texture : public RefCountObject
const SamplerState &getSamplerState() const { return mSamplerState; }
SamplerState &getSamplerState() { return mSamplerState; }
- void getSamplerStateWithNativeOffset(SamplerState *sampler);
void setUsage(GLenum usage);
GLenum getUsage() const;
@@ -69,15 +68,16 @@ class Texture : public RefCountObject
virtual bool isSamplerComplete(const SamplerState &samplerState, const TextureCapsMap &textureCaps, const Extensions &extensions, int clientVersion) const = 0;
- rx::TextureStorage *getNativeTexture();
+ virtual Error generateMipmaps();
- virtual void generateMipmaps();
- virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
+ virtual Error copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
- unsigned int getTextureSerial();
+ // 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;
- int immutableLevelCount();
+ GLsizei immutableLevelCount();
rx::TextureImpl *getImplementation() { return mTexture; }
const rx::TextureImpl *getImplementation() const { return mTexture; }
@@ -86,17 +86,20 @@ class Texture : public RefCountObject
protected:
int mipLevels() const;
+ const rx::Image *getBaseLevelImage() const;
+ static unsigned int issueTextureSerial();
rx::TextureImpl *mTexture;
SamplerState mSamplerState;
GLenum mUsage;
- bool mImmutable;
+ GLsizei mImmutableLevelCount;
GLenum mTarget;
- const rx::Image *getBaseLevelImage() const;
+ const unsigned int mTextureSerial;
+ static unsigned int mCurrentTextureSerial;
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
@@ -116,18 +119,18 @@ class Texture2D : public Texture
bool isCompressed(GLint level) const;
bool isDepth(GLint level) const;
- void setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
- void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
- void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
- void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+ 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 void generateMipmaps();
+ virtual Error generateMipmaps();
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
@@ -152,19 +155,12 @@ class TextureCubeMap : public Texture
bool isCompressed(GLenum target, GLint level) const;
bool isDepth(GLenum target, GLint level) const;
- void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
-
- void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
-
- void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
- void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
- void storage(GLsizei levels, GLenum internalformat, GLsizei size);
+ 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;
@@ -195,11 +191,11 @@ class Texture3D : public Texture
bool isCompressed(GLint level) const;
bool isDepth(GLint level) const;
- void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- void 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);
- void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ 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;
@@ -225,11 +221,11 @@ class Texture2DArray : public Texture
bool isCompressed(GLint level) const;
bool isDepth(GLint level) const;
- void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
- void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
- void 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);
- void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
- void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+ 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;
diff --git a/src/3rdparty/angle/src/libGLESv2/VertexArray.h b/src/3rdparty/angle/src/libGLESv2/VertexArray.h
index 993ba042cf..a724c0be1c 100644
--- a/src/3rdparty/angle/src/libGLESv2/VertexArray.h
+++ b/src/3rdparty/angle/src/libGLESv2/VertexArray.h
@@ -14,14 +14,13 @@
#define LIBGLESV2_VERTEXARRAY_H_
#include "common/RefCountObject.h"
-#include "libGLESv2/constants.h"
+#include "libGLESv2/Constants.h"
#include "libGLESv2/VertexAttribute.h"
#include <vector>
namespace rx
{
-class Renderer;
class VertexArrayImpl;
}
@@ -44,7 +43,7 @@ class VertexArray
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.data(); }
+ const VertexAttribute* getVertexAttributes() const { return &mVertexAttributes[0]; }
Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); }
void setElementArrayBuffer(Buffer *buffer);
GLuint getElementArrayBufferId() const { return mElementArrayBuffer.id(); }
diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
index bb6425df64..5a0cfc5ad9 100644
--- a/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/angletypes.cpp
@@ -9,6 +9,10 @@
#include "libGLESv2/angletypes.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/VertexAttribute.h"
+#include "libGLESv2/State.h"
+#include "libGLESv2/VertexArray.h"
+
+#include <float.h>
namespace gl
{
@@ -148,16 +152,16 @@ VertexFormat::VertexFormat(const VertexAttribute &attrib, GLenum currentValueTyp
void VertexFormat::GetInputLayout(VertexFormat *inputLayout,
ProgramBinary *programBinary,
- const VertexAttribute *attributes,
- const gl::VertexAttribCurrentValueData *currentValues)
+ const State &state)
{
+ const VertexAttribute *vertexAttributes = state.getVertexArray()->getVertexAttributes();
for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
{
int semanticIndex = programBinary->getSemanticIndex(attributeIndex);
if (semanticIndex != -1)
{
- inputLayout[semanticIndex] = VertexFormat(attributes[attributeIndex], currentValues[attributeIndex].Type);
+ inputLayout[semanticIndex] = VertexFormat(vertexAttributes[attributeIndex], state.getVertexAttribCurrentValue(attributeIndex).Type);
}
}
}
@@ -192,4 +196,15 @@ bool VertexFormat::operator<(const VertexFormat& other) const
return mPureInteger < other.mPureInteger;
}
+bool Box::operator==(const Box &other) const
+{
+ return (x == other.x && y == other.y && z == other.z &&
+ width == other.width && height == other.height && depth == other.depth);
+}
+
+bool Box::operator!=(const Box &other) const
+{
+ return !(*this == other);
+}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.h b/src/3rdparty/angle/src/libGLESv2/angletypes.h
index 642a6ec266..78fe6b0e26 100644
--- a/src/3rdparty/angle/src/libGLESv2/angletypes.h
+++ b/src/3rdparty/angle/src/libGLESv2/angletypes.h
@@ -9,13 +9,13 @@
#ifndef LIBGLESV2_ANGLETYPES_H_
#define LIBGLESV2_ANGLETYPES_H_
-#include "libGLESv2/constants.h"
+#include "libGLESv2/Constants.h"
#include "common/RefCountObject.h"
-#include <float.h>
namespace gl
{
class Buffer;
+class State;
class ProgramBinary;
struct VertexAttribute;
struct VertexAttribCurrentValueData;
@@ -66,6 +66,8 @@ struct Box
Box() : x(0), y(0), z(0), width(0), height(0), depth(0) { }
Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in) : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in) { }
+ bool operator==(const Box &other) const;
+ bool operator!=(const Box &other) const;
};
struct Extents
@@ -230,8 +232,7 @@ struct VertexFormat
static void GetInputLayout(VertexFormat *inputLayout,
ProgramBinary *programBinary,
- const VertexAttribute *attributes,
- const gl::VertexAttribCurrentValueData *currentValues);
+ const State& currentValues);
bool operator==(const VertexFormat &other) const;
bool operator!=(const VertexFormat &other) const;
@@ -251,13 +252,6 @@ enum VertexConversionType
VERTEX_CONVERT_BOTH = 3
};
-enum D3DWorkaroundType
-{
- ANGLE_D3D_WORKAROUND_NONE,
- ANGLE_D3D_WORKAROUND_SKIP_OPTIMIZATION,
- ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION
-};
-
}
#endif // LIBGLESV2_ANGLETYPES_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
index 07f5d47473..587950a139 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
@@ -34,13 +34,12 @@
#include "libGLESv2/validationES3.h"
#include "libGLESv2/queryconversions.h"
-
extern "C"
{
// OpenGL ES 2.0 functions
-void __stdcall glActiveTexture(GLenum texture)
+void GL_APIENTRY glActiveTexture(GLenum texture)
{
EVENT("(GLenum texture = 0x%X)", texture);
@@ -57,7 +56,7 @@ void __stdcall glActiveTexture(GLenum texture)
}
}
-void __stdcall glAttachShader(GLuint program, GLuint shader)
+void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
{
EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
@@ -103,7 +102,7 @@ void __stdcall glAttachShader(GLuint program, GLuint shader)
}
}
-void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
+void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint id)
{
EVENT("(GLenum target = 0x%X, GLuint %d)", target, id);
@@ -124,7 +123,7 @@ void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
}
}
-void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+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);
@@ -163,7 +162,7 @@ void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar*
}
}
-void __stdcall glBindBuffer(GLenum target, GLuint buffer)
+void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
{
EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
@@ -210,7 +209,7 @@ void __stdcall glBindBuffer(GLenum target, GLuint buffer)
}
}
-void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
+void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
{
EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
@@ -235,7 +234,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
}
}
-void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
{
EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
@@ -252,7 +251,7 @@ void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
}
}
-void __stdcall glBindTexture(GLenum target, GLuint texture)
+void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
{
EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
@@ -291,7 +290,7 @@ void __stdcall glBindTexture(GLenum target, GLuint texture)
}
}
-void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+void GL_APIENTRY glBlendColor(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);
@@ -304,12 +303,12 @@ void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp
}
}
-void __stdcall glBlendEquation(GLenum mode)
+void GL_APIENTRY glBlendEquation(GLenum mode)
{
glBlendEquationSeparate(mode, mode);
}
-void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
{
EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
@@ -348,12 +347,12 @@ void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
}
}
-void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
+void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
{
glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
}
-void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+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);
@@ -488,7 +487,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha
}
}
-void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+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);
@@ -550,7 +549,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
}
}
-void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+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);
@@ -611,7 +610,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
}
}
-GLenum __stdcall glCheckFramebufferStatus(GLenum target)
+GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
{
EVENT("(GLenum target = 0x%X)", target);
@@ -626,13 +625,14 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target)
gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
ASSERT(framebuffer);
- return framebuffer->completeness();
+
+ return framebuffer->completeness(context->getData());
}
return 0;
}
-void __stdcall glClear(GLbitfield mask)
+void GL_APIENTRY glClear(GLbitfield mask)
{
EVENT("(GLbitfield mask = 0x%X)", mask);
@@ -640,8 +640,9 @@ void __stdcall glClear(GLbitfield mask)
if (context)
{
gl::Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
+ ASSERT(framebufferObject);
- if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ if (framebufferObject->completeness(context->getData()) != GL_FRAMEBUFFER_COMPLETE)
{
context->recordError(gl::Error(GL_INVALID_FRAMEBUFFER_OPERATION));
return;
@@ -662,7 +663,7 @@ void __stdcall glClear(GLbitfield mask)
}
}
-void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+void GL_APIENTRY glClearColor(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);
@@ -674,7 +675,7 @@ void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp
}
}
-void __stdcall glClearDepthf(GLclampf depth)
+void GL_APIENTRY glClearDepthf(GLclampf depth)
{
EVENT("(GLclampf depth = %f)", depth);
@@ -685,7 +686,7 @@ void __stdcall glClearDepthf(GLclampf depth)
}
}
-void __stdcall glClearStencil(GLint s)
+void GL_APIENTRY glClearStencil(GLint s)
{
EVENT("(GLint s = %d)", s);
@@ -696,7 +697,7 @@ void __stdcall glClearStencil(GLint s)
}
}
-void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+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);
@@ -708,7 +709,7 @@ void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboo
}
}
-void __stdcall glCompileShader(GLuint shader)
+void GL_APIENTRY glCompileShader(GLuint shader)
{
EVENT("(GLuint shader = %d)", shader);
@@ -731,11 +732,11 @@ void __stdcall glCompileShader(GLuint shader)
}
}
- shaderObject->compile();
+ shaderObject->compile(context->getData());
}
}
-void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
+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, "
@@ -771,7 +772,12 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
case GL_TEXTURE_2D:
{
gl::Texture2D *texture = context->getTexture2D();
- texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
+ gl::Error error = texture->setCompressedImage(level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -783,7 +789,12 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{
gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
+ gl::Error error = texture->setCompressedImage(target, level, internalformat, width, height, imageSize, context->getState().getUnpackState(), data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -794,7 +805,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
}
}
-void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+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, "
@@ -831,7 +842,12 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
case GL_TEXTURE_2D:
{
gl::Texture2D *texture = context->getTexture2D();
- texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
+ gl::Error error = texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, context->getState().getUnpackState(), data);
+ if (error.isError())
+ {
+ context->recordError(error);
+ return;
+ }
}
break;
@@ -843,7 +859,12 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{
gl::TextureCubeMap *texture = context->getTextureCubeMap();
- texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+ 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;
@@ -854,7 +875,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
}
}
-void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+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)",
@@ -884,7 +905,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
case GL_TEXTURE_2D:
{
gl::Texture2D *texture = context->getTexture2D();
- texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
+ gl::Error error = texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
+ if (error.isError())
+ {
+